npm.io
0.13.0 • Published 5 months agoCLI

neostandard

Licence
MIT
Version
0.13.0
Deps
9
Size
265 kB
Vulns
0
Weekly
0
Stars
398
neostandard

npm version npm downloads neostandard javascript style

A spiritual successor to the standard javascript style guide

Initial development sponsored by:

platformatic

Table of Contents

Quick Start

Migrate from standard
  1. npm install -D neostandard eslint
  2. (Validate that it runs cleanly by running npx neostandard --help, see #267)
  3. npx neostandard --migrate > eslint.config.js (uses our config helper)
  4. Replace standard with eslint in all places where you run standard, eg. "scripts" and .github/workflows/ (neostandard CLI tracked in #2)
  5. (Add ESLint editor integration, eg. VS Code ESLint extension)
  6. Cleanup:
    • npm uninstall standard
    • Remove unused "standard" top level key from your package.json
    • Deactivate standard specific integrations if you no longer use them (eg. vscode-standard))
Add to new project
  1. npm install -D neostandard eslint

  2. Add an eslint.config.js:

    Using config helper:

    npx neostandard --esm > eslint.config.js

    Or to get CommonJS:

    npx neostandard > eslint.config.js

    Or manually create the file as ESM:

    import neostandard from 'neostandard'
    
    export default neostandard({
      // options
    })

    Or as CommonJS:

    module.exports = require('neostandard')({
      // options
    })
  3. Run neostandard by running ESLint, eg. using npx eslint, npx eslint --fix or 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 module

    import 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 ESLint files

    import 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 ESLint files

    import 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 ESLint languageOptions.globals

    Using 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 details

    import 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 syntax

    import 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 similar

    import 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 as semistandard did)

    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, use filesTs

    import 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
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

  • Investigate a dedicated neostandard runner: #33 / #2

Full list in 1.0.0 milestone

Differences to standard / eslint-config-standard 17.x

Relaxed rules

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.

neostandard javascript style

[![neostandard javascript style](https://img.shields.io/badge/neo-standard-7fffff?style=flat&labelColor=ff80ff)](https://github.com/neostandard/neostandard)

neostandard javascript style

[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-7fffff?style=flat&labelColor=ff80ff)](https://github.com/neostandard/neostandard)

neostandard javascript style

[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-brightgreen?style=flat)](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
  1. neostandard rules describes current best practices in the community and help align developers, contributors and maintainers along those
  2. neostandard rules are not a tool to promote changed practices within the community by prescribing new such practices
  3. neostandard 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
  4. neostandard rule changes and additions should improve the description of project best practices, not prescribe new practices
  5. neostandard 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 neostandard an incomplete baseline config, and the community is split between a few clear alternatives (such as semi), 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:

, 'jQuery'], // Treat $ and jQuery as global variables })

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
    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

    • Investigate a dedicated __INLINE_CODE_70__ runner: #33 / #2

    Full list in 1.0.0 milestone

    Differences to standard / eslint-config-standard 17.x

    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.

    neostandard javascript style

    __CODE_BLOCK_27__

    neostandard javascript style

    __CODE_BLOCK_28__

    neostandard javascript style

    __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
    1. __INLINE_CODE_102__ rules describes current best practices in the community and help align developers, contributors and maintainers along those
    2. __INLINE_CODE_103__ rules are not a tool to promote changed practices within the community by prescribing new such practices
    3. __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
    4. __INLINE_CODE_105__ rule changes and additions should improve the description of project best practices, not prescribe new practices
    5. __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__: