Library / SDK
sindresorhus/eslint-plugin-unicorn avatar
sindresorhus/eslint-plugin-unicorn

eslint-plugin-unicorn: 300 rules that assume Node 22 and flat config

More than 300 powerful ESLint rules

5,289 stars499 forksJavaScriptMIT

At a glance

What is it?
eslint-plugin-unicorn is an ESLint plugin with more than 300 rules, most aimed at JavaScript and TypeScript, with presets for CSS, HTML, JSON, Markdown, SOML, TOML, and YAML on top. It ships a new major version every week or two, refuses outside pull requests, and puts a floor under your toolchain that has to be checked before anything else.
Who is it for?
Adopt eslint-plugin-unicorn if your project is already on flat config with ESLint 10.4 or later and Node 22 or later, and if you are ready to treat its recommended configuration as a starting point you edit rather than a finished style.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 13, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • sindresorhus/eslint-plugin-unicorn5,289 ★ · +40
Star history
Repository2026-09-232026-11-13
sindresorhus/eslint-plugin-unicorn5.2k5.3k

40 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The install line carries three version floors

Installing the plugin is one command.

sh
npm install --save-dev eslint eslint-plugin-unicorn

Everything difficult about this package is in what that line assumes. package.json declares engines node at >=22 and type as module, so the plugin is ESM only and is not shaped for a CommonJS require chain. The stated requirements add ESLint >=10.4, flat config, and ESM. Together those rule out the older .eslintrc layout, so a codebase that has not migrated cannot adopt this version without rewriting its configuration first, and that migration is the real cost of the install line rather than the install line itself. Two smaller details from the same manifest matter for bundlers and editors: exports points types at ./index.d.ts and default at ./index.js, so TypeScript has a declared entry point, and sideEffects is false, which lets a bundler drop the whole plugin when no rule from it runs. The package is MIT licensed, authored by Sindre Sorhus, and takes funding through a sponsor link recorded in its funding field. The repository layout follows the same split: index.js and index.d.ts are the entry points named in exports, configs/ holds the preset configurations, rules/ holds the individual rule implementations, docs/ holds one page per rule, scripts/ holds the creation and renaming helpers, and test/ holds the suites.

Six file types need a language plugin you supply

Most rules target JavaScript and TypeScript. The plugin also reaches past code: CSS, HTML, JSON, Markdown, SOML, TOML, and YAML are covered when the matching ESLint language plugin is in use, and each of those has its own configuration, named recommended-css, recommended-html, recommended-json, recommended-markdown, recommended-soml, recommended-toml, and recommended-yaml, sitting alongside recommended for JavaScript and unopinionated. The catch is that a configuration cannot parse a file on its own. A language plugin has to hand ESLint a syntax tree before any rule can inspect it, and the install command above pulls in eslint and this plugin and nothing else, so no parser arrives with it. Turning on recommended-markdown in a project without a Markdown language plugin therefore leaves you with a configuration and no files for it to act on. The marker columns in the rule table make the same point from the rule side: a rule only appears against recommended-toml if that configuration genuinely applies to the files your parser delivers.

The rule table is generated, and adding a rule is three commands

The list of rules in the readme is not maintained by hand, and the file says so above the table: do not modify it manually, run npm run fix:eslint-docs instead. The tool doing the work is eslint-doc-generator, configured through .eslint-doc-generatorrc.js at the repository root. Adding and renaming are both scripted in package.json, and both finish the same way, with an index rebuild and then the documentation fix.

sh
npm run create-rule
npm run rename-rule
npm run create-rules-index-file
npm run fix:eslint-docs

Contributing to this repository is a narrow door: the readme states that pull requests are not accepted because of too much AI slop, and anyone with a rule idea is pointed at .github/contributing.md instead. The consequence for a reader is that the table is the source of truth about which rules exist and how each one behaves, and a rule name mentioned in an issue or a blog post may take a release to appear there, because the row is only written when the generator runs.

Fixable from the CLI and fixable in the editor are different rules

Three markers separate what a rule can do to your code, and the difference decides whether a CI run is enough. A rule marked as automatically fixable by the --fix CLI option rewrites itself with no human in the loop. A rule marked as manually fixable by editor suggestions changes only when someone accepts the suggestion in an editor, so a file processed by the command line keeps that pattern. A rule that requires type information cannot reach a verdict without the type checker behind it, which is a heavier dependency than the other two. The visible rows show the first two cases. better-dom-traversing sits in recommended and unopinionated but is suggestion-only, so --fix leaves it alone. catch-error-name and consistent-assert are in recommended and are CLI fixable. class-reference-in-static-methods and consistent-class-member-order are recommended but suggestion-only. comment-content and consistent-arrow-return-style are CLI fixable without being in recommended at all.

A preset, or the same languageOptions written by hand

You can start from a preset configuration or wire up every rule yourself in eslint.config.js. Take the second route and the readme is explicit that you have to supply the same languageOptions the preset would have set.

js
import unicorn from 'eslint-plugin-unicorn';
import {defineConfig} from 'eslint/config';
import globals from 'globals';

export default defineConfig([
	{
		files: ['**/*.js'],
		languageOptions: {
			globals: globals.builtin,
		},
		plugins: {
			unicorn,
		},
		rules: {
			'unicorn/prefer-module': 'error',
			'unicorn/…': 'error',
		},
	},
	// …
]);

TypeScript needs the same block with two changes: scope it to files matching **/*.ts and set parser to typescriptEslintParser, imported from @typescript-eslint/parser, inside the same languageOptions object that holds the globals. Two consequences follow. The plugin does not detect file types, so a block scoped to **/*.js never runs against TypeScript files, and the scoping is entirely your problem. And every rule has to be named in full with the unicorn/ prefix, which is what the placeholder line in that example stands for. If writing that config is the part you would rather skip, XO includes this plugin.

The repository runs its own rules on its own source

There is a second config file beside the ordinary one, eslint.dogfooding.config.js, and a script named run-rules-on-codebase whose command begins with eslint --config, pointing at a config other than the default. The tests use the Node test runner instead of a framework: the coverage script runs node --test with experimental test coverage over index.js, configs, and rules while excluding test, fix:snapshots reruns the same suites with snapshot updating, and integration runs test/integration/test.js.

sh
npm run coverage
npm run integration
npm run lint:js
npm run lint:markdown
npm run lint:package-json

Linting fans out instead of being one command. The lint script runs every lint:* entry through run-p with --continue-on-error, covering eslint for JavaScript, markdownlint across Markdown files, eslint against package.json files, a check on the generated non-JavaScript language list, and a check that the generated documentation is current. The fix scripts mirror the same fan out. Two files at the root, AGENTS.md and CLAUDE.md, exist to tell coding agents what to do in a repository that does not take outside patches.

Editorial conclusion

Adopt eslint-plugin-unicorn if your project is already on flat config with ESLint 10.4 or later and Node 22 or later, and if you are ready to treat its recommended configuration as a starting point you edit rather than a finished style. Hold off if your build still uses the legacy config format, if you cannot add a language plugin for every non-JavaScript file type you want covered, or if you need fixes to land from a CI run, since several rules only change code through an editor suggestion. Before installing, check the release you are pinning against your ESLint version, and read the generated rule table rather than a blog post, because it is the only place the preset and fixability markers are maintained.

Frequently asked questions

What is eslint-plugin-unicorn and how many rules does it hold?

It is an ESLint plugin holding more than 300 rules. Most of them target JavaScript and TypeScript, and some also lint CSS, HTML, JSON, Markdown, SOML, TOML, and YAML when the matching ESLint language plugin is in use. It requires ESLint >=10.4, flat config, ESM, and Node >=22.

Is ESLint obsolete, and does eslint-plugin-unicorn still ship?

The project's own signals point the other way. eslint-plugin-unicorn is at version 79.0.0, published on 2026-10-23, with v78.0.0 on 2026-10-12 and v77.0.0 on 2026-10-03, and the last push to the repository is dated 2026-10-31. It requires ESLint >=10.4 and flat config, so it targets current ESLint rather than the old config format.

Is eslint-plugin-unicorn an argument for ESLint over Biome?

The project makes no comparison with Biome, so nothing here weighs the two linters. What it states about its own requirements: ESLint >=10.4, flat config, ESM, and Node >=22, plus a matching ESLint language plugin for each non-JavaScript file type it lints, and type information for the rules that require it.

What are the best ESLint plugins, including eslint-plugin-unicorn?

eslint-plugin-unicorn does not rank plugins or compare itself to others. It states that it holds more than 300 rules, that most target JavaScript and TypeScript, and it points readers who want a bundled setup to XO, which includes this plugin. Rule by rule choices are made through its own preset configurations.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sindresorhus/eslint-plugin-unicorn on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sindresorhus-eslint-plugin-unicorn.svg)](https://hysenlabs.com/projects/sindresorhus-eslint-plugin-unicorn)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/sindresorhus-eslint-plugin-unicorn.svg)](https://hysenlabs.com/projects/sindresorhus-eslint-plugin-unicorn)

Was this useful?