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

eslint-plugin-unicorn: 300+ opinionated ESLint rules for JS and TS

More than 300 powerful ESLint rules

5,256 stars496 forksJavaScriptMIT

At a glance

What is it?
A flat-config-only rule pack from Sindre Sorhus that pushes a single house style across JavaScript, TypeScript and non-JavaScript files. It is powerful, opinionated, and hard to adopt halfway.
Who is it for?
Adopt eslint-plugin-unicorn if your project is already ESM, on ESLint 10.4 or newer with flat config, and you accept a house style that will rewrite a lot of existing code. Do not adopt it if you are pinned to eslintrc, CommonJS, or an ESLint version below 10.4, because the README states those are unsupported.
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 last received commits 3 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

The problem: ESLint core stops at correctness, not style

ESLint core rules catch bugs and enforce a few conventions. They do not tell you whether to name a caught error `error` or `err`, whether booleans should start with `is`, or whether a class member should appear before another. Teams fill that gap with internal style guides, review comments, or a hand-rolled config that drifts.

eslint-plugin-unicorn is a rule pack aimed at exactly that layer. The README describes it as "More than 300 powerful ESLint rules", and the rules list in the README covers naming, assertion style, class member order, DOM traversal APIs, compound word spelling, and conditional object spread. It is for teams that want one published opinion instead of a private one, and for maintainers of libraries who want their published code to look consistent across contributors.

The audience is narrower than the rule count suggests. The README states the plugin requires ESLint `>=10.4`, flat config and ESM. That rules out projects still on `.eslintrc` files or CommonJS output, and it means the plugin is not a drop-in for older toolchains. The README also points at XO, which bundles this plugin, for people who would rather not assemble the config themselves.

How the plugin is wired: one plugin object, presets, and per-rule opt-in

The mechanism is the standard ESLint plugin shape. The package exports a plugin object, and you register it under a namespace in a flat config object. From there you either enable rules one by one with the `unicorn/` prefix or spread a preset.

The README documents two presets, `recommended` and `unopinionated`, and the rules table uses two markers for them: a check mark for rules set in `recommended` and a checkbox for rules set in `unopinionated`. Some rules carry both, which means they are on in either preset. That distinction matters when you are deciding how aggressive to be: `unopinionated` is the smaller set, so it is the safer starting point if you want to avoid a large first-run diff.

The rules table also marks three other things. A wrench means the rule is automatically fixable with ESLint's `--fix`. A lightbulb means it offers editor suggestions rather than automatic fixes, so a human has to accept each one. A speech balloon means the rule requires type information, which in practice means a typed linting setup. Those markers are the practical map of adoption cost: the fixable rules are cheap, the suggestion-only and type-aware rules are not.

The README notes that most rules target JavaScript and TypeScript, but that some also lint CSS, HTML, JSON, Markdown, TOML and YAML when used with the matching ESLint language plugin. So the plugin is not purely a JS concern, though the JS and TS rules are the bulk of it.

Installing eslint-plugin-unicorn and running a first real check

The README gives a single install command. It pulls in ESLint alongside the plugin, so both land in devDependencies.

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

Before you write any config, confirm your environment. The README states ESLint `>=10.4`, flat config, and ESM are required, and `package.json` sets `"engines": {"node": ">=22"}`. If any of those do not hold, stop here rather than debugging confusing parser errors later.

The README's first usage example registers the plugin and turns on one rule by name. Note that it also sets `languageOptions.globals` from the `globals` package, and the README says to set the same `languageOptions` if you do not use a preset.

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',
		},
	},
]);

Run `npx eslint .` after saving that file. With only `unicorn/prefer-module` enabled you should see findings only for that rule, which is the point: it proves the plugin loaded before you turn on a preset.

For TypeScript, the README scopes Unicorn to TypeScript files and configures a TypeScript parser on the same config object, rather than applying the plugin globally.

js
import typescriptEslintParser from '@typescript-eslint/parser';
import unicorn from 'eslint-plugin-unicorn';
import {defineConfig} from 'eslint/config';
import globals from 'globals';

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

Once that works, switch to a preset instead of listing rules. The README documents `recommended` and `unopinionated` as the two configurations; which one you pick determines how many rules fire on the first run. The README does not document a rollback path or a migration helper for turning a preset off again, so treat the first preset run as a measurement step, not a commit.

Where eslint-plugin-unicorn fights your codebase

The main limitation is the platform floor. ESLint `>=10.4`, flat config and ESM are hard requirements in the README, and Node `>=22` is set in `package.json`. A repository on eslintrc, or one that emits CommonJS, cannot use this plugin without a migration that has nothing to do with the plugin itself. That is a real cost, and the README does not offer an alternative entry point for older setups.

The second limitation is the volume of opinion. More than 300 rules means a preset can produce a large first-run diff, and the rules table shows that only some of them are auto-fixable. Rules marked with a lightbulb are suggestion-only, so they cannot be cleared with `--fix`; someone has to review each one in an editor. Rules marked as requiring type information need typed linting configured before they will run at all. If you enable a preset wholesale and then find a rule you disagree with, you are now maintaining a disable list, which is the opposite of the plugin's purpose.

The third is governance. The README states plainly: "We do not accept pull requests because of too much AI slop." That is a deliberate trade-off. You get a coherent, single-author direction and no committee drift; you also cannot send a patch for a rule that misfires on your code. The README directs new rule ideas to a contributing document rather than to pull requests, and the repository carries both `AGENTS.md` and `CLAUDE.md` at the top level.

Finally, this is not a security or correctness linter. It does not replace a plugin aimed at vulnerabilities. If your goal is finding injection flaws, this is the wrong tool.

eslint-plugin-unicorn against Biome, sonarjs and the typescript-eslint plugin

Biome is the most different alternative. It is a separate linter and formatter rather than a plugin, so it does not run inside ESLint and does not consume ESLint rules. Adopting Biome means replacing the runner, not extending it. eslint-plugin-unicorn assumes ESLint is already your runner and adds rules to it, which is why the README can demand a specific ESLint version and flat config.

eslint-plugin-sonarjs is a closer comparison in shape: also an ESLint plugin, also a rule pack. The difference is intent. Sonar's ruleset comes out of static analysis for code quality and defect patterns. Unicorn's rules, judging by the rule names in the README, are about style and idiom: naming, assertion consistency, class member order, DOM traversal APIs. They overlap in mechanics, not in what they police.

typescript-eslint/eslint-plugin is the one you will almost certainly run alongside this one, not instead of it. It supplies the parser and the type-aware rule infrastructure; Unicorn's type-information rules depend on that kind of setup being present. The two are complements, and the README's TypeScript example shows the parser being configured in the same config object as the plugin.

eslint-plugin-n and eslint-plugin-import-x cover Node API usage and module import resolution respectively. Those are narrower problem domains. If you only need import ordering, Unicorn is far more than you asked for.

Maintenance, releases and what the MIT licence leaves you

The repository is not archived, and the last push was on 2026-09-22. Recent releases are frequent and versioned as major bumps: v74.0.0 on 2026-08-28, v75.0.0 on 2026-09-16, and v76.0.0 on 2026-09-19. For a consumer, that cadence is the upgrade cost. Major versions mean rule behaviour or preset membership can change between them, and the README does not describe a deprecation policy for rules that are removed or moved between presets.

A changelog exists, since people search for one, but its contents are not reproduced here. Read it before each major bump rather than after.

The licence is MIT, declared in `package.json` and present as a `license` file at the repository root. MIT is permissive: you can use the plugin in commercial and closed-source projects, and you can modify it. It does not grant trademark rights, and it comes with no warranty. Nothing here is legal advice; if your organisation has a policy on third-party licence review, run it through that process.

One practical maintenance note: the README's rules list carries the comment "Do not manually modify this list. Run: `npm run fix:eslint-docs`". That is an instruction for contributors to the plugin, not for consumers, but it tells you the rules list is generated and therefore stays in sync with the code.

Editorial conclusion

Adopt eslint-plugin-unicorn if your project is already ESM, on ESLint 10.4 or newer with flat config, and you accept a house style that will rewrite a lot of existing code. Do not adopt it if you are pinned to eslintrc, CommonJS, or an ESLint version below 10.4, because the README states those are unsupported. Before turning on the recommended preset across a large repository, run it on one directory and check how many findings are auto-fixable versus only suggestion-level, then read the docs/rules page for each rule you keep.

Frequently asked questions

What is eslint-plugin-unicorn?

It is an ESLint plugin that provides more than 300 rules, mostly for JavaScript and TypeScript, with some rules covering CSS, HTML, JSON, Markdown, TOML and YAML when used with the matching ESLint language plugin. It ships recommended and unopinionated preset configurations.

What does the eslint-plugin-unicorn plugin do?

It registers a set of ESLint rules under the unicorn namespace that enforce naming, assertion style, class member order, DOM traversal APIs and similar conventions. You enable them individually or through the recommended or unopinionated preset.

Is ESLint obsolete?

That question is about ESLint itself, and the README does not address it. What the README does show is that eslint-plugin-unicorn requires ESLint 10.4 or newer, flat config and ESM.

Which linter is better, ESLint or Biome?

The README does not compare them. It does show that eslint-plugin-unicorn is an ESLint plugin and therefore assumes ESLint as the runner, while Biome is a separate linter rather than a plugin that extends ESLint.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. sindresorhus/eslint-plugin-unicorn on GitHub
For maintainers

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)
Community notes

Community notes