From 0b4767e771f89e323cf0d7fdbb539ab02bdf7593 Mon Sep 17 00:00:00 2001
From: Razvan Stoenescu <razvan.stoenescu@gmail.com>
Date: Sat, 30 Nov 2024 15:49:54 +0200
Subject: [PATCH] feat(create-quasar): update all new q/app templates to use
 ESLint v9; convert webpack to type=module & all related files

---
 .../app/quasar-v2/js-vite-2/BASE/README.md    |   7 +-
 .../quasar-v2/js-vite-2/BASE/_.editorconfig   |   6 +-
 .../js-vite-2/BASE/_.vscode/extensions.json   |   4 +-
 .../js-vite-2/BASE/_.vscode/settings.json     |   4 +-
 .../quasar-v2/js-vite-2/BASE/_package.json    |  31 ++--
 .../js-vite-2/BASE/postcss.config.js          |   1 -
 .../quasar-v2/js-vite-2/BASE/quasar.config.js |  11 +-
 .../js-vite-2/eslint/_eslint.config.js        |  64 ++++++++
 .../app/quasar-v2/js-vite-2/index.js          |  17 +--
 .../js-vite-2/lint/_eslint.config.js          |  76 ----------
 .../js-vite-2/prettier/_.prettierrc.json      |   6 +
 .../app/quasar-v2/js-webpack-4/BASE/README.md |   7 +-
 .../js-webpack-4/BASE/_.editorconfig          |   6 +-
 .../BASE/_.vscode/extensions.json             |   4 +-
 .../js-webpack-4/BASE/_.vscode/settings.json  |   4 +-
 .../quasar-v2/js-webpack-4/BASE/_package.json |  29 ++--
 .../js-webpack-4/BASE/quasar.config.js        |   4 +-
 .../js-webpack-4/eslint/_eslint.config.js     |  64 ++++++++
 .../app/quasar-v2/js-webpack-4/index.js       |  16 +-
 .../js-webpack-4/lint/_eslint.config.js       |  76 ----------
 .../js-webpack-4/prettier/_.prettierrc.json   |   6 +
 .../app/quasar-v2/ts-vite-2/BASE/README.md    |   7 +-
 .../quasar-v2/ts-vite-2/BASE/_.editorconfig   |   6 +-
 .../ts-vite-2/BASE/_.vscode/extensions.json   |   4 +-
 .../ts-vite-2/BASE/_.vscode/settings.json     |   4 +-
 .../quasar-v2/ts-vite-2/BASE/_package.json    |  37 ++---
 .../quasar-v2/ts-vite-2/BASE/quasar.config.ts |  12 +-
 .../ts-vite-2/eslint/_eslint.config.js        |  66 +++++++++
 .../app/quasar-v2/ts-vite-2/index.js          |  23 +--
 .../quasar-v2/ts-vite-2/lint/_.eslintignore   |   7 -
 .../quasar-v2/ts-vite-2/lint/_.eslintrc.cjs   | 135 -----------------
 .../quasar-v2/ts-vite-2/prettier/_.prettierrc |   4 -
 .../ts-vite-2/prettier/_.prettierrc.json      |   6 +
 .../app/quasar-v2/ts-webpack-4/BASE/README.md |   7 +-
 .../ts-webpack-4/BASE/_.editorconfig          |   6 +-
 .../BASE/_.vscode/extensions.json             |   4 +-
 .../ts-webpack-4/BASE/_.vscode/settings.json  |   4 +-
 .../quasar-v2/ts-webpack-4/BASE/_package.json |  38 ++---
 .../ts-webpack-4/BASE/quasar.config.ts        |  10 +-
 .../ts-webpack-4/eslint/_eslint.config.js     |  66 +++++++++
 .../app/quasar-v2/ts-webpack-4/index.js       |  23 +--
 .../ts-webpack-4/lint/_.eslintignore          |   8 -
 .../ts-webpack-4/lint/_.eslintrc.cjs          | 139 ------------------
 .../ts-webpack-4/prettier/_.prettierrc        |   4 -
 .../ts-webpack-4/prettier/_.prettierrc.json   |   6 +
 45 files changed, 419 insertions(+), 650 deletions(-)
 create mode 100644 create-quasar/templates/app/quasar-v2/js-vite-2/eslint/_eslint.config.js
 delete mode 100644 create-quasar/templates/app/quasar-v2/js-vite-2/lint/_eslint.config.js
 create mode 100644 create-quasar/templates/app/quasar-v2/js-vite-2/prettier/_.prettierrc.json
 create mode 100644 create-quasar/templates/app/quasar-v2/js-webpack-4/eslint/_eslint.config.js
 delete mode 100644 create-quasar/templates/app/quasar-v2/js-webpack-4/lint/_eslint.config.js
 create mode 100644 create-quasar/templates/app/quasar-v2/js-webpack-4/prettier/_.prettierrc.json
 create mode 100644 create-quasar/templates/app/quasar-v2/ts-vite-2/eslint/_eslint.config.js
 delete mode 100644 create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintignore
 delete mode 100644 create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintrc.cjs
 delete mode 100644 create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc
 create mode 100644 create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc.json
 create mode 100644 create-quasar/templates/app/quasar-v2/ts-webpack-4/eslint/_eslint.config.js
 delete mode 100644 create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintignore
 delete mode 100644 create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintrc.cjs
 delete mode 100644 create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc
 create mode 100644 create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc.json

diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/README.md b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/README.md
index b35e2860814..151e7357dcd 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/README.md
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/README.md
@@ -13,7 +13,7 @@ npm install
 ```bash
 quasar dev
 ```
