Verbesserung der JavaScript-Codequalität mit eslint-plugin-unicorn
eslint-plugin-unicorn für ESLint 10: Installation mit Flat Config, Presets recommended oder unopinionated und autofixierbare Regeln für bessere JS- und TS-Qualität.
eslint-plugin-unicorn ist ein umfangreiches, meinungsstarkes ESLint-Plugin mit über 300 Regeln, das moderne JavaScript- und TypeScript-Idiome fördert, subtile Qualitätsfehler aufdeckt und dessen Regeln größtenteils automatisch korrigierbar sind. Es setzt ESLint >=10.4, Flat Config und ESM voraus, was bedeutet, dass das alte .eslintrc-Setup mit extends: 'plugin:unicorn/recommended' nicht mehr anwendbar ist. Wer ESLint bereits mit einer einfachen Konfiguration betreibt und die Codequalität verbessern möchte, ohne eigene Regeln schreiben zu müssen, findet in diesem Plugin den schnellsten Weg dorthin.
Der Haken dabei: „Meinungsstark” ist ein zweischneidiges Schwert. Einige Regeln verhindern versehentlich quadratische Schleifen und echte Korrektheitsfehler; andere erzwingen stilistische Präferenzen, die in einer gewachsenen Codebasis zu Reibungspunkten führen. Dieser Leitfaden trennt beides voneinander: was das Plugin durchsetzt, welche Regeln ihren Aufwand rechtfertigen, welche herabgestuft oder deaktiviert werden sollten – und eine direkt verwendbare eslint.config.mjs, die mit den aktuellen Werkzeugen funktioniert.
Wichtigste Erkenntnisse
- eslint-plugin-unicorn liefert über 300 größtenteils automatisch korrigierbare Regeln und setzt ab v69 (Juni 2026) ESLint ≥10.4, Flat Config und ESM voraus —
.eslintrcfunktioniert nicht mehr, da ESLint 10 es vollständig entfernt hat. - Der schnellste Einstieg:
unicorn/recommendederweitern,eslint --fixausführen und dann die wenigen Regeln deaktivieren, die mit der eigenen Codebasis kollidieren — oder mit demunopinionated-Preset beginnen, das die meinungsstarken Regeln bereits vorab deaktiviert. - Das Plugin exportiert drei Presets:
recommended,unopinionated(recommended ohne die meinungsstarken Regeln) undall. prefer-set-haswandelt versehentlich quadratische.includes()-Aufrufe in Schleifen in O(n)-Set.has()-Abfragen um;no-array-for-eachschreibt.forEach()infor…ofum und ermöglicht so eine bessere TypeScript-Typverengung.- In Kombination mit
@typescript-eslint/recommended-type-checkedlassen sich Idiom-Durchsetzung und typbewusstes Linting vereinen.
Was eslint-plugin-unicorn ist und wie es konzipiert ist
eslint-plugin-unicorn ist eine Sammlung von ESLint-Regeln, die Code in Richtung moderner, fehlerunanfälligerer JavaScript- und TypeScript-Muster lenkt – etwa die Bevorzugung von Set-Mitgliedschaft gegenüber Array-Suchen, for…of statt .forEach(), node:-Import-Spezifizierer statt bloßer Modulnamen und so weiter. Es setzt ESLint >=10.4, Flat Config und ESM voraus. Das Repository beschreibt sich selbst als mit über 300 Regeln ausgestattet, und die aktuelle Version ist 69.0.0, mit Releases ungefähr im Monatsrhythmus.
Zwei Designentscheidungen prägen die Einführung des Plugins. Erstens sind die meisten Regeln automatisch korrigierbar, sodass ein Großteil der Verstöße mit eslint --fix behoben wird, anstatt manuell editiert werden zu müssen. Zweitens liefert das Plugin Preset-Konfigurationen, sodass Regeln nicht einzeln aktiviert werden müssen. Das Plugin exportiert eine recommended-Konfiguration, die bewährte Praktiken durchsetzt, sowie separat eine all-Konfiguration, die jede nicht veraltete Regel aktiviert. Die Regeltabelle verwendet Emojis zur Kennzeichnung des Status: ✅ für Regeln in der recommended-Konfiguration, ☑️ für die unopinionated-Konfiguration und 🔧 für Regeln, die durch die --fix-CLI-Option automatisch korrigierbar sind.
Der Anwendungsbereich umfasst hauptsächlich JavaScript und TypeScript, mit einem nützlichen Zusatz: Während die meisten Regeln auf JavaScript und TypeScript ausgerichtet sind, können einige auch andere Dateitypen linten, wenn sie mit dem entsprechenden ESLint-Sprach-Plugin wie @eslint/css, @eslint/json, @eslint/markdown oder @html-eslint/eslint-plugin verwendet werden. Für die meisten Teams sind die JS/TS-Regeln der eigentliche Grund für die Installation.
Installation von eslint-plugin-unicorn mit Flat Config und ESM
Discover how at OpenReplay.com.
Das Plugin und ein kompatibles ESLint installieren, dann das recommended-Preset in einer flachen eslint.config.mjs erweitern. Die aktuelle Anforderung ist ESLint 10.x — ESLint 10 hat das Legacy-eslintrc-System vollständig entfernt und Flat Config als einziges unterstütztes Format etabliert. Jedes Tutorial, das .eslintrc.json mit extends: 'plugin:unicorn/recommended' zeigt, ist daher veraltet. ESLint setzt eine aktuelle Node.js-Laufzeitumgebung voraus (Node 20.19+, 22.13+ oder 24+ gemäß der ESLint-npm-Seite).
npm install --save-dev eslint eslint-plugin-unicorn
Eine minimale, auf JavaScript- und TypeScript-Dateien beschränkte Konfiguration:
// eslint.config.mjs
import unicorn from 'eslint-plugin-unicorn';
import { defineConfig } from 'eslint/config';
export default defineConfig([
{
files: ['**/*.{js,mjs,cjs,ts,tsx}'],
extends: [unicorn.configs.recommended],
rules: {
// Überschreibungen hier eintragen
},
},
]);
Dies entspricht der offiziellen Verwendung: unicorn aus 'eslint-plugin-unicorn' importieren, {defineConfig} aus 'eslint/config' importieren und dann innerhalb von defineConfig files und extends: [unicorn.configs.recommended] setzen. Die Einschränkung mit files ist wichtig, sobald in derselben Konfiguration auch Nicht-JavaScript-Sprachen gelinted werden — Unicorns JS-Regeln sollten in einem eigenen Konfigurationsobjekt verbleiben.
Es stehen drei Presets als Ausgangspunkt zur Auswahl:
recommended— der kuratierte Standard.unopinionated—recommendedohne die meinungsstarken Regeln.all— jede nicht veraltete Regel.
Wenn das Team die meinungsstarken Regeln als zu störend empfindet, kann unicorn.configs.recommended durch unicorn.configs.unopinionated ersetzt werden, wodurch ein Großteil der unten beschriebenen manuellen Anpassungen entfällt.
Ein Migrationshinweis: Wer noch von einem Plugin abhängt, das ausschließlich eine eslintrc-konforme Konfiguration liefert, kann es mit FlatCompat aus @eslint/eslintrc einbinden. Für ESLint 10.x sollte die neueste Version von @eslint/eslintrc verwendet werden.
Die wertvollsten eslint-plugin-unicorn-Regeln mit Vorher-Nachher-Vergleichen
Die wertvollsten Unicorn-Regeln sollten zuerst eingeführt werden, da jede von ihnen ein Performance-, Korrektheitsproblem oder ein Lesbarkeitsdefizit behebt, anstatt nur stilistische Präferenzen durchzusetzen. Jedes der folgenden Beispiele zeigt, was eslint --fix erzeugt — kein handgeschriebener Idealcode.
prefer-set-has — versehentlich quadratische Lookups eliminieren
prefer-set-has markiert ein Array, das ausschließlich für .includes()-Mitgliedschaftsprüfungen verwendet wird, und lenkt zur Verwendung eines Set. Es bevorzugt Set#has() gegenüber Array#includes() bei der Prüfung auf Vorhandensein oder Nichtvorhandensein. Dies ist besonders in Schleifen relevant: Array.prototype.includes hat O(n) pro Aufruf, sodass ein Aufruf pro Iteration über eine andere Kollektion O(n²) ergibt, während Set.prototype.has annähernd konstante Laufzeit hat.
// ❌ O(n²): includes() durchsucht bei jeder Iteration das gesamte Array erneut
const allowed = ['read', 'write', 'admin', /* …Hunderte… */];
const granted = requested.filter((scope) => allowed.includes(scope));
// ✅ O(n): Set.has() hat annähernd konstante Laufzeit pro Lookup
const allowed = new Set(['read', 'write', 'admin', /* …Hunderte… */]);
const granted = requested.filter((scope) => allowed.has(scope));
Das Versagensmuster ist unauffällig: Bei kleinen Eingaben funktioniert es einwandfrei und verschlechtert sich mit wachsenden Datenmengen erheblich. Genau das sind die Regressions-Probleme bei langsamen Interaktionen, die man später in der Produktion diagnostiziert, anstatt sie im Code-Review zu entdecken.
no-array-for-each — bessere TypeScript-Typverengung und Kontrollfluss
no-array-for-each schreibt .forEach()-Callbacks in for…of-Schleifen um. Es bevorzugt for…of gegenüber der forEach-Methode. Der Vorteil geht über den Stil hinaus: for…of ermöglicht eine bessere TypeScript-Typverengung über den gesamten Schleifenkörper, erlaubt die direkte Verwendung von await ohne Callback-Umwege und unterstützt break/continue — alles Dinge, die innerhalb eines .forEach()-Callbacks nicht sauber funktionieren.
// ❌
users.forEach((user) => {
sendEmail(user);
});
// ✅ automatisch korrigiert
for (const user of users) {
sendEmail(user);
}
prefer-node-protocol — eindeutige Node-Built-ins
prefer-node-protocol schreibt einfache Built-in-Imports in die explizite node:-Form um. Es bevorzugt die Verwendung des node:-Protokolls beim Import von Node.js-Built-in-Modulen. Das explizite Präfix macht den Import eindeutig als Node-Built-in erkennbar und erschwert das versehentliche Überschatten durch ein gleichnamiges npm-Paket.
// ❌
import fs from 'fs';
import { join } from 'path';
// ✅ automatisch korrigiert
import fs from 'node:fs';
import { join } from 'node:path';
Weitere automatisch korrigierbare Verbesserungen
Jede der folgenden Regeln bildet ein veraltetes Muster auf sein modernes Äquivalent ab und wird automatisch korrigiert:
// throw-new-error — new beim Werfen eines Fehlers vorschreiben
throw Error('boom'); // ❌
throw new Error('boom'); // ✅
// prefer-string-replace-all — globales Ersetzen ohne /g-Regex
str.replace(/-/g, ' '); // ❌
str.replaceAll('-', ' '); // ✅
// prefer-array-flat-map — map().flat() zusammenfassen
rows.map((r) => r.cells).flat(); // ❌
rows.flatMap((r) => r.cells); // ✅
// new-for-builtins — new für Map/Set/Array/Date usw. vorschreiben
const cache = Map(); // ❌
const cache = new Map(); // ✅
Die Regel throw-new-error schreibt new bei der Fehlererzeugung vor (sowohl für const e = Error() als auch für throw Error()), und sie ist in der recommended-Konfiguration enthalten und automatisch korrigierbar. new-for-builtins erzwingt die Verwendung von new für alle Built-ins, mit Ausnahme von String, Number, Boolean, Symbol und BigInt. Array.prototype.flatMap ist sowohl klarer als auch effizienter, da es das Zwischenarray vermeidet, das .map().flat() alloziert.
Zwei auf Lesbarkeit ausgerichtete Regeln runden die hochwertigsten Regeln ab. better-regex verbessert reguläre Ausdrücke, indem es sie kürzer und konsistenter macht (beispielsweise wird [0-9] zu \d). prefer-ternary fasst einfache if/else-Blöcke zusammen: Es bevorzugt ternäre Ausdrücke gegenüber einfachen if-Anweisungen, die Werte zurückgeben oder zuweisen. Eine if-else-Anweisung erzeugt typischerweise mehr Zeilen als ein einzeiliger ternärer Ausdruck und kann dazu zwingen, Variablen mit let zu deklarieren, nur um sie in den Blöcken neu zuzuweisen — was sie unnötig veränderlich macht und verhindert, dass prefer-const die Variable markiert.
// ❌
function status(ok) {
if (ok) {
return 'pass';
} else {
return 'fail';
}
}
// ✅ automatisch korrigiert
function status(ok) {
return ok ? 'pass' : 'fail';
}
Die umstrittenen Regeln und wie man entscheidet
Einige recommended-Regeln erzwingen Präferenzen statt Korrektheit und erzeugen den meisten Lärm in einer bestehenden Codebasis. Die folgende Tabelle zeigt die Empfehlung – beibehalten, als Warnung einstufen oder deaktivieren – für die üblichen Kandidaten, die alle in recommended aktiviert sind.
| Regel | Empfehlung | Begründung |
|---|---|---|
prevent-abbreviations | Warnung oder eingrenzen | Benennt e → error, req → request, props → properties um; kollidiert mit Namen, die Framework und Team bereits verwenden. |
no-null | Deaktivieren, wenn null verwendet wird | Unicorn bevorzugt undefined, aber null ist legitim, wenn ein ORM oder eine API es zurückgibt — es gibt keine universell richtige Antwort. |
no-array-reduce | Beibehalten oder als Warnung | Verbietet Array#reduce() und Array#reduceRight(); aus Lesbarkeitsgründen sinnvoll, aber reduce ist für viele Teams akzeptabel. |
filename-case | Ausnahmen eingrenzen | Kollidiert mit Framework-vorgeschriebenen Dateinamen; beibehalten, aber Ausnahmen ausschließen. |
Der Fall no-null ist am eindeutigsten: Unicorn bevorzugt undefined, doch null ist das, was viele Datenbanktreiber und HTTP-APIs zurückliefern. Das Erzwingen einer Variante über die andere erzeugt Konvertierungsaufwand ohne Korrektheitsgewinn. Deaktivieren, wenn null Teil des Datenvertrags ist.
Diese Regeln müssen nicht manuell deaktiviert werden. Das unopinionated-Preset lässt die meinungsstarken Regeln — einschließlich no-null und prevent-abbreviations — standardmäßig deaktiviert, und ist damit die eingebaute Mitte zwischen recommended und einer stark angepassten Konfiguration.
Für beibehaltene, aber anzupassende Regeln empfiehlt sich Eingrenzen statt Deaktivieren. Ein gängiges Muster für filename-case schließt Framework-Dateien aus:
{
files: ['**/*.{js,ts,tsx}'],
extends: [unicorn.configs.recommended],
rules: {
'unicorn/no-null': 'off',
'unicorn/prevent-abbreviations': 'warn',
'unicorn/filename-case': [
'error',
{
cases: { pascalCase: true, camelCase: true },
ignore: ['next-env\\.d\\.ts', 'vite\\.config\\.ts'],
},
],
},
}
Schrittweise Einführung in einer bestehenden Codebasis
Das Plugin stufenweise einführen, damit der erste Durchlauf nicht von Fehlern überwältigt. Die bewährte Vorgehensweise:
- Mit einem Preset beginnen.
unicorn/recommendederweitern, oderunicorn/unopinionated, wenn die meinungsstarken Regeln für das Team zu störend sind. - Zuerst automatisch korrigieren.
npx eslint . --fixausführen. Da die meisten Regeln automatisch korrigierbar sind, verschwinden hier ein Großteil der Verstöße, und man überprüft einen einzigen mechanischen Diff statt Hunderte einzelner Fehler. - Störende Regeln auf
warnherabstufen. Alles, was noch in großem Umfang auslöst und kein Korrektheitsproblem darstellt —prevent-abbreviationsist der übliche Kandidat — auf'warn'setzen, damit CI während der Migration nicht blockiert wird. - Ausnahmen eingrenzen statt vollständig deaktivieren. Die
ignore-Option (wie beifilename-case) undfiles-Globs verwenden, um Ausnahmen zu definieren, anstatt eine nützliche Regel überall zu deaktivieren. - Typbewusstes Linting ergänzen.
@typescript-eslint/recommended-type-checkedneben Unicorn hinzufügen. Unicorn setzt Idiome durch; die typgeprüfte Konfiguration von typescript-eslint findet Fehler, die nur das Typsystem erkennen kann. Beide ergänzen sich und sind gemeinsam eine starke Standardkonfiguration für TypeScript-Projekte.
Die Konfiguration als lebendes Dokument behandeln. Mit jedem Plugin-Upgrade — Releases erscheinen ungefähr monatlich — die Regeltabelle auf neue Regeln und Umbenennungen prüfen und überdenken, welche warn-Regeln bereit sind, zu error befördert zu werden.
Der schnellste Weg zu besserem JavaScript mit eslint-plugin-unicorn ist unspektakulär: unicorn/recommended erweitern, eslint --fix ausführen und die Aufmerksamkeit nur auf die wenigen meinungsstarken Regeln richten, die tatsächlich mit dem Schreibstil des Teams kollidieren. Heute mit dem Preset beginnen, den Autofixer die Hauptarbeit erledigen lassen und von dort aus anpassen — die offizielle Regeltabelle ist die Referenz für den aktuellen Status und die Optionen jeder Regel.
Häufig gestellte Fragen
Funktioniert eslint-plugin-unicorn zusammen mit typescript-eslint, oder gibt es Konflikte?
Beide ergänzen sich und sind darauf ausgelegt, gemeinsam zu laufen. Unicorn setzt moderne JavaScript- und TypeScript-Idiome durch, während typescript-eslint typbewusste Regeln hinzufügt, die Fehler erkennen, die nur das Typsystem sehen kann. Beide als separate Konfigurationsobjekte in der flachen eslint.config.mjs hinzufügen und unicorn/recommended mit der recommended-type-checked-Konfiguration von typescript-eslint kombinieren. Beide gemeinsam zu aktivieren ist eine starke Standardkonfiguration für TypeScript-Projekte, ohne Regelüberschneidungen, die aufgelöst werden müssten.
Was ist der Unterschied zwischen den Presets recommended und unopinionated?
Das recommended-Preset ist der kuratierte Standard, der sowohl Korrektheitsregeln als auch meinungsstarke stilistische Regeln aktiviert. Das unopinionated-Preset ist recommended ohne die meinungsstarken Regeln und deaktiviert daher kontroverse Einträge wie no-null und prevent-abbreviations vorab, die in gewachsenen Codebasen zu Reibungspunkten führen. unopinionated wählen, wenn das Team die stilistischen Regeln als zu störend empfindet; es ist die eingebaute Mitte zwischen recommended und einer stark angepassten Konfiguration. Ein drittes Preset, all, aktiviert jede nicht veraltete Regel.
Warum funktioniert meine alte .eslintrc-Konfiguration mit extends plugin:unicorn/recommended nicht mehr?
ESLint 10 hat das Legacy-eslintrc-System vollständig entfernt und Flat Config als einziges unterstütztes Format etabliert. eslint-plugin-unicorn setzt ESLint 10.4 oder höher, Flat Config und ESM voraus. Die alte .eslintrc-Syntax mit extends 'plugin:unicorn/recommended' als Zeichenkette wird nicht mehr geladen. Migration zu einer eslint.config.mjs, die unicorn aus 'eslint-plugin-unicorn' importiert und extends auf unicorn.configs.recommended innerhalb eines mit files eingeschränkten Konfigurationsobjekts setzt.
Wird das Hinzufügen von eslint-plugin-unicorn meinen Build mit Hunderten von Fehlern zum Absturz bringen?
Die meisten Verstöße werden automatisch behoben, da die Mehrheit der Unicorn-Regeln automatisch korrigierbar ist. Zuerst eslint mit dem fix-Flag ausführen, was einen Großteil der Probleme als einzelnen mechanischen Diff bereinigt, anstatt Hunderte einzelner Fehler zu erzeugen. Für Regeln, die noch in großem Umfang auslösen, aber keine Korrektheitsprobleme darstellen — wie prevent-abbreviations — auf warn setzen, damit CI während der Migration nicht blockiert wird. Dieses stufenweise Vorgehen hält den Build grün, während das Plugin eingeführt wird.