@qlik/eslint-config
v2.0.6
Published
Qlik's ESLint configs
Downloads
61,871
Readme
@qlik/eslint-config
Qlik's ESlint config for JavaScript/TypeScript environments with optional framework support.
Built for ease of use and low config. It is built on standard configs from @eslint/js and typescript-eslint
and their recommended configs. And it adds some extra support for vitest that will add lint rules for unit test
based on standard settings. It is built for basically zero config and will "just work" for standard projects.
Migrating from v1->v2 ?
Go to the migration section
Quick Start
Example eslint.config.js that uses typescript, react, vitest. Suitable for a bundler environment for react
development and vitest unit testing.
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.react,
...qlik.configs.vitest,
{
rules: {
// Override rules if needed
},
},
// Put ignores in its own object so it's global
{
ignores: ["dist", "script"],
},
);Add another eslint plugin just like you would normally do.
// @ts-check
import qlik from "@qlik/eslint-config";
import pluginQuery from "@tanstack/eslint-plugin-query";
import { defineConfig } from "eslint/config";
export default defineConfig([
...qlik.configs.react,
...qlik.configs.vitest,
pluginQuery.configs["flat/recommended"],
{
ignores: ["dist", "script", "my-special-no-linting.ts"],
},
]);typescript
When using typescript with @qlik/eslint-config, include all files that should be linted (e.g. "include": [".*", "**/*"]) in the project's tsconfig.json so that the files are picked up by the project service when linting.
Usage
The default exports configs works on both TypeScript and JavaSript out of the box. (as long as the file endings are any of .js, .jsx, .mjs, .cjs, .ts, .tsx, .cts, .mts).
The configs are eslint flat config arrays populated with configs that has appropriate file endings attached to them. Designed
to diminish the amount of configuration needed in an eslint.config.js file.
To get started, create eslint.config.js (if your package json has "type": "module"), otherwise create eslint.config.mjs.
If you are not building your project with TypeScript (using Webpack or Vite for example), then tell TypeScript to include
all files by setting "include": [".*", "**/*"] in tsconfig.json.
For a pure browser environment with a bundler and no specific framework use:
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.recommended, // adds linting on .js, .jsx, .mjs, .cjs, .ts, .tsx, .cts, .mts files. use for pure browser environment
{
ignores: ["dist"],
},
);Using React:
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.react, // based on the recommended config and adds react linting on .jsx and .tsx files
{
ignores: ["dist"],
},
);Using Pure ES modules in browser:
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.esbrowser, // based on the recommended config and adds specific es module rules (file endings)
{
ignores: ["dist"],
},
);Node environment:
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.esm, // or qlik.configs.cjs for commonjs, recommended config with node environment enabled
{
ignores: ["dist"],
},
);Additional configs that can be used in conjunction with the ones above:
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.recommended, // pure browser environment
...qlik.configs.vitest, // enable vitest linting on files inside __test(s)__ folder
...qlik.configs.playwright, // enable playwright linting on files inside ./test(s) folder.
{
ignores: ["dist"],
},
);What if the playwright test files are not in the default ./test folder?
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.recommended, // pure browser environment
...qlik.configs.vitest, // enable vitest linting on files inside __test(s)__ folder
{
files: ["playwright/**/*.{js,jsx,ts,tsx}"], // will lint the files inside ./playwright folder with the playwright plugin
extends: [...qlik.configs.playwright],
},
{
ignores: ["dist"],
},
);
Example: Using React with vitest:
// @ts-check
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.react, // based on the recommended config and adds react linting on .jsx and .tsx files
...qlik.configs.vitest, // enable vitest linting on files inside __test(s)__ folder
{
ignores: ["dist"],
},
);Using the named exports configs
The different configs are also accessible through named imports. These configs can be used in specific scenarios where more
control of the configs are needed. The extends property can be used to apply a config on certain file patterns.
Example only use javascript rules with react
import { reactJS } from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
reactJS,
)with typescript support
import { reactJS, reactTS } from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
reactJS,
reactTS,
)This is equal to:
import qlik from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.react,
)The single configs can be useful together with the extends property. Below shows an example of a config
that wants to use lint rules for node environment on a part of the code base.
import qlik, { esmJS, cjsJS } from "@qlik/eslint-config";
import { defineConfig } from "eslint/config";
export default defineConfig(
// apply recommended config to all files
...qlik.configs.recommended,
{
// set node esm config on .mjs files inside the tools folder
files: ["tools/**/*.mjs"],
extends: [esmJS],
},
{
// set node commonJS config on .cjs files inside the tools folder
files: ["tools/**/*.cjs"],
extends: [cjsJS],
},
)
Migrating
The biggest changes between v1 and v2 is the plugins used. Since a lot of plugins does not yet support ESLint 10 Some of the plugins was removed or replaced from v1.
eslint-plugin-jsx-a11y- Removedeslint-plugin-jest- Removedeslint-plugin-playwright- Removedeslint-plugin-svelte- Removedeslint-plugin-react- Replaced with @eslint-react/eslint-plugineslint-plugin-react-hooks- Replaced with @eslint-react/eslint-plugin
When migrating from v1 -> v2 do the following:
Automatic:
Use the prompt supplied below and give to a co-pilot agent.
Manual:
- Remove the
qlik.composefunction and replace it withdefineConfig - If you were using any of the removed plugins (e.g. eslint-plugin-jest) you will have to add it to the eslint config.
- This new config has a stricter set of rules applied, especially in the typescript files. Also, some rules might have been removed (removed plugins) or changed. So you might see new lint errors after migrating. But it's highlighting possible problems in the code so spend some time fixing the errors. Disabling rules should only be done when you have good reasons.
Example of migration:
old config:
// @ts-check
import qlik from "@qlik/eslint-config";
import pluginQuery from "@tanstack/eslint-plugin-query";
export default qlik.compose(
...qlik.configs.react,
...qlik.configs.vitest,
pluginQuery.configs["flat/recommended"],
{
rules: {
// Override rules if needed
},
},
// In its own object so it's global
{
ignores: ["dist", "node_modules", "script"],
},
);- add
import { defineConfig } from "eslint/config"; - replace
qlik.composewithdefineConfig - replace
extendwithextends(if present)
new config:
// @ts-check
import qlik from "@qlik/eslint-config";
import pluginQuery from "@tanstack/eslint-plugin-query";
import { defineConfig } from "eslint/config";
export default defineConfig(
...qlik.configs.react,
...qlik.configs.vitest,
pluginQuery.configs["flat/recommended"],
{
rules: {
// Override rules if needed
},
},
// In its own object so it's global
{
ignores: ["dist", "node_modules", "script"],
},
);If you are using jest the eslint-plugin-jest has been removed, so you may want to add it to your config.
Add eslint-plugin-jest to your npm dependencies and simply add a new section targeting your jest files with the plugin added.
Look at the plugin's documentation
Same things applies to eslint-plugin-playwright
AI Prompt
Use this prompt for migrating:
I want to migrate this project from ESLint v9 to ESLint v10 and update `@qlik/eslint-config` to v2 which supports ESLint v10.
The changes in `@qlik/eslint-config` from v1 -> v2 are mainly changes of which plugins are used.
- `eslint-plugin-jsx-a11y` - Removed
- `eslint-plugin-jest` - Removed
- `eslint-plugin-playwright` - Removed
- `eslint-plugin-svelte` - Removed
- `eslint-plugin-react` - Replaced with [@eslint-react/eslint-plugin](https://github.com/Rel1cx/eslint-react)
- `eslint-plugin-react-hooks` - Replaced with [@eslint-react/eslint-plugin](https://github.com/Rel1cx/eslint-react)
The default settings now also include stricter typescript rules.
Follow these steps carefully and explain changes where non-trivial:
1. Update dependencies:
- Set `eslint` to the latest version (v10)
- Set `@qlik/eslint-config` to the latest version (v2)
2. Install dependencies and ensure there are no version conflicts.
3. Remove or update any constraints that block ESLint or upgrades:
- `resolutions`, `overrides`, or pinned versions in `package.json`
- `.ncurc.json` rules preventing upgrades
4. Migrate ESLint config to be compatible with ESLint 10:
- Ensure flat config format is used (`eslint.config.js/ts`)
- Import `defineConfig` from `"eslint/config"`
- Replace any usage of `qlik.compose` with `defineConfig` where applicable
- Replace any usage of `extend` with `extends`
- Ensure plugins and configs are compatible with ESLint 10
5. Run `npx eslint . --fix`
6. Handle remaining issues:
- Prefer code fixes over disabling rules
- Only disable rules if absolutely necessary
- For every disabled rule, add a comment explaining why
7. Validation:
- ESLint runs without errors
- No critical rules are disabled silently
- The project builds and tests still pass
8. Output:
- Summary of changes made
- List of rules disabled (if any) with justification
- Any potential risks or follow-ups
Important:
- Do not make changes that alter runtime behavior or business logic.
- If uncertain, ask before making destructive or unclear changes.