-<% if (preset.lint) { %>
+<% if (preset.eslint) { %>
 
 ### Lint the files
 ```bash
@@ -21,7 +21,7 @@ yarn lint
 # or
 npm run lint
 ```
-<% if (lintConfig === 'prettier') { %>
+<% if (prettier) { %>
 
 ### Format the files
 ```bash
@@ -29,8 +29,7 @@ yarn format
 # or
 npm run format
 ```
-<% } %>
-<% } %>
+<% } } %>
 
 ### Build the app for production
 ```bash
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.editorconfig b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.editorconfig
index 9d08a1a828a..f654551630b 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.editorconfig
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.editorconfig
@@ -1,9 +1,7 @@
-root = true
-
-[*]
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
 charset = utf-8
-indent_style = space
 indent_size = 2
+indent_style = space
 end_of_line = lf
 insert_final_newline = true
 trim_trailing_whitespace = true
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/extensions.json b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/extensions.json
index 5d59d46ce93..2e1143730ab 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/extensions.json
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/extensions.json
@@ -1,7 +1,7 @@
 {
   "recommendations": [
-    <% if (preset.lint) { %>"dbaeumer.vscode-eslint",
-    <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode",<% } } %>
+    <% if (preset.eslint) { %>"dbaeumer.vscode-eslint",<% } %>
+    <% if (prettier) { %>"esbenp.prettier-vscode",<% } %>
     "editorconfig.editorconfig",
     "vue.volar",
     "wayou.vscode-todo-highlight"
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/settings.json b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/settings.json
index ec6e1641537..aa599144929 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/settings.json
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_.vscode/settings.json
@@ -1,8 +1,8 @@
 {
   "editor.bracketPairColorization.enabled": true,
-  "editor.guides.bracketPairs": true<% if (preset.lint) { %>,
+  "editor.guides.bracketPairs": true<% if (preset.eslint) { %>,
   "editor.formatOnSave": true,
-  "editor.defaultFormatter": <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
+  "editor.defaultFormatter": <% if (prettier) { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
   "editor.codeActionsOnSave": [
     "source.fixAll.eslint"
   ],
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_package.json b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_package.json
index de943a3447f..7b0e7dc4973 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_package.json
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/_package.json
@@ -7,9 +7,8 @@
   "type": "module",
   "private": true,
   "scripts": {
-    <% if (preset.lint) { %>"lint": "eslint -c ./eslint.config.js",
-    <% if (lintConfig === 'prettier') { %>"format": "prettier --write \"**/*.{js,vue<% if (css !== 'sass') { %>,<%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
-    <% } %>
+    <% if (preset.eslint) { %>"lint": "eslint",<% } %>
+    <% if (prettier) { %>"format": "prettier --write \"**/*.{js,vue<% if (css !== 'sass') { %>,<%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
     "test": "echo \"No test specified\" && exit 0",
     "dev": "quasar dev",
     "build": "quasar build",
@@ -25,24 +24,24 @@
     "vue-router": "^4.0.0"
   },
   "devDependencies": {
-    <% if (preset.lint) { %>
-    "eslint": "^9.15.0",
-    "eslint-plugin-vue": "^9.0.0",
-    "eslint-webpack-plugin": "^4.2.0",
-    "globals": "^15.12.0",<% if (lintConfig === 'standard') { %>
-    "eslint-config-standard": "^17.0.0",
-    "eslint-plugin-import": "^2.31.0",
-    "eslint-plugin-n": "^17.14.0",
-    "eslint-plugin-promise": "^7.2.1",<% } else if (lintConfig === 'prettier') { %>
-    "eslint-config-prettier": "^9.0.0",
-    "prettier": "^3.0.3",
-    <% } } %><% if (preset.i18n) { %>"@intlify/unplugin-vue-i18n": "^2.0.0",<% } %>
+    <% if (preset.i18n) { %>"@intlify/unplugin-vue-i18n": "^2.0.0",<% } %>
+    <% if (preset.eslint) { %>
+    "@eslint/js": "^9.14.0",
+    "eslint": "^9.14.0",
+    "eslint-plugin-vue": "^9.30.0",
+    "globals": "^15.12.0",
+    "vite-plugin-checker": "^0.8.0",
+    <% } %>
+    <% if (prettier) { %>
+    "@vue/eslint-config-prettier": "^10.1.0",
+    "prettier": "^3.3.3",
+    <% } %>
     "@quasar/app-vite": "^2.0.0",
     "autoprefixer": "^10.4.2",
     "postcss": "^8.4.14"
   },
   "engines": {
-    "node": "^24 || ^22 || ^20 || ^18",
+    "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18",
     "npm": ">= 6.13.4",
     "yarn": ">= 1.21.1"
   }
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/postcss.config.js b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/postcss.config.js
index 29a4bf0544b..25db2f4c878 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/postcss.config.js
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/postcss.config.js
@@ -1,4 +1,3 @@
-/* eslint-disable */
 // https://github.com/michael-ciniawsky/postcss-load-config
 
 import autoprefixer from 'autoprefixer'
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/quasar.config.js b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/quasar.config.js
index 93e40fa3ad7..30189bae886 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/quasar.config.js
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/BASE/quasar.config.js
@@ -1,10 +1,6 @@
-/* eslint-env node */
-
 // Configuration for your app
 // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
 
-<% if (preset.lint && lintConfig === 'airbnb') { %>/* eslint func-names: 0 */
-/* eslint global-require: 0 */<% } %>
 import { defineConfig } from '#q-app/wrappers'
 <% if (preset.i18n) { %>import { fileURLToPath } from 'node:url';<% } %>
 
@@ -66,7 +62,7 @@ export default defineConfig((<% if (preset.i18n) { %>ctx<% } else { %>/* ctx */<
       // extendViteConf (viteConf) {},
       // viteVuePluginOptions: {},
 
-      <% if (preset.i18n || preset.lint) { %>vitePlugins: [<% if (preset.i18n) { %>
+      <% if (preset.i18n || preset.eslint) { %>vitePlugins: [<% if (preset.i18n) { %>
         ['@intlify/unplugin-vue-i18n/vite', {
           // if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
           // compositionOnly: false,
@@ -79,10 +75,11 @@ export default defineConfig((<% if (preset.i18n) { %>ctx<% } else { %>/* ctx */<
 
           // you need to set i18n resource including paths !
           include: [ fileURLToPath(new URL('./src/i18n', import.meta.url)) ],
-        }]<% } %><% if (preset.lint) { %><% if (preset.i18n) { %>,<% } %>
+        }]<% } %><% if (preset.eslint) { %><% if (preset.i18n) { %>,<% } %>
         ['vite-plugin-checker', {
           eslint: {
-            lintCommand: 'eslint "./**/*.{js,mjs,cjs,vue}"'
+            lintCommand: 'eslint',
+            useFlatConfig: true
           }
         }, { server: false }]<% } %>
       ]<% } else { %>
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/eslint/_eslint.config.js b/create-quasar/templates/app/quasar-v2/js-vite-2/eslint/_eslint.config.js
new file mode 100644
index 00000000000..b87b972bf79
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/eslint/_eslint.config.js
@@ -0,0 +1,64 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import pluginVue from 'eslint-plugin-vue'
+import pluginQuasar from '@quasar/app-vite/eslint'<% if (prettier) { %>
+import prettierSkipFormatting from '@vue/eslint-config-prettier/skip-formatting'<% } %>
+
+export default [
+  {
+    /**
+     * Ignore the following files.
+     * Please note that pluginQuasar.configs.recommended already ignores
+     * the "node_modules" folder for you (and all other Quasar project
+     * relevant folders and files).
+     *
+     * ESLint requires "ignores" key to be the only one in this object
+     */
+    // ignores: []
+  },
+
+  pluginQuasar.configs.recommended,
+  js.configs.recommended,
+  ...pluginVue.configs[ 'flat/essential' ],
+
+  {
+    languageOptions: {
+      ecmaVersion: 'latest',
+      sourceType: 'module',
+
+      globals: {
+        ...globals.browser,
+        ...globals.node, // SSR, Electron, config files
+        process: 'readonly', // process.env.*
+        ga: 'readonly', // Google Analytics
+        cordova: 'readonly',
+        Capacitor: 'readonly',
+        chrome: 'readonly', // BEX related
+        browser: 'readonly' // BEX related
+      }
+    },
+
+    linterOptions: {
+      reportUnusedDisableDirectives: 'warn'
+    },
+
+    // add your custom rules here
+    rules: {
+      'prefer-promise-reject-errors': 'off',
+
+      // allow debugger during development only
+      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
+    }
+  },
+
+  {
+    files: [ 'src-pwa/custom-service-worker.{js,ts}' ],
+    languageOptions: {
+      globals: {
+        ...globals.serviceworker
+      }
+    }
+  }<% if (prettier) { %>,
+
+  prettierSkipFormatting<% } %>
+]
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/index.js b/create-quasar/templates/app/quasar-v2/js-vite-2/index.js
index 15360884800..d58d3cfa716 100644
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/index.js
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/index.js
@@ -5,7 +5,7 @@ export async function script ({ scope, utils }) {
       name: 'preset',
       message: 'Check the features needed for your project:',
       choices: [
-        { title: 'Linting (vite-plugin-checker + ESLint)', value: 'lint', description: 'recommended', selected: true },
+        { title: 'Linting (vite-plugin-checker + ESLint)', value: 'eslint', description: 'recommended', selected: true },
         { title: 'State Management (Pinia)', value: 'pinia', description: 'https://pinia.vuejs.org' },
         { title: 'axios', value: 'axios' },
         { title: 'vue-i18n', value: 'i18n' }
@@ -13,14 +13,10 @@ export async function script ({ scope, utils }) {
       format: utils.convertArrayToObject
     },
     {
-      type: (_, { preset }) => (preset.lint ? 'select' : null),
-      name: 'lintConfig',
-      message: 'Pick an ESLint preset:',
-      choices: [
-        { title: 'Prettier', value: 'prettier', description: 'https://github.com/prettier/prettier' },
-        { title: 'Standard', value: 'standard', description: 'https://github.com/standard/standard' },
-        { title: 'Airbnb', value: 'airbnb', description: 'https://github.com/airbnb/javascript' }
-      ]
+      type: (_, { preset }) => (preset.eslint ? 'confirm' : null),
+      name: 'prettier',
+      initial: false,
+      message: 'Add Prettier for code formatting?'
     }
   ])
 
@@ -30,6 +26,7 @@ export async function script ({ scope, utils }) {
 
   if (scope.preset.axios) utils.renderTemplate('axios', scope)
   if (scope.preset.i18n) utils.renderTemplate('i18n', scope)
-  if (scope.preset.lint) utils.renderTemplate('lint', scope)
+  if (scope.preset.eslint) utils.renderTemplate('eslint', scope)
+  if (scope.prettier) utils.renderTemplate('prettier', scope)
   if (scope.preset.pinia) utils.renderTemplate('pinia', scope)
 }
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/lint/_eslint.config.js b/create-quasar/templates/app/quasar-v2/js-vite-2/lint/_eslint.config.js
deleted file mode 100644
index ffb9460a2ad..00000000000
--- a/create-quasar/templates/app/quasar-v2/js-vite-2/lint/_eslint.config.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import js from '@eslint/js'
-import globals from 'globals'
-import pluginVue from 'eslint-plugin-vue'
-<% if (lintConfig === 'standard') { %>
-import standard from 'eslint-config-standard'
-import importPlugin from 'eslint-plugin-import'
-import nodePlugin from 'eslint-plugin-n'
-import pluginPromise from 'eslint-plugin-promise'
-<% } else if (lintConfig === 'prettier') { %>
-import eslintConfigPrettier from 'eslint-config-prettier'<% } %>
-
-export default [
-  {
-    ignores: [
-      'node_modules/*',
-      'dist/*',
-      'src-capacitor/*',
-      'src-cordova/*',
-      '.quasar/*',
-      'eslint.config.js',
-      'quasar.config.*.temporary.compiled*'
-    ]
-  },
-
-  js.configs.recommended,
-  ...pluginVue.configs[ 'flat/essential' ],
-  <% if (lintConfig === 'standard') { %>
-  standard,
-  importPlugin.flatConfigs.recommended,
-  nodePlugin.configs["flat/recommended-script"],
-  pluginPromise.configs['flat/recommended'],
-  <% } else if (lintConfig === 'prettier') { %>
-  eslintConfigPrettier,
-  <% } %>
-
-  {
-    languageOptions: {
-      sourceType: 'module',
-
-      globals: {
-        ...globals.browser,
-        ga: 'readonly', // Google Analytics
-        process: 'readonly',
-        cordova: 'readonly',
-        Capacitor: 'readonly',
-        chrome: 'readonly', // BEX related
-        browser: 'readonly' // BEX related
-      }
-    },
-
-    // add your custom rules here
-    rules: {
-      <% if (lintConfig === 'standard') { %>
-      // allow async-await
-      'generator-star-spacing': 'off',
-      // allow paren-less arrow functions
-      'arrow-parens': 'off',
-      'one-var': 'off',
-      'no-void': 'off',
-      'multiline-ternary': 'off',
-
-      'import/first': 'off',
-      'import/named': 'error',
-      'import/namespace': 'error',
-      'import/default': 'error',
-      'import/export': 'error',
-      'import/extensions': 'off',
-      'import/no-unresolved': 'off',
-      'import/no-extraneous-dependencies': 'off',
-      <% } %>'prefer-promise-reject-errors': 'off',
-
-      // allow debugger during development only
-      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
-    }
-  }
-]
diff --git a/create-quasar/templates/app/quasar-v2/js-vite-2/prettier/_.prettierrc.json b/create-quasar/templates/app/quasar-v2/js-vite-2/prettier/_.prettierrc.json
new file mode 100644
index 00000000000..29a2402ef05
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/js-vite-2/prettier/_.prettierrc.json
@@ -0,0 +1,6 @@
+{
+  "$schema": "https://json.schemastore.org/prettierrc",
+  "semi": false,
+  "singleQuote": true,
+  "printWidth": 100
+}
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/README.md b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/README.md
index 9e7f870e5ee..702bea50ee3 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/README.md
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/README.md
@@ -13,7 +13,7 @@ npm install
 ```bash
 quasar dev
 ```
-<% if (preset.lint) { %>
+<% if (preset.eslint) { %>
 
 ### Lint the files
 ```bash
@@ -21,7 +21,7 @@ yarn lint
 # or
 npm run lint
 ```
-<% if (lintConfig === 'prettier') { %>
+<% if (prettier) { %>
 
 ### Format the files
 ```bash
@@ -29,8 +29,7 @@ yarn format
 # or
 npm run format
 ```
-<% } %>
-<% } %>
+<% } } %>
 
 ### Build the app for production
 ```bash
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.editorconfig b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.editorconfig
index 9d08a1a828a..f654551630b 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.editorconfig
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.editorconfig
@@ -1,9 +1,7 @@
-root = true
-
-[*]
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
 charset = utf-8
-indent_style = space
 indent_size = 2
+indent_style = space
 end_of_line = lf
 insert_final_newline = true
 trim_trailing_whitespace = true
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/extensions.json b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/extensions.json
index 5d59d46ce93..2e1143730ab 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/extensions.json
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/extensions.json
@@ -1,7 +1,7 @@
 {
   "recommendations": [
-    <% if (preset.lint) { %>"dbaeumer.vscode-eslint",
-    <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode",<% } } %>
+    <% if (preset.eslint) { %>"dbaeumer.vscode-eslint",<% } %>
+    <% if (prettier) { %>"esbenp.prettier-vscode",<% } %>
     "editorconfig.editorconfig",
     "vue.volar",
     "wayou.vscode-todo-highlight"
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/settings.json b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/settings.json
index ec6e1641537..aa599144929 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/settings.json
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_.vscode/settings.json
@@ -1,8 +1,8 @@
 {
   "editor.bracketPairColorization.enabled": true,
-  "editor.guides.bracketPairs": true<% if (preset.lint) { %>,
+  "editor.guides.bracketPairs": true<% if (preset.eslint) { %>,
   "editor.formatOnSave": true,
-  "editor.defaultFormatter": <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
+  "editor.defaultFormatter": <% if (prettier) { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
   "editor.codeActionsOnSave": [
     "source.fixAll.eslint"
   ],
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_package.json b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_package.json
index 16bd7972edb..2ae6e3b0097 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_package.json
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/_package.json
@@ -7,9 +7,8 @@
   "private": true,
   "type": "module",
   "scripts": {
-    <% if (preset.lint) { %>"lint": "eslint -c ./eslint.config.js",
-    <% if (lintConfig === 'prettier') { %>"format": "prettier --write \"**/*.{js,vue<% if (css !== 'sass') { %>,<%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
-    <% } %>
+    <% if (preset.eslint) { %>"lint": "eslint",<% } %>
+    <% if (prettier) { %>"format": "prettier --write \"**/*.{js,vue<% if (css !== 'sass') { %>,<%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
     "test": "echo \"No test specified\" && exit 0",
     "dev": "quasar dev",
     "build": "quasar build",
@@ -26,18 +25,18 @@
     "vue-router": "^4.0.12"
   },
   "devDependencies": {
-    <% if (preset.lint) { %>
-    "eslint": "^9.15.0",
-    "eslint-plugin-vue": "^9.0.0",
+    <% if (preset.eslint) { %>
+    "@eslint/js": "^9.14.0",
+    "eslint": "^9.14.0",
+    "eslint-plugin-vue": "^9.30.0",
     "eslint-webpack-plugin": "^4.2.0",
-    "globals": "^15.12.0",<% if (lintConfig === 'standard') { %>
-    "eslint-config-standard": "^17.0.0",
-    "eslint-plugin-import": "^2.31.0",
-    "eslint-plugin-n": "^17.14.0",
-    "eslint-plugin-promise": "^7.2.1",<% } else if (lintConfig === 'prettier') { %>
-    "eslint-config-prettier": "^9.0.0",
-    "prettier": "^3.0.3",
-    <% } } %>"@quasar/app-webpack": "^4.0.0"
+    "globals": "^15.12.0",
+    <% } %>
+    <% if (prettier) { %>
+    "@vue/eslint-config-prettier": "^10.1.0",
+    "prettier": "^3.3.3",
+    <% } %>
+    "@quasar/app-webpack": "^4.0.0"
   },
   "browserslist": [
     "last 10 Chrome versions",
@@ -51,7 +50,7 @@
     "last 5 Opera versions"
   ],
   "engines": {
-    "node": "^24 || ^22 || ^20 || ^18",
+    "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18",
     "npm": ">= 6.13.4",
     "yarn": ">= 1.21.1"
   }
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/quasar.config.js b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/quasar.config.js
index 38719d34f9a..f37414e171c 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/quasar.config.js
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/BASE/quasar.config.js
@@ -1,5 +1,3 @@
-/* eslint-env node */
-
 // Configuration for your app
 // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js
 
@@ -7,7 +5,7 @@ import { defineConfig } from '#q-app/wrappers';
 
 export default defineConfig((ctx) => {
   return {
-    <% if (preset.lint) { %>eslint: {
+    <% if (preset.eslint) { %>eslint: {
       // fix: true,
       // include: [],
       // exclude: [],
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/eslint/_eslint.config.js b/create-quasar/templates/app/quasar-v2/js-webpack-4/eslint/_eslint.config.js
new file mode 100644
index 00000000000..bd16f6a5ddb
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/eslint/_eslint.config.js
@@ -0,0 +1,64 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import pluginVue from 'eslint-plugin-vue'
+import pluginQuasar from '@quasar/app-webpack/eslint'<% if (prettier) { %>
+import prettierSkipFormatting from '@vue/eslint-config-prettier/skip-formatting'<% } %>
+
+export default [
+  {
+    /**
+     * Ignore the following files.
+     * Please note that pluginQuasar.configs.recommended already ignores
+     * the "node_modules" folder for you (and all other Quasar project
+     * relevant folders and files).
+     *
+     * ESLint requires "ignores" key to be the only one in this object
+     */
+    // ignores: []
+  },
+
+  pluginQuasar.configs.recommended,
+  js.configs.recommended,
+  ...pluginVue.configs[ 'flat/essential' ],
+
+  {
+    languageOptions: {
+      ecmaVersion: 'latest',
+      sourceType: 'module',
+
+      globals: {
+        ...globals.browser,
+        ...globals.node, // SSR, Electron, config files
+        process: 'readonly', // process.env.*
+        ga: 'readonly', // Google Analytics
+        cordova: 'readonly',
+        Capacitor: 'readonly',
+        chrome: 'readonly', // BEX related
+        browser: 'readonly' // BEX related
+      }
+    },
+
+    linterOptions: {
+      reportUnusedDisableDirectives: 'warn'
+    },
+
+    // add your custom rules here
+    rules: {
+      'prefer-promise-reject-errors': 'off',
+
+      // allow debugger during development only
+      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
+    }
+  },
+
+  {
+    files: [ 'src-pwa/custom-service-worker.{js,ts}' ],
+    languageOptions: {
+      globals: {
+        ...globals.serviceworker
+      }
+    }
+  }<% if (prettier) { %>,
+
+  prettierSkipFormatting<% } %>
+]
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/index.js b/create-quasar/templates/app/quasar-v2/js-webpack-4/index.js
index 00890562fc7..439744a07ca 100644
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/index.js
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/index.js
@@ -5,7 +5,7 @@ export async function script ({ scope, utils }) {
       name: 'preset',
       message: 'Check the features needed for your project:',
       choices: [
-        { title: 'Linting (ESLint)', value: 'lint', description: 'recommended', selected: true },
+        { title: 'Linting (ESLint)', value: 'eslint', description: 'recommended', selected: true },
         { title: 'State Management (Pinia)', value: 'pinia', description: 'https://pinia.vuejs.org' },
         { title: 'axios', value: 'axios' },
         { title: 'vue-i18n', value: 'i18n' }
@@ -13,13 +13,10 @@ export async function script ({ scope, utils }) {
       format: utils.convertArrayToObject
     },
     {
-      type: (_, { preset }) => (preset.lint ? 'select' : null),
-      name: 'lintConfig',
-      message: 'Pick an ESLint preset:',
-      choices: [
-        { title: 'Prettier', value: 'prettier', description: 'https://github.com/prettier/prettier' },
-        { title: 'Standard', value: 'standard', description: 'https://github.com/standard/standard' }
-      ]
+      type: (_, { preset }) => (preset.eslint ? 'confirm' : null),
+      name: 'prettier',
+      initial: false,
+      message: 'Add Prettier for code formatting?'
     }
   ])
 
@@ -29,6 +26,7 @@ export async function script ({ scope, utils }) {
 
   if (scope.preset.axios) utils.renderTemplate('axios', scope)
   if (scope.preset.i18n) utils.renderTemplate('i18n', scope)
-  if (scope.preset.lint) utils.renderTemplate('lint', scope)
+  if (scope.preset.eslint) utils.renderTemplate('eslint', scope)
+  if (scope.prettier) utils.renderTemplate('prettier', scope)
   if (scope.preset.pinia) utils.renderTemplate('pinia', scope)
 }
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/lint/_eslint.config.js b/create-quasar/templates/app/quasar-v2/js-webpack-4/lint/_eslint.config.js
deleted file mode 100644
index ffb9460a2ad..00000000000
--- a/create-quasar/templates/app/quasar-v2/js-webpack-4/lint/_eslint.config.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import js from '@eslint/js'
-import globals from 'globals'
-import pluginVue from 'eslint-plugin-vue'
-<% if (lintConfig === 'standard') { %>
-import standard from 'eslint-config-standard'
-import importPlugin from 'eslint-plugin-import'
-import nodePlugin from 'eslint-plugin-n'
-import pluginPromise from 'eslint-plugin-promise'
-<% } else if (lintConfig === 'prettier') { %>
-import eslintConfigPrettier from 'eslint-config-prettier'<% } %>
-
-export default [
-  {
-    ignores: [
-      'node_modules/*',
-      'dist/*',
-      'src-capacitor/*',
-      'src-cordova/*',
-      '.quasar/*',
-      'eslint.config.js',
-      'quasar.config.*.temporary.compiled*'
-    ]
-  },
-
-  js.configs.recommended,
-  ...pluginVue.configs[ 'flat/essential' ],
-  <% if (lintConfig === 'standard') { %>
-  standard,
-  importPlugin.flatConfigs.recommended,
-  nodePlugin.configs["flat/recommended-script"],
-  pluginPromise.configs['flat/recommended'],
-  <% } else if (lintConfig === 'prettier') { %>
-  eslintConfigPrettier,
-  <% } %>
-
-  {
-    languageOptions: {
-      sourceType: 'module',
-
-      globals: {
-        ...globals.browser,
-        ga: 'readonly', // Google Analytics
-        process: 'readonly',
-        cordova: 'readonly',
-        Capacitor: 'readonly',
-        chrome: 'readonly', // BEX related
-        browser: 'readonly' // BEX related
-      }
-    },
-
-    // add your custom rules here
-    rules: {
-      <% if (lintConfig === 'standard') { %>
-      // allow async-await
-      'generator-star-spacing': 'off',
-      // allow paren-less arrow functions
-      'arrow-parens': 'off',
-      'one-var': 'off',
-      'no-void': 'off',
-      'multiline-ternary': 'off',
-
-      'import/first': 'off',
-      'import/named': 'error',
-      'import/namespace': 'error',
-      'import/default': 'error',
-      'import/export': 'error',
-      'import/extensions': 'off',
-      'import/no-unresolved': 'off',
-      'import/no-extraneous-dependencies': 'off',
-      <% } %>'prefer-promise-reject-errors': 'off',
-
-      // allow debugger during development only
-      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
-    }
-  }
-]
diff --git a/create-quasar/templates/app/quasar-v2/js-webpack-4/prettier/_.prettierrc.json b/create-quasar/templates/app/quasar-v2/js-webpack-4/prettier/_.prettierrc.json
new file mode 100644
index 00000000000..29a2402ef05
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/js-webpack-4/prettier/_.prettierrc.json
@@ -0,0 +1,6 @@
+{
+  "$schema": "https://json.schemastore.org/prettierrc",
+  "semi": false,
+  "singleQuote": true,
+  "printWidth": 100
+}
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/README.md b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/README.md
index b35e2860814..151e7357dcd 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/README.md
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/README.md
@@ -13,7 +13,7 @@ npm install
 ```bash
 quasar dev
 ```
-<% if (preset.lint) { %>
+<% if (preset.eslint) { %>
 
 ### Lint the files
 ```bash
@@ -21,7 +21,7 @@ yarn lint
 # or
 npm run lint
 ```
-<% if (lintConfig === 'prettier') { %>
+<% if (prettier) { %>
 
 ### Format the files
 ```bash
@@ -29,8 +29,7 @@ yarn format
 # or
 npm run format
 ```
-<% } %>
-<% } %>
+<% } } %>
 
 ### Build the app for production
 ```bash
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.editorconfig b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.editorconfig
index 9d08a1a828a..f654551630b 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.editorconfig
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.editorconfig
@@ -1,9 +1,7 @@
-root = true
-
-[*]
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
 charset = utf-8
-indent_style = space
 indent_size = 2
+indent_style = space
 end_of_line = lf
 insert_final_newline = true
 trim_trailing_whitespace = true
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/extensions.json b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/extensions.json
index 5d59d46ce93..2e1143730ab 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/extensions.json
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/extensions.json
@@ -1,7 +1,7 @@
 {
   "recommendations": [
-    <% if (preset.lint) { %>"dbaeumer.vscode-eslint",
-    <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode",<% } } %>
+    <% if (preset.eslint) { %>"dbaeumer.vscode-eslint",<% } %>
+    <% if (prettier) { %>"esbenp.prettier-vscode",<% } %>
     "editorconfig.editorconfig",
     "vue.volar",
     "wayou.vscode-todo-highlight"
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/settings.json b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/settings.json
index 9fe8f5a6f3b..b07ec68ba65 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/settings.json
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_.vscode/settings.json
@@ -1,8 +1,8 @@
 {
   "editor.bracketPairColorization.enabled": true,
-  "editor.guides.bracketPairs": true,<% if (preset.lint) { %>
+  "editor.guides.bracketPairs": true,<% if (preset.eslint) { %>
   "editor.formatOnSave": true,
-  "editor.defaultFormatter": <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
+  "editor.defaultFormatter": <% if (prettier) { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
   "editor.codeActionsOnSave": [
     "source.fixAll.eslint"
   ],
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_package.json b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_package.json
index 70fed4cdac9..d50d20a720e 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_package.json
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/_package.json
@@ -7,9 +7,8 @@
   "type": "module",
   "private": true,
   "scripts": {
-    <% if (preset.lint) { %>"lint": "eslint --ext .js,.ts,.vue ./",
-    <% if (lintConfig === 'prettier') { %>"format": "prettier --write \"**/*.{js,ts,vue,<% if (css !== 'sass') { %><%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
-    <% } %>
+    <% if (preset.eslint) { %>"lint": "eslint",<% } %>
+    <% if (prettier) { %>"format": "prettier --write \"**/*.{js,ts,vue,<% if (css !== 'sass') { %><%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
     "test": "echo \"No test specified\" && exit 0",
     "dev": "quasar dev",
     "build": "quasar build",
@@ -25,25 +24,19 @@
     "vue-router": "^4.0.12"
   },
   "devDependencies": {
-    <% if (preset.lint) { %>
-    "@typescript-eslint/eslint-plugin": "^7.16.0",
-    "@typescript-eslint/parser": "^7.16.0",
-    "vite-plugin-checker": "^0.8.0",
+    <% if (preset.eslint) { %>
+    "@eslint/js": "^9.14.0",
+    "eslint": "^9.14.0",
+    "eslint-plugin-vue": "^9.30.0",
+    "globals": "^15.12.0",
     "vue-tsc": "^2.0.29",
-    "eslint": "^8.57.0",
-    "eslint-plugin-vue": "^9.0.0",
-    <% if (lintConfig === 'standard') { %>
-    "eslint-config-standard": "^17.0.0",
-    "eslint-plugin-import": "^2.19.1",
-    "eslint-plugin-n": "^15.0.0",
-    "eslint-plugin-promise": "^6.0.0",
-    <% } else if (lintConfig === 'airbnb') { %>
-    "eslint-config-airbnb-base": "^15.0.0",
-    "eslint-plugin-import": "^2.20.1",
-    <% } else if (lintConfig === 'prettier') { %>
-    "eslint-config-prettier": "^9.0.0",
-    "prettier": "^3.0.3",
-    <% } } %>
+    "@vue/eslint-config-typescript": "^14.1.3",
+    "vite-plugin-checker": "^0.8.0",
+    <% } %>
+    <% if (prettier) { %>
+    "@vue/eslint-config-prettier": "^10.1.0",
+    "prettier": "^3.3.3",
+    <% } %>
     "@types/node": "^20.5.9",
     <% if (preset.i18n) { %>"@intlify/unplugin-vue-i18n": "^2.0.0",<% } %>
     "@quasar/app-vite": "^2.0.0",
@@ -51,7 +44,7 @@
     "typescript": "~5.5.3"
   },
   "engines": {
-    "node": "^24 || ^22 || ^20 || ^18",
+    "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18",
     "npm": ">= 6.13.4",
     "yarn": ">= 1.21.1"
   }
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/quasar.config.ts b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/quasar.config.ts
index 70afc2296d2..b56d8338514 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/quasar.config.ts
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/BASE/quasar.config.ts
@@ -1,11 +1,6 @@
-/* eslint-env node */
-
 // Configuration for your app
 // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js
 
-<% if (preset.lint && lintConfig === 'airbnb') { %>/* eslint func-names: 0 */
-/* eslint global-require: 0 */
-<% } %>
 import { defineConfig } from '#q-app/wrappers';
 <% if (preset.i18n) { %>import { fileURLToPath } from 'node:url';<% } %>
 
@@ -73,7 +68,7 @@ export default defineConfig((<% if (preset.i18n) { %>ctx<% } else { %>/* ctx */<
       // extendViteConf (viteConf) {},
       // viteVuePluginOptions: {},
 
-      <% if (preset.i18n || preset.lint) { %>vitePlugins: [<% if (preset.i18n) { %>
+      <% if (preset.i18n || preset.eslint) { %>vitePlugins: [<% if (preset.i18n) { %>
         ['@intlify/unplugin-vue-i18n/vite', {
           // if you want to use Vue I18n Legacy API, you need to set `compositionOnly: false`
           // compositionOnly: false,
@@ -86,11 +81,12 @@ export default defineConfig((<% if (preset.i18n) { %>ctx<% } else { %>/* ctx */<
 
           // you need to set i18n resource including paths !
           include: [ fileURLToPath(new URL('./src/i18n', import.meta.url)) ],
-        }]<% } %><% if (preset.lint) { %><% if (preset.i18n) { %>,<% } %>
+        }]<% } %><% if (preset.eslint) { %><% if (preset.i18n) { %>,<% } %>
         ['vite-plugin-checker', {
           vueTsc: true,
           eslint: {
-            lintCommand: 'eslint "./**/*.{js,ts,mjs,cjs,vue}"'
+            lintCommand: 'eslint',
+            useFlatConfig: true
           }
         }, { server: false }]<% } %>
       ]<% } else { %>
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/eslint/_eslint.config.js b/create-quasar/templates/app/quasar-v2/ts-vite-2/eslint/_eslint.config.js
new file mode 100644
index 00000000000..23eb6f1b1aa
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/eslint/_eslint.config.js
@@ -0,0 +1,66 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import pluginVue from 'eslint-plugin-vue'
+import pluginQuasar from '@quasar/app-vite/eslint'
+import vueTsEslintConfig from '@vue/eslint-config-typescript'<% if (prettier) { %>
+import prettierSkipFormatting from '@vue/eslint-config-prettier/skip-formatting'<% } %>
+
+export default [
+  {
+    /**
+     * Ignore the following files.
+     * Please note that pluginQuasar.configs.recommended already ignores
+     * the "node_modules" folder for you (and all other Quasar project
+     * relevant folders and files).
+     *
+     * ESLint requires "ignores" key to be the only one in this object
+     */
+    // ignores: []
+  },
+
+  pluginQuasar.configs.recommended,
+  js.configs.recommended,
+  ...pluginVue.configs[ 'flat/essential' ],
+  ...vueTsEslintConfig(),
+
+  {
+    languageOptions: {
+      ecmaVersion: 'latest',
+      sourceType: 'module',
+
+      globals: {
+        ...globals.browser,
+        ...globals.node, // SSR, Electron, config files
+        process: 'readonly', // process.env.*
+        ga: 'readonly', // Google Analytics
+        cordova: 'readonly',
+        Capacitor: 'readonly',
+        chrome: 'readonly', // BEX related
+        browser: 'readonly' // BEX related
+      }
+    },
+
+    linterOptions: {
+      reportUnusedDisableDirectives: 'warn'
+    },
+
+    // add your custom rules here
+    rules: {
+      'prefer-promise-reject-errors': 'off',
+
+      // allow debugger during development only
+      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
+    }
+  },
+
+  {
+    files: [ 'src-pwa/custom-service-worker.{js,ts}' ],
+    languageOptions: {
+      globals: {
+        ...globals.serviceworker
+      }
+    }
+  }<% if (prettier) { %>,
+
+  prettierSkipFormatting<% } %>
+]
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/index.js b/create-quasar/templates/app/quasar-v2/ts-vite-2/index.js
index a38f1025aca..8d1b74679a6 100644
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/index.js
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/index.js
@@ -5,7 +5,7 @@ export async function script ({ scope, utils }) {
       name: 'preset',
       message: 'Check the features needed for your project:',
       choices: [
-        { title: 'Linting (vite-plugin-checker + ESLint + vue-tsc)', value: 'lint', description: 'recommended', selected: true },
+        { title: 'Linting (vite-plugin-checker + ESLint + vue-tsc)', value: 'eslint', description: 'recommended', selected: true },
         { title: 'State Management (Pinia)', value: 'pinia', description: 'https://pinia.vuejs.org' },
         { title: 'axios', value: 'axios' },
         { title: 'vue-i18n', value: 'i18n' }
@@ -13,14 +13,10 @@ export async function script ({ scope, utils }) {
       format: utils.convertArrayToObject
     },
     {
-      type: (_, { preset }) => (preset.lint ? 'select' : null),
-      name: 'lintConfig',
-      message: 'Pick an ESLint preset:',
-      choices: [
-        { title: 'Prettier', value: 'prettier', description: 'https://github.com/prettier/prettier' },
-        { title: 'Standard', value: 'standard', description: 'https://github.com/standard/standard' },
-        { title: 'Airbnb', value: 'airbnb', description: 'https://github.com/airbnb/javascript' }
-      ]
+      type: (_, { preset }) => (preset.eslint ? 'confirm' : null),
+      name: 'prettier',
+      initial: false,
+      message: 'Add Prettier for code formatting?'
     }
   ])
 
@@ -30,12 +26,7 @@ export async function script ({ scope, utils }) {
 
   if (scope.preset.axios) utils.renderTemplate('axios', scope)
   if (scope.preset.i18n) utils.renderTemplate('i18n', scope)
-  if (scope.preset.lint) {
-    utils.renderTemplate('lint', scope)
-    if (scope.lintConfig === 'prettier') {
-      utils.renderTemplate('prettier', scope)
-    }
-  }
-
+  if (scope.preset.eslint) utils.renderTemplate('eslint', scope)
+  if (scope.prettier) utils.renderTemplate('prettier', scope)
   if (scope.preset.pinia) utils.renderTemplate('pinia', scope)
 }
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintignore b/create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintignore
deleted file mode 100644
index 9f81cf845b7..00000000000
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintignore
+++ /dev/null
@@ -1,7 +0,0 @@
-/dist
-/src-capacitor
-/src-cordova
-/.quasar
-/node_modules
-.eslintrc.cjs
-/quasar.config.*.temporary.compiled*
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintrc.cjs b/create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintrc.cjs
deleted file mode 100644
index 1371b09e9c1..00000000000
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/lint/_.eslintrc.cjs
+++ /dev/null
@@ -1,135 +0,0 @@
-module.exports = {
-  // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
-  // This option interrupts the configuration hierarchy at this file
-  // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
-  root: true,
-
-  // https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
-  // Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
-  // `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
-  parserOptions: {
-    parser: require.resolve('@typescript-eslint/parser'),
-    extraFileExtensions: [ '.vue' ]
-  },
-
-  env: {
-    browser: true,
-    es2021: true,
-    node: true
-  },
-
-  // Rules order is important, please avoid shuffling them
-  extends: [
-    // Base ESLint recommended rules
-    // 'eslint:recommended',
-
-    // https://typescript-eslint.io/getting-started/legacy-eslint-setup
-    // ESLint typescript rules
-    'plugin:@typescript-eslint/recommended',
-
-    // Uncomment any of the lines below to choose desired strictness,
-    // but leave only one uncommented!
-    // See https://eslint.vuejs.org/rules/#available-rules
-    'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
-    // 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
-    // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
-
-    <% if (lintConfig === 'standard') { %>'standard'
-    <% } else if (lintConfig === 'airbnb') { %>'airbnb-base'
-    <% } else if (lintConfig === 'prettier') { %>// https://github.com/prettier/eslint-config-prettier#installation
-    // usage with Prettier, provided by 'eslint-config-prettier'.
-    'prettier'<% } %>
-  ],
-
-  plugins: [
-    // required to apply rules which need type information
-    '@typescript-eslint',
-
-    // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
-    // required to lint *.vue files
-    'vue'
-    <% if (lintConfig === 'prettier') { %>
-    // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
-    // Prettier has not been included as plugin to avoid performance impact
-    // add it as an extension for your IDE
-    <% } %>
-  ],
-
-  globals: {
-    ga: 'readonly', // Google Analytics
-    cordova: 'readonly',
-    __statics: 'readonly',
-    __QUASAR_SSR__: 'readonly',
-    __QUASAR_SSR_SERVER__: 'readonly',
-    __QUASAR_SSR_CLIENT__: 'readonly',
-    __QUASAR_SSR_PWA__: 'readonly',
-    process: 'readonly',
-    Capacitor: 'readonly',
-    chrome: 'readonly'
-  },
-
-  // add your custom rules here
-  rules: {
-    <% if (lintConfig === 'standard') { %>
-    // allow async-await
-    'generator-star-spacing': 'off',
-    // allow paren-less arrow functions
-    'arrow-parens': 'off',
-    'one-var': 'off',
-    'no-void': 'off',
-    'multiline-ternary': 'off',
-
-    'import/first': 'off',
-    'import/namespace': 'error',
-    'import/default': 'error',
-    'import/export': 'error',
-    'import/extensions': 'off',
-    'import/no-unresolved': 'off',
-    'import/no-extraneous-dependencies': 'off',
-
-    // The core 'import/named' rules
-    // does not work with type definitions
-    'import/named': 'off',
-    <% } else if (lintConfig === 'airbnb') { %>
-    'no-plusplus': 'off',
-    'no-param-reassign': 'off',
-    'no-void': 'off',
-    'no-nested-ternary': 'off',
-    'max-classes-per-file': 'off',
-
-    'no-shadow': 'off',
-    '@typescript-eslint/no-shadow': 'error',
-
-    'import/first': 'off',
-    'import/named': 'error',
-    'import/namespace': 'error',
-    'import/default': 'error',
-    'import/export': 'error',
-    'import/extensions': 'off',
-    'import/no-unresolved': 'off',
-    'import/no-extraneous-dependencies': 'off',
-    'import/prefer-default-export': 'off',
-    <% } %>
-    'prefer-promise-reject-errors': 'off',
-
-    quotes: ['warn', 'single', { avoidEscape: true }],
-
-    // this rule, if on, would require explicit return type on the `render` function
-    '@typescript-eslint/explicit-function-return-type': 'off',
-
-    // in plain CommonJS modules, you can't use `import foo = require('foo')` to pass this rule, so it has to be disabled
-    '@typescript-eslint/no-var-requires': 'off',
-
-    '@typescript-eslint/consistent-type-imports': [
-      'error',
-      { prefer: 'type-imports' },
-    ],
-
-    // The core 'no-unused-vars' rules (in the eslint:recommended ruleset)
-    // does not work with type definitions
-    'no-unused-vars': 'off',
-
-    // allow debugger during development only
-    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
-  }
-}
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc b/create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc
deleted file mode 100644
index 650cb880f6f..00000000000
--- a/create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "singleQuote": true,
-  "semi": true
-}
diff --git a/create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc.json b/create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc.json
new file mode 100644
index 00000000000..29a2402ef05
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/ts-vite-2/prettier/_.prettierrc.json
@@ -0,0 +1,6 @@
+{
+  "$schema": "https://json.schemastore.org/prettierrc",
+  "semi": false,
+  "singleQuote": true,
+  "printWidth": 100
+}
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/README.md b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/README.md
index 9e7f870e5ee..702bea50ee3 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/README.md
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/README.md
@@ -13,7 +13,7 @@ npm install
 ```bash
 quasar dev
 ```
-<% if (preset.lint) { %>
+<% if (preset.eslint) { %>
 
 ### Lint the files
 ```bash
@@ -21,7 +21,7 @@ yarn lint
 # or
 npm run lint
 ```
-<% if (lintConfig === 'prettier') { %>
+<% if (prettier) { %>
 
 ### Format the files
 ```bash
@@ -29,8 +29,7 @@ yarn format
 # or
 npm run format
 ```
-<% } %>
-<% } %>
+<% } } %>
 
 ### Build the app for production
 ```bash
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.editorconfig b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.editorconfig
index 9d08a1a828a..f654551630b 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.editorconfig
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.editorconfig
@@ -1,9 +1,7 @@
-root = true
-
-[*]
+[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue}]
 charset = utf-8
-indent_style = space
 indent_size = 2
+indent_style = space
 end_of_line = lf
 insert_final_newline = true
 trim_trailing_whitespace = true
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/extensions.json b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/extensions.json
index 5d59d46ce93..763fe5d6efe 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/extensions.json
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/extensions.json
@@ -1,7 +1,7 @@
 {
   "recommendations": [
-    <% if (preset.lint) { %>"dbaeumer.vscode-eslint",
-    <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode",<% } } %>
+    <% if (preset.eslint) { %>"dbaeumer.vscode-eslint",<% } %>
+    <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode",<% } %>
     "editorconfig.editorconfig",
     "vue.volar",
     "wayou.vscode-todo-highlight"
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/settings.json b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/settings.json
index 9fe8f5a6f3b..b07ec68ba65 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/settings.json
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_.vscode/settings.json
@@ -1,8 +1,8 @@
 {
   "editor.bracketPairColorization.enabled": true,
-  "editor.guides.bracketPairs": true,<% if (preset.lint) { %>
+  "editor.guides.bracketPairs": true,<% if (preset.eslint) { %>
   "editor.formatOnSave": true,
-  "editor.defaultFormatter": <% if (lintConfig === 'prettier') { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
+  "editor.defaultFormatter": <% if (prettier) { %>"esbenp.prettier-vscode"<% } else { %>"dbaeumer.vscode-eslint"<% } %>,
   "editor.codeActionsOnSave": [
     "source.fixAll.eslint"
   ],
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_package.json b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_package.json
index fafd9aab478..7c39d1edac5 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_package.json
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/_package.json
@@ -5,10 +5,10 @@
   "productName": "<%= productName %>",
   "author": "<%= author %>",
   "private": true,
+  "type": "module",
   "scripts": {
-    <% if (preset.lint) { %>"lint": "eslint --ext .js,.ts,.vue ./",
-    <% if (lintConfig === 'prettier') { %>"format": "prettier --write \"**/*.{js,ts,vue,<% if (css !== 'sass') { %><%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
-    <% } %>
+    <% if (preset.eslint) { %>"lint": "eslint --ext .js,.ts,.vue ./",<% } %>
+    <% if (prettier) { %>"format": "prettier --write \"**/*.{js,ts,vue,<% if (css !== 'sass') { %><%= css %><% } %>,html,md,json}\" --ignore-path .gitignore",<% } %>
     "test": "echo \"No test specified\" && exit 0",
     "dev": "quasar dev",
     "build": "quasar build",
@@ -25,24 +25,18 @@
     "vue-router": "^4.0.0"
   },
   "devDependencies": {
-    <% if (preset.lint) { %>
-    "@typescript-eslint/eslint-plugin": "^7.16.0",
-    "@typescript-eslint/parser": "^7.16.0",
-    "eslint": "^8.57.0",
-    "eslint-plugin-vue": "^9.0.0",
-    "eslint-webpack-plugin": "^4.0.1",
-    <% if (lintConfig === 'standard') { %>
-    "eslint-config-standard": "^17.0.0",
-    "eslint-plugin-import": "^2.19.1",
-    "eslint-plugin-n": "^15.0.0",
-    "eslint-plugin-promise": "^6.0.0",
-    <% } else if (lintConfig === 'airbnb') { %>
-    "eslint-config-airbnb-base": "^15.0.0",
-    "eslint-plugin-import": "^2.20.1",
-    <% } else if (lintConfig === 'prettier') { %>
-    "eslint-config-prettier": "^9.0.0",
-    "prettier": "^3.0.3",
-    <% } } %>
+    <% if (preset.eslint) { %>
+    "@eslint/js": "^9.14.0",
+    "eslint": "^9.14.0",
+    "eslint-plugin-vue": "^9.30.0",
+    "eslint-webpack-plugin": "^4.2.0",
+    "@vue/eslint-config-typescript": "^14.1.3",
+    "globals": "^15.12.0",
+    <% } %>
+    <% if (prettier) { %>
+    "@vue/eslint-config-prettier": "^10.1.0",
+    "prettier": "^3.3.3",
+    <% } %>
     "@types/node": "^20.5.9",
     "@quasar/app-webpack": "^4.0.0",
     "ts-loader": "^9.4.2",
@@ -60,7 +54,7 @@
     "last 5 Opera versions"
   ],
   "engines": {
-    "node": "^24 || ^22 || ^20 || ^18",
+    "node": "^28 || ^26 || ^24 || ^22 || ^20 || ^18",
     "npm": ">= 6.13.4",
     "yarn": ">= 1.21.1"
   }
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/quasar.config.ts b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/quasar.config.ts
index 9a45c3801ab..fada5576b4e 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/quasar.config.ts
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/BASE/quasar.config.ts
@@ -1,20 +1,14 @@
-/* eslint-env node */
-
 // Configuration for your app
 // https://v2.quasar.dev/quasar-cli-webpack/quasar-config-js
 
-<% if (preset.lint) { %>
+<% if (preset.eslint) { %>
 /* eslint-disable @typescript-eslint/no-var-requires */
-<% if (lintConfig === 'airbnb') { %>
-/* eslint func-names: 0 */
-/* eslint global-require: 0 */
-<% } %>
 <% } %>
 import { defineConfig } from '#q-app/wrappers';
 
 export default defineConfig((/* ctx */) => {
   return {
-    <% if (preset.lint) { %>eslint: {
+    <% if (preset.eslint) { %>eslint: {
       // fix: true,
       // include: [],
       // exclude: [],
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/eslint/_eslint.config.js b/create-quasar/templates/app/quasar-v2/ts-webpack-4/eslint/_eslint.config.js
new file mode 100644
index 00000000000..14d229c0abb
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/eslint/_eslint.config.js
@@ -0,0 +1,66 @@
+import js from '@eslint/js'
+import globals from 'globals'
+import pluginVue from 'eslint-plugin-vue'
+import pluginQuasar from '@quasar/app-webpack/eslint'
+import vueTsEslintConfig from '@vue/eslint-config-typescript'<% if (prettier) { %>
+import prettierSkipFormatting from '@vue/eslint-config-prettier/skip-formatting'<% } %>
+
+export default [
+  {
+    /**
+     * Ignore the following files.
+     * Please note that pluginQuasar.configs.recommended already ignores
+     * the "node_modules" folder for you (and all other Quasar project
+     * relevant folders and files).
+     *
+     * ESLint requires "ignores" key to be the only one in this object
+     */
+    // ignores: []
+  },
+
+  pluginQuasar.configs.recommended,
+  js.configs.recommended,
+  ...pluginVue.configs[ 'flat/essential' ],
+  ...vueTsEslintConfig(),
+
+  {
+    languageOptions: {
+      ecmaVersion: 'latest',
+      sourceType: 'module',
+
+      globals: {
+        ...globals.browser,
+        ...globals.node, // SSR, Electron, config files
+        process: 'readonly', // process.env.*
+        ga: 'readonly', // Google Analytics
+        cordova: 'readonly',
+        Capacitor: 'readonly',
+        chrome: 'readonly', // BEX related
+        browser: 'readonly' // BEX related
+      }
+    },
+
+    linterOptions: {
+      reportUnusedDisableDirectives: 'warn'
+    },
+
+    // add your custom rules here
+    rules: {
+      'prefer-promise-reject-errors': 'off',
+
+      // allow debugger during development only
+      'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
+    }
+  },
+
+  {
+    files: [ 'src-pwa/custom-service-worker.{js,ts}' ],
+    languageOptions: {
+      globals: {
+        ...globals.serviceworker
+      }
+    }
+  }<% if (prettier) { %>,
+
+  prettierSkipFormatting<% } %>
+]
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/index.js b/create-quasar/templates/app/quasar-v2/ts-webpack-4/index.js
index 064e411f1e9..439744a07ca 100644
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/index.js
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/index.js
@@ -5,7 +5,7 @@ export async function script ({ scope, utils }) {
       name: 'preset',
       message: 'Check the features needed for your project:',
       choices: [
-        { title: 'Linting (ESLint)', value: 'lint', description: 'recommended', selected: true },
+        { title: 'Linting (ESLint)', value: 'eslint', description: 'recommended', selected: true },
         { title: 'State Management (Pinia)', value: 'pinia', description: 'https://pinia.vuejs.org' },
         { title: 'axios', value: 'axios' },
         { title: 'vue-i18n', value: 'i18n' }
@@ -13,14 +13,10 @@ export async function script ({ scope, utils }) {
       format: utils.convertArrayToObject
     },
     {
-      type: (_, { preset }) => (preset.lint ? 'select' : null),
-      name: 'lintConfig',
-      message: 'Pick an ESLint preset:',
-      choices: [
-        { title: 'Prettier', value: 'prettier', description: 'https://github.com/prettier/prettier' },
-        { title: 'Standard', value: 'standard', description: 'https://github.com/standard/standard' },
-        { title: 'Airbnb', value: 'airbnb', description: 'https://github.com/airbnb/javascript' }
-      ]
+      type: (_, { preset }) => (preset.eslint ? 'confirm' : null),
+      name: 'prettier',
+      initial: false,
+      message: 'Add Prettier for code formatting?'
     }
   ])
 
@@ -30,12 +26,7 @@ export async function script ({ scope, utils }) {
 
   if (scope.preset.axios) utils.renderTemplate('axios', scope)
   if (scope.preset.i18n) utils.renderTemplate('i18n', scope)
-  if (scope.preset.lint) {
-    utils.renderTemplate('lint', scope)
-    if (scope.lintConfig === 'prettier') {
-      utils.renderTemplate('prettier', scope)
-    }
-  }
-
+  if (scope.preset.eslint) utils.renderTemplate('eslint', scope)
+  if (scope.prettier) utils.renderTemplate('prettier', scope)
   if (scope.preset.pinia) utils.renderTemplate('pinia', scope)
 }
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintignore b/create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintignore
deleted file mode 100644
index d6fdd5b809c..00000000000
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintignore
+++ /dev/null
@@ -1,8 +0,0 @@
-/dist
-/src-capacitor
-/src-cordova
-/.quasar
-/node_modules
-.eslintrc.cjs
-babel.config.cjs
-/quasar.config.*.temporary.compiled*
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintrc.cjs b/create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintrc.cjs
deleted file mode 100644
index 72cc135578c..00000000000
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/lint/_.eslintrc.cjs
+++ /dev/null
@@ -1,139 +0,0 @@
-
-module.exports = {
-  // https://eslint.org/docs/user-guide/configuring#configuration-cascading-and-hierarchy
-  // This option interrupts the configuration hierarchy at this file
-  // Remove this if you have an higher level ESLint config file (it usually happens into a monorepos)
-  root: true,
-
-  // https://eslint.vuejs.org/user-guide/#how-to-use-a-custom-parser
-  // Must use parserOptions instead of "parser" to allow vue-eslint-parser to keep working
-  // `parser: 'vue-eslint-parser'` is already included with any 'plugin:vue/**' config and should be omitted
-  parserOptions: {
-    parser: require.resolve('@typescript-eslint/parser'),
-    extraFileExtensions: [ '.vue' ]
-  },
-
-  env: {
-    browser: true,
-    es2021: true,
-    node: true
-  },
-
-  // Rules order is important, please avoid shuffling them
-  extends: [
-    // Base ESLint recommended rules
-    // 'eslint:recommended',
-
-    // https://typescript-eslint.io/getting-started/legacy-eslint-setup
-    // ESLint typescript rules
-    'plugin:@typescript-eslint/recommended',
-
-    // Uncomment any of the lines below to choose desired strictness,
-    // but leave only one uncommented!
-    // See https://eslint.vuejs.org/rules/#available-rules
-    'plugin:vue/vue3-essential', // Priority A: Essential (Error Prevention)
-    // 'plugin:vue/vue3-strongly-recommended', // Priority B: Strongly Recommended (Improving Readability)
-    // 'plugin:vue/vue3-recommended', // Priority C: Recommended (Minimizing Arbitrary Choices and Cognitive Overhead)
-
-    <% if (lintConfig === 'standard') { %>'standard'
-    <% } else if (lintConfig === 'airbnb') { %>'airbnb-base'
-    <% } else if (lintConfig === 'prettier') { %>// https://github.com/prettier/eslint-config-prettier#installation
-    // usage with Prettier, provided by 'eslint-config-prettier'.
-    'prettier'<% } %>
-  ],
-
-  plugins: [
-    // required to apply rules which need type information
-    '@typescript-eslint',
-
-    // https://eslint.vuejs.org/user-guide/#why-doesn-t-it-work-on-vue-files
-    // required to lint *.vue files
-    'vue'
-    <% if (lintConfig === 'prettier') { %>
-    // https://github.com/typescript-eslint/typescript-eslint/issues/389#issuecomment-509292674
-    // Prettier has not been included as plugin to avoid performance impact
-    // add it as an extension for your IDE
-    <% } %>
-  ],
-
-  globals: {
-    ga: 'readonly', // Google Analytics
-    cordova: 'readonly',
-    __statics: 'readonly',
-    __QUASAR_SSR__: 'readonly',
-    __QUASAR_SSR_SERVER__: 'readonly',
-    __QUASAR_SSR_CLIENT__: 'readonly',
-    __QUASAR_SSR_PWA__: 'readonly',
-    process: 'readonly',
-    Capacitor: 'readonly',
-    chrome: 'readonly',
-  },
-
-  // add your custom rules here
-  rules: {
-    <% if (lintConfig === 'standard') { %>
-    // allow async-await
-    'generator-star-spacing': 'off',
-    // allow paren-less arrow functions
-    'arrow-parens': 'off',
-    'one-var': 'off',
-    'no-void': 'off',
-    'multiline-ternary': 'off',
-
-    'import/first': 'off',
-    'import/namespace': 'error',
-    'import/default': 'error',
-    'import/export': 'error',
-    'import/extensions': 'off',
-    'import/no-unresolved': 'off',
-    'import/no-extraneous-dependencies': 'off',
-
-    // The core 'import/named' rules
-    // does not work with type definitions
-    'import/named': 'off',
-    <% } else if (lintConfig === 'airbnb') { %>
-    'no-plusplus': 'off',
-    'no-param-reassign': 'off',
-    'no-void': 'off',
-    'no-nested-ternary': 'off',
-    'max-classes-per-file': 'off',
-
-    'no-shadow': 'off',
-    '@typescript-eslint/no-shadow': 'error',
-
-    'import/first': 'off',
-    'import/namespace': 'error',
-    'import/default': 'error',
-    'import/export': 'error',
-    'import/extensions': 'off',
-    'import/no-unresolved': 'off',
-    'import/no-extraneous-dependencies': 'off',
-    'import/prefer-default-export': 'off',
-
-    // The core 'import/named' rules
-    // does not work with type definitions
-    'import/named': 'off',
-    <% } %>
-    'prefer-promise-reject-errors': 'off',
-
-    quotes: ['warn', 'single', { avoidEscape: true }],
-
-    // this rule, if on, would require explicit return type on the `render` function
-    '@typescript-eslint/explicit-function-return-type': 'off',
-
-    // in plain CommonJS modules, you can't use `import foo = require('foo')` to pass this rule, so it has to be disabled
-    '@typescript-eslint/no-var-requires': 'off',
-
-    '@typescript-eslint/consistent-type-imports': [
-      'error',
-      { prefer: 'type-imports' },
-    ],
-
-    // The core 'no-unused-vars' rules (in the eslint:recommended ruleset)
-    // does not work with type definitions
-    'no-unused-vars': 'off',
-
-    // allow debugger during development only
-    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
-  }
-}
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc b/create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc
deleted file mode 100644
index 650cb880f6f..00000000000
--- a/create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "singleQuote": true,
-  "semi": true
-}
diff --git a/create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc.json b/create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc.json
new file mode 100644
index 00000000000..29a2402ef05
--- /dev/null
+++ b/create-quasar/templates/app/quasar-v2/ts-webpack-4/prettier/_.prettierrc.json
@@ -0,0 +1,6 @@
+{
+  "$schema": "https://json.schemastore.org/prettierrc",
+  "semi": false,
+  "singleQuote": true,
+  "printWidth": 100
+}