{"id":15043769,"url":"https://github.com/voxpelli/eslint-config","last_synced_at":"2025-04-10T19:04:31.543Z","repository":{"id":37270483,"uuid":"231109259","full_name":"voxpelli/eslint-config","owner":"voxpelli","description":"My personal ESLint config. Based on neostandard","archived":false,"fork":false,"pushed_at":"2025-03-24T09:45:44.000Z","size":1287,"stargazers_count":12,"open_issues_count":37,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-24T16:45:59.091Z","etag":null,"topics":["config","eslint","eslint-config","eslint-shareable-configs","flat-config","neostandard","npm-package","semistandard","standard-js"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voxpelli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["voxpelli"]}},"created_at":"2019-12-31T15:18:53.000Z","updated_at":"2025-02-12T14:43:37.000Z","dependencies_parsed_at":"2024-01-09T00:30:58.493Z","dependency_job_id":"51a13db2-d744-4c65-bdee-ee0ea7d12331","html_url":"https://github.com/voxpelli/eslint-config","commit_stats":{"total_commits":482,"total_committers":4,"mean_commits":120.5,"dds":"0.37136929460580914","last_synced_commit":"638bbad2580bc4246527a6f0d989dc8194547475"},"previous_names":[],"tags_count":77,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Feslint-config","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Feslint-config/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Feslint-config/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpelli%2Feslint-config/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voxpelli","download_url":"https://codeload.github.com/voxpelli/eslint-config/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248279196,"owners_count":21077406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["config","eslint","eslint-config","eslint-shareable-configs","flat-config","neostandard","npm-package","semistandard","standard-js"],"created_at":"2024-09-24T20:49:34.323Z","updated_at":"2025-04-10T19:04:31.515Z","avatar_url":"https://github.com/voxpelli.png","language":"JavaScript","funding_links":["https://github.com/sponsors/voxpelli"],"categories":[],"sub_categories":[],"readme":"# @voxpelli/eslint-config\n\n[![npm version](https://img.shields.io/npm/v/@voxpelli/eslint-config.svg?style=flat)](https://www.npmjs.com/package/@voxpelli/eslint-config)\n[![npm downloads](https://img.shields.io/npm/dm/@voxpelli/eslint-config.svg?style=flat)](https://www.npmjs.com/package/@voxpelli/eslint-config)\n[![neostandard javascript style](https://img.shields.io/badge/code_style-neostandard-7fffff?style=flat\u0026labelColor=ff80ff)](https://github.com/neostandard/neostandard)\n[![Follow @voxpelli@mastodon.social](https://img.shields.io/mastodon/follow/109247025527949675?domain=https%3A%2F%2Fmastodon.social\u0026style=social)](https://mastodon.social/@voxpelli)\n\nMy personal [ESLint](https://eslint.org/) config – a superset of the [neostandard](https://github.com/neostandard/neostandard) base config that I co-created and co-maintain.\n\nThis config contains a couple of more opinionated checks that I find helpful in my projects.\n\n## Install\n\nTo easily install correct peer dependencies, you can use [`install-peerdeps`](https://www.npmjs.com/package/install-peerdeps):\n\n```bash\ninstall-peerdeps --dev @voxpelli/eslint-config\n```\n\n## Usage\n\nAdd an `eslint.config.js` (or `eslint.config.mjs` if your project is CJS) that exports this config:\n\n```js\nexport { default } from '@voxpelli/eslint-config';\n```\n\nIf you need to configure something, instead do:\n\n```js\nimport { voxpelli } from '@voxpelli/eslint-config';\n\nexport default voxpelli({\n  cjs: true,     // Ensures the config has rules fit for a CJS context rather than an ESM context\n  noMocha: true, // By standard this config expects tests to be of the Mocha kind, but one can opt out\n});\n```\n\nYou can also do custom extensions:\n\n```js\nimport { voxpelli } from '@voxpelli/eslint-config';\n\nexport default [\n  ...voxpelli({\n    // Config options\n  }),\n  {\n    // Custom ESLint config\n  },\n];\n```\n\n###\n\n## How does this differ from pure [neostandard](https://github.com/neostandard/neostandard)?\n\n* :stop_sign: = changed to `error` level\n* :warning: = changed to `warn` level\n* :mute: = deactivated\n* :wrench: = changed config\n\n### :wrench: Changed [neostandard](https://github.com/neostandard/neostandard) rules\n\n* :wrench: [`@stylistic/comma-dangle`](https://eslint.org/docs/rules/comma-dangle) – *changed* – set to enforce dangling commas in arrays, objects, imports and exports\n* :wrench: [`no-unused-vars`](https://eslint.org/docs/rules/no-unused-vars) – *changed* – sets `\"args\": \"all\", \"argsIgnorePattern\": \"^_\",` because I personally don't feel limited by [Express error handlers](https://github.com/standard/standard/issues/419#issuecomment-718186130) + wants to stay in sync with TypeScript `noUnusedParameters`\n\n### :heavy_plus_sign: Added ESLint core rules\n\n* :warning: [`func-style`](https://eslint.org/docs/rules/func-style) – disallows function declarations, good to be consistent with how functions are declared\n* :warning: [`no-console`](https://eslint.org/docs/rules/no-console) – warns on existence of `console.log` and similar, as they are mostly used for debugging and should not be committed\n* :stop_sign: [`no-constant-binary-expression`](https://eslint.org/docs/rules/no-constant-binary-expression) – errors when binary expressions are detected to constantly evaluate a specific way\n* :stop_sign: [`no-nonoctal-decimal-escape`](https://eslint.org/docs/rules/no-nonoctal-decimal-escape) – there's no reason not to ban it\n* :stop_sign: [`no-unsafe-optional-chaining`](https://eslint.org/docs/rules/no-unsafe-optional-chaining) – enforces one to be careful with `.?` and not use it in ways that can inadvertently cause errors or `NaN` results\n* :warning: [`no-warning-comments`](https://eslint.org/docs/rules/no-warning-comments) – warns of the existence of `FIXME` comments, as they should always be fixed before pushing\n* :stop_sign: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand) – requires the use of object shorthands for properties, more tidy\n\n### :package: Added ESLint rule packages\n\n* [`plugin:jsdoc/recommended`](https://github.com/gajus/eslint-plugin-jsdoc#rules)\n* [`plugin:mocha/recommended`](https://github.com/lo1tuma/eslint-plugin-mocha#rules)\n* [`plugin:n/recommended`](https://github.com/eslint-community/eslint-plugin-n#-rules)\n* [`plugin:promise/recommended`](https://github.com/eslint-community/eslint-plugin-promise#rules)\n* [`plugin:security/recommended`](https://github.com/eslint-community/eslint-plugin-security#rules)\n* [`plugin:unicorn/recommended`](https://github.com/sindresorhus/eslint-plugin-unicorn#rules)\n\n#### :wrench: Overrides of added ESLint rule packages\n\n* :mute: [`jsdoc/check-types`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/check-types.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :mute: [`jsdoc/no-undefined-types`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/no-undefined-types.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :mute: [`jsdoc/require-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-jsdoc.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :mute: [`jsdoc/require-param-description`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-param-description.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :mute: [`jsdoc/require-property-description`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-property-description.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :mute: [`jsdoc/require-returns-description`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-returns-description.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :mute: [`jsdoc/require-yields`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/require-yields.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n* :wrench: [`jsdoc/tag-lines`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/tag-lines.md) – *changed* – to enforce an empty line between description and tags, but disallow them elsewhere.\n* :mute: [`jsdoc/valid-types`](https://github.com/gajus/eslint-plugin-jsdoc/blob/main/docs/rules/valid-types.md) – *deactivated* – to improve use with [types in js](https://github.com/voxpelli/types-in-js).\n\n* :mute: [`mocha/no-mocha-arrows`](https://github.com/lo1tuma/eslint-plugin-mocha/blob/master/docs/rules/no-mocha-arrows.md) – *deactivated* – while [Mocha discourages arrow functions](https://mochajs.org/#arrow-functions) I find it more readable to use them + I find it safe when combined with type checking as then the type checking will notify one when one tries to do a `this.setTimeout()` or similar in an arrow function where there is no such local context\n\n* :mute: [`n/no-process-exit`](https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-process-exit.md) – *deactivated* – added by `plugin:n/recommended`, but deactivated in favor of [`unicorn/no-process-exit`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/no-process-exit.md)\n\n* :mute: [`security/detect-object-injection`](https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-object-injection.md) – *deactivated* – causes too many false errors\n* :mute: [`security/detect-unsafe-regex`](https://github.com/eslint-community/eslint-plugin-security/blob/main/docs/rules/detect-unsafe-regex.md) – *deactivated* – at least early on wasn't very stable\n\n* :wrench: [`unicorn/catch-error-name`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/catch-error-name.md) – *changed* – I prefer `err` over `error` as I find `error`to be a far too similar name to the built in `Error` class\n* :mute: [`unicorn/explicit-length-check`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/explicit-length-check.md) – *deactivated* – I don't see an issue with `if (string.length)` instead of `if (string.length !== 0)`\n* :warning: [`unicorn/unicorn/no-await-expression-member`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/unicorn/no-await-expression-member.md) – *changed* – eg. useful in chai tests\n* :warning: [`unicorn/unicorn/no-negated-condition`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/unicorn/no-negated-condition.md) – *deactivated* – turned off, there are valid cases for this, so it simply gets noisy\n* :mute: [`unicorn/numeric-separators-style`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/numeric-separators-style.md) – *deactivated* – currently not enough good support for this in engines\n* :warning: [`unicorn/prefer-add-event-listener`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prefer-add-event-listener.md) – *changed* – set to `warn` instead of `error`\n* :warning: [`unicorn/prefer-event-target`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules//prefer-event-target.md) – *changed* – set to `warn` instead of `error`\n* :mute: [`unicorn/prefer-module`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prefer-module.md) – *deactivated*  – only useful when you know you're targetting ESM\n* :warning: [`unicorn/prefer-spread`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prefer-spread.md) – *changed* – set to `warn` instead of `error`\n* :warning: [`unicorn/prefer-string-replace-all`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prefer-string-replace-all.md) – *changed* – set to `warn` instead of `error`\n* :mute: [`unicorn/prevent-abbreviations`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prevent-abbreviations.md) – *deactivated* – same as `unicorn/catch-error-name`, I prefer an abbreviated `err` over a non-abbreviated `error`because the latter is too similar to `Error` for my taste\n* :wrench: [`unicorn/switch-case-braces`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/switch-case-braces.md) – *changed* – I prefer to avoid braces in `case` statements rather than enforcing them\n\n### :heavy_plus_sign: Additional standalone ESLint rules\n\n* :stop_sign: [`@stylistic/quote-props`](https://eslint.style/rules/ts/quote-props) – requires properties to be quoted when needed but otherwise disallows it\n\n* :warning: [`es-x/no-exponential-operators`](https://eslint-community.github.io/eslint-plugin-es-x/rules/no-exponential-operators.html) – disallows the use of the `**` operator, as that's in most cases a mistake and one really meant to write `*`\n\n\u003c!-- * :warning: [`import/no-deprecated`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-deprecated.md) – disallows the use of explicitly deprecated code (code marked with `@deprecated`)\n* :stop_sign: [`import/no-order`](https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-order.md) – enforces a specific ordering of imports --\u003e\n\n* :warning: [`n/prefer-global/console`](https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-global/console.md)\n* :warning: [`n/prefer-promises/fs`](https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/prefer-promises/fs.md)\n* :warning: [`n/no-process-env`](https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-process-env.md)\n* :stop_sign: [`n/no-sync`](https://github.com/eslint-community/eslint-plugin-n/blob/master/docs/rules/no-sync.md)\n\n* :stop_sign: [`promise/prefer-await-to-then`](https://github.com/eslint-community/eslint-plugin-promise/blob/main/docs/rules/prefer-await-to-then.md)\n\n* :stop_sign: [`sort-destructure-keys/sort-destructure-keys`](https://github.com/mthadley/eslint-plugin-sort-destructure-keys)\n\n* :stop_sign: [`unicorn/consistent-destructuring`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/consistent-destructuring.md) – while unicorn dropped it from their recommended config I still like it, see [#283](https://github.com/voxpelli/eslint-config/issues/283)\n\n## ESM specific rules\n\nUnless one configures `cjs: true` these additional rules will be applied:\n\n#### :wrench: Overrides of rules\n\n* :warning: [`func-style`](https://eslint.org/docs/rules/func-style) – enforces function declarations whenever an arrow function isn't used. Better to do `export function foo () {` than `export const foo = function () {`\n* :stop_sign: [`unicorn/prefer-module`](https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/prefer-module.md) – *changed* – restored to its `plugin:unicorn/recommended` value of `error`\n\n## Can I use this in my own project?\n\nYou may want to use [neostandard](https://github.com/neostandard/neostandard) instead, it's the general base config that I help maintain for the community.\n\nI do maintain this project though as if multiple people are using it, so sure, you can use it, but its ultimate purpose is to support my projects.\n\nI do follow  [semantic versioning](https://semver.org/), so the addition or tightening of any checks will trigger major releases whereas minor and patch releases should only ever have relaxation of rules and bug fixes.\n\n## Alternatives\n\n* [`neostandard`](https://github.com/neostandard/neostandard)\n* [`xo`](https://github.com/xojs/xo)\n\n## See also\n\n* [`voxpelli/ghatemplates`](https://github.com/voxpelli/ghatemplates) – the templates I use with [`ghat`](https://github.com/fregante/ghat) to update GitHub Actions in my projects\n* [`voxpelli/renovate-config-voxpelli`](https://github.com/voxpelli/renovate-config-voxpelli) – the shareable [renovate setup](https://docs.renovatebot.com/config-presets/) I use in my projects\n* [`voxpelli/tsconfig`](https://github.com/voxpelli/tsconfig) – the shareable `tsconfig.json` setup I use in my projects\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpelli%2Feslint-config","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoxpelli%2Feslint-config","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpelli%2Feslint-config/lists"}