@krakentech/eslint-config v1.0.0
This package provides a wide range of "recommended" ESLint configs with the goal of minimising end-user configuration and increasing consistency across projects. It is designed around ESLint v9 to allow for easily shareable, modular and extensible configurations by leveraging the new "Flat" config files.
Installation
We publish our ESLint config publicy on npm. No registry token or
authentication is required to install the config. Install it alongside the latest eslint version using your preferred
package manager:
pnpm add -D @krakentech/eslint-config eslintyarn add -D @krakentech/eslint-config eslintnpm install --save-dev @krakentech/eslint-config eslint!NOTE If you are using a monorepo it's still recommended to install the package at the root of the project. ESlint v9 is now able to apply rules top down, making it trivial to limit specific rule-sets to the right files. For example, the recommended NextJS package can easily be restricted to
apps/webif that is the only NextJS application in the monorepo.
Configuration
ESLint v9 now enforces the use of a file named eslint.config.js. This should be placed at the root of your project. Configuration of the whole repository can be done from this single file. Simply load the package and export linters.load(FlatConfig, ...).
Each FlatConfig only requires the user to define which files should have which plugins applied to them (or ignores) and which plugins the config extends from. You can pass as many configs as you like.
!IMPORTANT If you don't define any
filesfor a config, the default behaviour it to lint all project files! This may affect performance.
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
// Ignore all node_modules and dist folders
{
ignores: ["**/node_modules/**", "**/dist/**"],
},
// Apply recommended typescript rules to all
// Typescript files in the repo
{
files: ["**/*.{ts,tsx,mts,cts}"],
extends: linters.configs.typescript.recommended,
},
);// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
// Also ignore next build folder
{
ignores: [
"**/node_modules/**",
"**/dist/**",
"**/.next/**"
],
},
// Apply recommended next rules to all apps
{
files: ["apps/**/*.{ts,tsx}"],
extends: linters.configs.next.recommended,
},
// Only apply typescript rules to packages
{
files: ["packages/**/*.{ts,mts,cts}"],
extends: linters.configs.typescript.recommended,
},
);!TIP We support both CJS and ESM config files! You can use
importandexport defaultif your package package type is set tomodule.
Fine tuning configurations
Whilst we suggest that you try to use the recommended configurations where possible to maintain consistency across projects, it is still simple to "extend" our recommended configs and "override" specific rules.
Simple Typescript Package
For example, lets say we want to create a ReactJS project that uses Typescript and disables the @typescript-eslint/no-explicit-any rule:
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
// ... other configs
{
files: ["**/*.{ts,tsx}"],
extends: [
// Load recommended Javascript rules
...linters.configs.javascript.recommended,
// Load the recommended typescript configs
...linters.configs.typescript.recommended,
// Then extend it with the React config
...linters.configs.react.recommended,
],
// Override a specific rule
rules: {
"@typescript-eslint/no-explicit-any": "off",
},
},
);Monorepo with multiple apps, packages and tests
// eslint.config.js
const linters = require("@krakentech/eslint-config");
module.exports = linters.load(
// Global ignores across the whole repo
{
ignores: ["**/node_modules/**", "**/build/**", "**/*.typegen.*/**"],
},
// Apply Javascript recommended rules to all js(x) and ts(x) files
{
files: ["**/*.{js,jsx,ts,tsx}"],
extends: linters.configs.javascript.recommended,
},
// Apply next recommended rules to all apps
{
files: ["apps/**/*.{ts,tsx}"],
extends: linters.configs.next.recommended,
},
// Only apply typescript rules to packages
{
files: ["packages/**/*.{ts,mts,cts}"],
extends: linters.configs.typescript.recommended,
},
// Applies react rules to all react files. This should also catch most test
// files too.
{
files: ["**/*.{jsx,tsx}"],
extends: [
...linters.configs.react.recommended, // Includes jsxa11y
],
},
// Applies jest rules to test files
{
files: ["**/*.spec.{js,jsx,ts,tsx}"],
extends: linters.configs.jest.recommended,
},
);!TIP Some plugins have "utility" configs that do something specific to that plugin (usually to disable rules). Use these the same way you would use the
baseconfigs.
export type LinterConfig = {
base: FlatConfig;
recommended: ConfigArray;
utils?: Record<string, FlatConfig>;
};
export type PackageConfig = {
load: (...configs: InfiniteDepthConfigWithExtends[]) => ConfigArray;
configs: Record<string, LinterConfig>;
};Plugins
The following plugins are supported by this package. Many of the recommended ConfigArray's only contain the base plugin, however, the recommended Typescript, React and NextJS configs contain multiple plugins, for which the table below also indicates the other plugins that are loaded.
| Plugin | Typescript | React | NextJS |
|---|---|---|---|
@eslint/js | ✅ | ⛔ | ✅ |
typescript-eslint | ✅ | ⛔ | ✅ |
eslint-plugin-import | ✅ | ⛔ | ✅ |
eslint-plugin-simple-import-sort | ✅ | ⛔ | ✅ |
eslint-plugin-react | ⛔ | ✅ | ✅ |
eslint-plugin-react-hooks | ⛔ | ✅ | ✅ |
eslint-plugin-jsx-a11y | ⛔ | ✅ | ✅ |
@next/eslint-plugin-next | ⛔ | ⛔ | ✅ |
eslint-plugin-turbo | ⛔ | ⛔ | ⛔ |
@vitest/eslint-plugin | ⛔ | ⛔ | ⛔ |
eslint-plugin-jest | ⛔ | ⛔ | ⛔ |
eslint-plugin-prettier | ⛔ | ⛔ | ⛔ |
!IMPORTANT The recommended configs are configurations we think you should use in your projects, not that they necessarily use the recommended rules sets. Whilst most do use the recommended rule sets, it's good to check which rules sets using the JSDoc strings on each export or the plugin details below.
Examples
Base Configs
@eslint/js
Overrides
no-console-["error", { allow: ["warn"] }]
typescript-eslint
We use the "Strict TypeChecked" rules (which automatically brings in the "Recommended" rules) to provide the most accurate type checking.
Overrides
@typescript-eslint/no-unused-vars- Allows the use of the
_prefix for unused variables - Will ignore unused destructured rest siblings:
{ ignoreMe, ...butNotMe } = someObject
- Allows the use of the
@typescript-eslint/consistent-type-imports- Prefers types are always imported using the
typekeyword - e.g.
import { type Foo }overimport { Foo } - This works well the fixable rule
import/consistent-type-specifier-styleto ensure import consistency.
The following have been disabled:
@typescript-eslint/no-confusing-void-expression- Off@typescript-eslint/restrict-template-expressions- Off@typescript-eslint/no-unsafe-enum-comparison- Off@typescript-eslint/unbound-method- Off@typescript-eslint/no-floating-promises- Off
!TIP We provide the
configs.typescript.utils.disableTypeCheckingutility to disable the type checking rules if you need to disable type checking for whatever reason (e.g. old JSX only components).
eslint-plugin-import and eslint-plugin-simple-import-sort
We use both packages in configs.imports.recommended. We prefer eslint-plugin-simple-import-sort for import sorting because it requires less configuration to apply sensible sorting, is easier to configure and only creates an single issue if there's an error in the sorting. We also include eslint-plugin-import for a few rules that the former does not handle:
import/first- Ensure all imports appear before other statements.import/newline-after-import- Enforce a newline after import statements.import/no-duplicates- Forbid repeated import of the same module in multiple places.import/consistent-type-specifier-style- Ensure that we consistently useimport { type Foo }.
We provide the ability to disable the simple-import-sort plugin if it does not fit well with your project. Simply extend your config with this utility like so:
// eslint.config.js
import linters from "@krakentech/eslint-config";
export default linters.load({
files: ["**/*.{ts,tsx}"],
extends: [
...linters.configs.typescript.recommended,
linters.configs.imports.utils.disableSimpleImportSort,
],
});eslint-plugin-react, eslint-plugin-react-hooks and eslint-plugin-jsx-a11y
eslint-plugin-reactRecommended Rule Seteslint-plugin-jsx-a11yStrict Rule Setreact-hooks/rules-of-hooks- Enforce rules of hooks.react-hooks/exhaustive-deps- Validate hook dependency arrays.
Overrides
react/prop-types- Off.react/react-in-jsx-scope- Off.
@next/eslint-plugin-next
eslint-plugin-turbo
@vitest/eslint-plugin
eslint-plugin-jest
eslint-plugin-prettier
!IMPORTANT Prettier is not enabled by default in our recommended configs. The official advice by both the Prettier team and the ESLint team is to not integrate Prettier rules into your ESLint config. Formatters should be something you forget about; lots of red squiggly lines in your editor can be distracting as well as less performant.
However, it is expected that users implement Prettier into their workflow at some point. Ideally users integrate Prettier into their editors, or you run Prettier as a file watcher.
Alternatively (or in addition to), you can conditionally enable Prettier during CI to ensure committed code is formatted correctly:
// eslint.config.js
// This is the common CI ennvar, however, adjust to your system
const isCI = process.env.CI;
export default linters.load(
...
// Enable Prettier in CI only
isCI && {
// No files array will lint all files
extends: linters.configs.recommended.prettier,
},
...
};!NOTE Prettier should be enabled as your last config so that it can override any rules it might conflict with.
Rule Comparison
This table details which rules have been added or removed from the last major release (also compatibility with Biome given it looks like a promising upgrade from ESLint).
9 months ago
8 months ago
8 months ago
9 months ago
9 months ago
9 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago