Table of Contents
- Quick Start
- Configuration options
- Extending
- Additional exports
- Missing for 1.0.0 release
- Differences to standard / eslint-config-standard 17.x
- Config helper
- Readme badges
- Mission statement
- Governance
- Used by
Quick Start
Migrate from standard
npm install -D neostandard eslint- (Validate that it runs cleanly by running
npx neostandard --help, see #267) npx neostandard --migrate > eslint.config.js(uses our config helper)- Replace
standardwitheslintin all places where you runstandard, eg."scripts"and.github/workflows/(neostandardCLI tracked in #2) - (Add ESLint editor integration, eg. VS Code ESLint extension)
- Cleanup:
npm uninstall standard- Remove unused
"standard"top level key from yourpackage.json - Deactivate
standardspecific integrations if you no longer use them (eg. vscode-standard))
Add to new project
npm install -D neostandard eslintAdd an
eslint.config.js:Using config helper:
npx neostandard --esm > eslint.config.jsOr to get CommonJS:
npx neostandard > eslint.config.jsOr manually create the file as ESM:
import neostandard from 'neostandard' export default neostandard({ // options })Or as CommonJS:
module.exports = require('neostandard')({ // options })Run
neostandardby running ESLint, eg. usingnpx eslint,npx eslint --fixor similar
Configuration options
All examples below use ESM (ECMAScript Modules) syntax. If you're using CommonJS (CJS), replace the import/export statements with the following:
// Replace
import neostandard from 'neostandard'
export default neostandard({ /* options */ })
// With
const neostandard = require('neostandard')
module.exports = neostandard({ /* options */ })
Here's a basic example of how to configure neostandard:
import neostandard from 'neostandard'
export default neostandard({
ts: true, // an option
// Add other options here
})
The options below allow you to customize neostandard for your project. Use them to add global variables, ignore files, enable TypeScript support, and more.
env-string[]- adds additional globals by importing them from the globals npm moduleimport neostandard from 'neostandard' export default neostandard({ env: ['browser', 'mocha'], // Add browser and mocha global variables })files-string[]- additional file patterns to match. Uses the same shape as ESLintfilesimport neostandard from 'neostandard' export default neostandard({ files: ['src/**/*.js', 'tests/**/*.js'], // Lint only files in src/ and tests/ directories })filesTs-string[]- additional file patterns for the TypeScript configs to match. Uses the same shape as ESLintfilesimport neostandard from 'neostandard' export default neostandard({ ts: true, // Enable TypeScript support filesTs: ['src/**/*.ts', 'tests/**/*.ts'], // Lint only TypeScript files in src/ and tests/ directories })globals-string[] | object- an array of names of globals or an object of the same shape as ESLintlanguageOptions.globalsUsing an array:
import neostandard from 'neostandard' export default neostandard({ globals: ['Using an object:
import neostandard from 'neostandard' export default neostandard({ globals: { $: 'readonly', // $ is a read-only global jQuery: 'writable', // jQuery can be modified localStorage: 'off', // Disable the localStorage global }, })ignores-string[]- an array of glob patterns for files that the config should not apply to, see ESLint documentation for detailsimport neostandard from 'neostandard' export default neostandard({ ignores: ['dist/**/*', 'tests/**'], // Ignore files in dist/ and tests/ directories })noJsx-boolean- if set, no jsx rules will be added. Useful if for some reason its clashing with your use of JSX-style syntaximport neostandard from 'neostandard' export default neostandard({ noJsx: true, // Disable JSX-specific rules })noStyle-boolean- if set, no style rules will be added. Especially useful when combined with Prettier, dprint or similarimport neostandard from 'neostandard' export default neostandard({ noStyle: true, // Disable style-related rules (useful with Prettier or dprint) })semi-boolean- if set, enforce rather than forbid semicolons (same assemistandarddid)import neostandard from 'neostandard' export default neostandard({ semi: true, // Enforce semicolons (like semistandard) })ts-boolean- if set, TypeScript syntax will be supported and*.ts(including*.d.ts) will be checked. To add additional file patterns to the TypeScript checks, usefilesTsimport neostandard from 'neostandard' export default neostandard({ ts: true, // Enable TypeScript support and lint .ts files })
Extending
The neostandard() function returns an ESLint config array which is intended to be exported directly or, if you want to modify or extend the config, can be combined with other configs like any other ESLint config array:
import neostandard from 'neostandard'
import jsdoc from 'eslint-plugin-jsdoc';
export default [
...neostandard(),
jsdoc.configs['flat/recommended-typescript-flavor'],
]
Do note that neostandard() is intended to be a complete linting config in itself, only extend it if you have needs that goes beyond what neostandard provides, and open an issue if you believe neostandard itself should be extended or changed in that direction.
It's recommended to stay compatible with the plain config when extending and only make your config stricter, not relax any of the rules, as your project would then still pass when using just the plain neostandard-config, which helps people know what baseline to expect from your project.
Adding back import checking
As of neostandard v1.0.0, eslint-plugin-import-x has been removed to reduce dependency weight and installation complexity. For most projects, TypeScript's compiler (tsc) provides superior import/export checking with full project context.
If you still need ESLint-based import checking, you can add it back manually:
import neostandard from 'neostandard'
import importX from 'eslint-plugin-import-x'
export default [
...neostandard(),
{
plugins: {
'import-x': importX
},
rules: {
'import-x/export': 'error',
'import-x/first': 'error',
'import-x/no-absolute-path': ['error', { esmodule: true, commonjs: true, amd: false }],
'import-x/no-duplicates': 'error',
'import-x/no-named-default': 'error',
'import-x/no-webpack-loader-syntax': 'error',
}
}
]
For TypeScript projects, you may also want to add the TypeScript resolver:
import neostandard from 'neostandard'
import importX from 'eslint-plugin-import-x'
import { createTypeScriptImportResolver } from 'eslint-import-resolver-typescript'
export default [
...neostandard(),
{
plugins: {
'import-x': importX
},
settings: {
'import-x/resolver-next': [
createTypeScriptImportResolver({
project: './tsconfig.json'
})
]
},
rules: {
'import-x/export': 'error',
'import-x/first': 'error',
'import-x/no-absolute-path': ['error', { esmodule: true, commonjs: true, amd: false }],
'import-x/no-duplicates': 'error',
'import-x/no-named-default': 'error',
'import-x/no-webpack-loader-syntax': 'error',
}
}
]
Recommended alternative: Use TypeScript's compiler for import checking instead:
tsc --noEmit
This provides more comprehensive checking including type imports, module resolution, and cross-file validation.
Additional exports
resolveIgnoresFromGitignore()
Finds a .gitignore file that resides in the same directory as the ESLint config file and returns an array of ESLint ignores that matches the same files.
ESM:
import neostandard, { resolveIgnoresFromGitignore } from 'neostandard'
export default neostandard({
ignores: resolveIgnoresFromGitignore(),
})
CommonJS:
module.exports = require('neostandard')({
ignores: require('neostandard').resolveIgnoresFromGitignore(),
})
Exported plugins
neostandard exports all the ESLint plugins that it uses. This to ensure that users who need to reference the plugin themselves will use the exact same instance of the plugin, which is a necessity when a plugin prefix is defined in multiple places.
List of exported plugins
@stylistic- export of@stylistic/eslint-pluginn- export ofeslint-plugin-npromise- export ofeslint-plugin-promisereact- export ofeslint-plugin-reacttypescript-eslint- export oftypescript-eslint
Usage of exported plugin
If one eg. wants to add the eslint-plugin-n recommended config, then one can do:
import neostandard, { plugins } from 'neostandard'
export default [
...neostandard(),
plugins.n.configs['flat/recommended'],
]
Missing for 1.0.0 release
Full list in 1.0.0 milestone
Differences to standard / eslint-config-standard 17.x
- Open governance, resolving governance issue
- Built for ESLint 9
- Relies on ESLint flat config to bundle plugins rather than custom
standard-engine - Replaces deprecated ESLint style rules with
eslint-stylisticrules - Defaults to the
standardbehaviour of bundling JSX-support (ported fromeslint-config-standard-jsx) with anoJsxoption that deactivates it to matcheslint-config-standard - Built in options replaces need for separate modules
tsoption makes*.tsfiles be checked as well (used to be handled byts-standard)semioption enforces rather than ban semicolons (used to be handled bysemistandard)noStyleoption deactivates style rules (used to require something likeeslint-config-prettier)
Relaxed rules
@stylistic/comma-dangle– changed – set to ignore dangling commas in arrays, objects, imports, exports and is it set towarnrather thanerror@stylistic/no-multi-spaces– changed – setsignoreEOLCommentstotrue, useful for aligning comments across multiple linedot-notation– deactivated – clashes with thenoPropertyAccessFromIndexSignaturecheck in TypeScriptn/no-deprecated-api– changed – changed towarninstead oferroras they are not urgent to fix
Config helper
You can use the provided CLI tool to generate a config for you:
neostandard --semi --ts > eslint.config.js
To see all available flags, run:
neostandard --help
Config migration
The CLI tool can also migrate an existing "standard" configuration from package.json:
neostandard --migrate > eslint.config.js
Migrations can also be extended, so to eg. migrate a semistandard setup, do:
neostandard --semi --migrate > eslint.config.js
Readme badges
Yes! If you use neostandard in your project, you can include one of these badges in
your readme to let people know that your code is using the neostandard style.
[](https://github.com/neostandard/neostandard)
[](https://github.com/neostandard/neostandard)
[](https://github.com/neostandard/neostandard)
Mission statement
Prior to the 1.0.0 release we are still rapidly evolving with fixes and improvements to reach rule parity with standard, hence more breaking changes will be experienced until then, as well as evolution of this statement
neostandard intends to set an expectable baseline for project linting that's descriptive of best practices rather than prescriptive of any opinionated approach.
Rule guidelines
neostandardrules describes current best practices in the community and help align developers, contributors and maintainers along thoseneostandardrules are not a tool to promote changed practices within the community by prescribing new such practicesneostandardrule changes and additions should be aligned with projects prior to being released, by eg. sending PR:s to them to align them ahead of time. When new best practices are incompatible with current best practices, rules should first be relaxed to allow for both approaches, then be made stricter when the community has moved to the new approachneostandardrule changes and additions should improve the description of project best practices, not prescribe new practicesneostandardshould, when faced with no clear best practice, avoid adding such a rule as it risks becoming prescriptive rather than descriptive. If leaving out such a rule would makeneostandardan incomplete baseline config, and the community is split between a few clear alternatives (such assemi), then making it configurable can enable it to still be added, but that should only be done in exceptional cases
Governance
neostandard is a community project with open governance.
See GOVERNANCE.md for specifics.
Used by
A subset of some of the projects that rely on neostandard:
bcomnes/npm-run-all2(https://github.com/bcomnes/npm-run-all2/pull/142)fastify/fastify(https://github.com/fastify/fastify/pull/5509)nodejs/undici(https://github.com/nodejs/undici/pull/3485)poolifier/poolifieruuidjs/uuid(https://github.com/uuidjs/uuid/pull/752)
Using an object:
__CODE_BLOCK_10____INLINE_CODE_36__ - __INLINE_CODE_37__ - an array of glob patterns for files that the config should not apply to, see ESLint documentation for details
__CODE_BLOCK_11____INLINE_CODE_38__ - __INLINE_CODE_39__ - if set, no jsx rules will be added. Useful if for some reason its clashing with your use of JSX-style syntax
__CODE_BLOCK_12____INLINE_CODE_40__ - __INLINE_CODE_41__ - if set, no style rules will be added. Especially useful when combined with Prettier, dprint or similar
__CODE_BLOCK_13____INLINE_CODE_42__ - __INLINE_CODE_43__ - if set, enforce rather than forbid semicolons (same as __INLINE_CODE_44__ did)
__CODE_BLOCK_14____INLINE_CODE_45__ - __INLINE_CODE_46__ - if set, TypeScript syntax will be supported and __INLINE_CODE_47__ (including __INLINE_CODE_48__) will be checked. To add additional file patterns to the TypeScript checks, use __INLINE_CODE_49__
__CODE_BLOCK_15__Extending
The __INLINE_CODE_50__ function returns an ESLint config array which is intended to be exported directly or, if you want to modify or extend the config, can be combined with other configs like any other ESLint config array:
__CODE_BLOCK_16__Do note that __INLINE_CODE_51__ is intended to be a complete linting config in itself, only extend it if you have needs that goes beyond what __INLINE_CODE_52__ provides, and open an issue if you believe __INLINE_CODE_53__ itself should be extended or changed in that direction.
It's recommended to stay compatible with the plain config when extending and only make your config stricter, not relax any of the rules, as your project would then still pass when using just the plain __INLINE_CODE_54__-config, which helps people know what baseline to expect from your project.
Adding back import checking
As of neostandard v1.0.0, __INLINE_CODE_55__ has been removed to reduce dependency weight and installation complexity. For most projects, TypeScript's compiler (__INLINE_CODE_56__) provides superior import/export checking with full project context.
If you still need ESLint-based import checking, you can add it back manually:
__CODE_BLOCK_17__For TypeScript projects, you may also want to add the TypeScript resolver:
__CODE_BLOCK_18__Recommended alternative: Use TypeScript's compiler for import checking instead:
__CODE_BLOCK_19__This provides more comprehensive checking including type imports, module resolution, and cross-file validation.
Additional exports
resolveIgnoresFromGitignore()
Finds a __INLINE_CODE_57__ file that resides in the same directory as the ESLint config file and returns an array of ESLint ignores that matches the same files.
ESM:
__CODE_BLOCK_20__CommonJS:
__CODE_BLOCK_21__Exported plugins
__INLINE_CODE_58__ exports all the ESLint plugins that it uses. This to ensure that users who need to reference the plugin themselves will use the exact same instance of the plugin, which is a necessity when a plugin prefix is defined in multiple places.
List of exported plugins
- __INLINE_CODE_59__ - export of __INLINE_CODE_60__
- __INLINE_CODE_61__ - export of __INLINE_CODE_62__
- __INLINE_CODE_63__ - export of __INLINE_CODE_64__
- __INLINE_CODE_65__ - export of __INLINE_CODE_66__
- __INLINE_CODE_67__ - export of __INLINE_CODE_68__
Usage of exported plugin
If one eg. wants to add the __INLINE_CODE_69__ recommended config, then one can do:
__CODE_BLOCK_22__Missing for 1.0.0 release
Full list in 1.0.0 milestone
Differences to standard / eslint-config-standard 17.x
- Open governance, resolving governance issue
- Built for ESLint 9
- Relies on ESLint flat config to bundle plugins rather than custom __INLINE_CODE_71__
- Replaces deprecated ESLint style rules with __INLINE_CODE_72__ rules
- Defaults to the __INLINE_CODE_73__ behaviour of bundling JSX-support (ported from __INLINE_CODE_74__) with a __INLINE_CODE_75__ option that deactivates it to match __INLINE_CODE_76__
- Built in options replaces need for separate modules
- __INLINE_CODE_77__ option makes __INLINE_CODE_78__ files be checked as well (used to be handled by __INLINE_CODE_79__)
- __INLINE_CODE_80__ option enforces rather than ban semicolons (used to be handled by __INLINE_CODE_81__)
- __INLINE_CODE_82__ option deactivates style rules (used to require something like __INLINE_CODE_83__)
Relaxed rules
- __INLINE_CODE_84__ – changed – set to ignore dangling commas in arrays, objects, imports, exports and is it set to __INLINE_CODE_85__ rather than __INLINE_CODE_86__
- __INLINE_CODE_87__ – changed – sets __INLINE_CODE_88__ to __INLINE_CODE_89__, useful for aligning comments across multiple line
- __INLINE_CODE_90__ – deactivated – clashes with the __INLINE_CODE_91__ check in TypeScript
- __INLINE_CODE_92__ – changed – changed to __INLINE_CODE_93__ instead of __INLINE_CODE_94__ as they are not urgent to fix
Config helper
You can use the provided CLI tool to generate a config for you:
__CODE_BLOCK_23__To see all available flags, run:
__CODE_BLOCK_24__Config migration
The CLI tool can also migrate an existing __INLINE_CODE_95__ configuration from __INLINE_CODE_96__:
__CODE_BLOCK_25__Migrations can also be extended, so to eg. migrate a __INLINE_CODE_97__ setup, do:
__CODE_BLOCK_26__Readme badges
Yes! If you use __INLINE_CODE_98__ in your project, you can include one of these badges in your readme to let people know that your code is using the neostandard style.
__CODE_BLOCK_27__ __CODE_BLOCK_28__ __CODE_BLOCK_29__Mission statement
Prior to the __INLINE_CODE_99__ release we are still rapidly evolving with fixes and improvements to reach rule parity with __INLINE_CODE_100__, hence more breaking changes will be experienced until then, as well as evolution of this statement
__INLINE_CODE_101__ intends to set an expectable baseline for project linting that's descriptive of best practices rather than prescriptive of any opinionated approach.
Rule guidelines
- __INLINE_CODE_102__ rules describes current best practices in the community and help align developers, contributors and maintainers along those
- __INLINE_CODE_103__ rules are not a tool to promote changed practices within the community by prescribing new such practices
- __INLINE_CODE_104__ rule changes and additions should be aligned with projects prior to being released, by eg. sending PR:s to them to align them ahead of time. When new best practices are incompatible with current best practices, rules should first be relaxed to allow for both approaches, then be made stricter when the community has moved to the new approach
- __INLINE_CODE_105__ rule changes and additions should improve the description of project best practices, not prescribe new practices
- __INLINE_CODE_106__ should, when faced with no clear best practice, avoid adding such a rule as it risks becoming prescriptive rather than descriptive. If leaving out such a rule would make __INLINE_CODE_107__ an incomplete baseline config, and the community is split between a few clear alternatives (such as __INLINE_CODE_108__), then making it configurable can enable it to still be added, but that should only be done in exceptional cases
Governance
__INLINE_CODE_109__ is a community project with open governance.
See GOVERNANCE.md for specifics.
Used by
A subset of some of the projects that rely on __INLINE_CODE_110__: