Hinweis: Dieses Video und der Podcast wurde mithilfe von KI erstellt auf Grundlage der ursprünglichen Inhalten sowie den technischen Erkenntnissen des Autors des Blogartikels.
In JavaScript gibt es für ein Problem immer mehrere Lösungen. Das Linting, also die statische Analyse von Quellcode, war da jedoch eine Ausnahme. Lange Zeit war ESLint das Werkzeug der Wahl, wenn es um die Analyse von JavaScript- und TypeScript-Code ging. Egal, ob es um die Einbindung in die IDE oder die Integration in die Build-Pipeline ging, es führte kaum ein Weg an ESLint vorbei. Mit Version 9 wurde die Flat Config zum Standard, das alte eslintrc-Format konnten Sie jedoch weiter nutzen. Für viele Projekte bestand kein Handlungsdruck. Dann wurde Version 10 veröffentlicht und wie es bei Projekten, die den SemVer-Ansatz ernst nehmen, so üblich ist, kann es bei einem Major-Release Breaking Changes geben. In dieser Version wurde das alte Format endgültig entfernt. Die aufgeschobenen Migrationen bekamen dadurch eine gewisse Dringlichkeit, vor allem vor dem Hintergrund, dass die Version 9 von ESLint seit dem 6. August 2026 keine Updates mehr erhält. Und plötzlich bekommt ein Werkzeug Aufmerksamkeit, das lange unauffällig und zuverlässig seinen Dienst verrichtet hat. Parallel zu diesem Release kommt noch etwas anderes hinzu: Das Konkurrenzprojekt Oxlint nimmt an Fahrt auf. Es ist größtenteils kompatibel zu ESLint, deutlich schneller und hat eine modernere Codebasis. Die eigenen Benchmarks von Oxlint zeigen, dass es bei gewöhnlichen Lintingaufgaben 50- bis 100-mal schneller ist als ESLint. Bei den typbasierten Regeln, also bei Regeln, die den Type-Checker von TypeScript nutzen, ist es laut Oxlint immerhin noch 10- bis 20-mal schneller. Ob das nur ein typisches Benchmark-Versprechen ist oder tatsächlich auch bei Ihrem Projekt der Fall ist, müssen Sie selbst messen. Und dann steht ja noch die nächste größere Änderung bei den Werkzeugen an: TypeScript 7 mit dem neuen, in Go geschriebenen Compiler, auch als tsgo bekannt. Hier machen sich das Alter und die gewachsene Struktur von ESLint bemerkbar. ESLint und typescript-eslint sind über die Jahre um den alten, in TypeScript geschriebenen TypeScript-Compiler und dessen Schnittstellen gebaut worden. Genau diese Schnittstellen gibt es in tsgo (noch) nicht. typescript-eslint muss also erst mühevoll auf die neue TypeScript-Version angepasst werden. Oxlint hat diese Altlast nicht und baut bei den typbasierten Regeln direkt auf tsgo auf. Auch, wenn das jetzt kein hartes Kriterium gegen ESLint ist, Oxlint wird dadurch noch einmal mehr zu einer interessanten Alternative.
Rust im Kern, Go für die Typen
Im Vergleich zu ESLint (seit 2013) ist Oxlint, das es seit 2023 gibt, ein noch junges Projekt. Im Gegensatz zu vielen bisherigen Werkzeugen im Web folgt Oxlint dem Trend, dass moderne Werkzeuge mit Rust implementiert werden. Die Gründe sind vor allem die Performance und die Speichersicherheit der Programmiersprache. Oxlint ist Teil von Oxc, einer Sammlung von Rust-Werkzeugen für JavaScript und TypeScript, zu der unter anderem auch ein Parser und ein Formatter gehören. Der Rust-Kern übernimmt das Dateihandling, die Kernlogik des Linters, die Konfiguration und alle nicht typbasierten Regeln. Hinzu kommt tsgolint, ein zweites, in Go geschriebenes Programm, das eng mit tsgo verflochten ist. Es wird als eigenes Paket installiert und über die Option –type-aware aktiviert. Oxlint nutzt diese Erweiterung für alle typbasierten Regeln. Diese arbeiten direkt auf dem TypeScript-AST und benötigen, anders als bei typescript-eslint, keine zusätzliche Umwandlung.
Aufgrund dieser Architektur arbeitet Oxlint im Kern mit zwei ASTs: dem TS-AST von tsgo für typbasierte Regeln und einem weiteren AST für alle übrigen Regeln. Der zweite AST stammt aus dem Parser von Oxc. Eine Regel arbeitet auf einer von zwei Pipelines: das normale Syntax-Linting läuft über Rust und das TypeScript-Linting über Go.
Der grundsätzliche Ablauf ist in beiden Fällen ähnlich. Der Parser erzeugt aus dem Quellcode einen AST, der Linter durchläuft ihn und die Regeln prüfen die einzelnen Knoten. Im Detail gibt es aber einen Unterschied. In tsgolint registriert sich eine Regel, wie man es von ESLint kennt, für einen oder mehrere Knotentypen und wird nur für diese aufgerufen. Die Rust-Regeln von Oxlint registrieren sich nicht explizit. Sie prüfen in ihrer run-Methode selbst, ob der Knotentyp für sie interessant ist. Aus diesen Prüfungen leitet ein Codegenerator ab, für welche Knotentypen eine Regel überhaupt aufgerufen werden muss. Das Ergebnis liegt als generierter Code im Repository und wird neu erzeugt, wenn sich eine Regel ändert. Findet eine Regel ein Problem, meldet sie es als Diagnose in Form eines Objekts. Dieses beinhaltet die Nachricht, die Start- und Endposition im Code und optional einen Hinweis zur Behebung. Kann das Problem automatisch behoben werden, hängt die Regel den Fix gleich mit an. Den Namen der Regel und den Schweregrad ergänzt Oxlint.
Die dritte Pipeline: Plug-ins in JavaScript
Beide nativen Pipelines haben einen Haken: Sie sind fest kompiliert und können keine Regeln nachladen. Brauchen Sie eigene Regeln, müssten Sie sie in Rust schreiben und in Oxlint selbst integrieren. Für die typische eigene Regel, die es in fast jedem größeren Projekt gibt, ist das keine Option, und dasselbe gilt für die vielen ESLint-Plug-ins, die Oxlint nicht nachgebaut hat. Seit Oktober 2025 als Preview und seit März 2026 als Alpha gibt es deshalb einen dritten Weg. Oxlint führt Plug-ins aus, die in JavaScript geschrieben sind, und stellt ihnen dafür die Plug-in-API von ESLint ab Version 9 zur Verfügung. Die meisten bestehenden Plug-ins sollen damit ohne Anpassung laufen.
In der Konfiguration bekommen diese Plug-ins einen eigenen Eintrag namens jsPlugins. Dort steht entweder der Name eines npm-Pakets oder der Pfad zu einer lokalen Datei. Die Regeln selbst aktivieren Sie wie gewohnt über den Namen des Plug-ins.
Technisch gesehen ist das die schwierigste der drei Pipelines, denn der AST entsteht in Rust und muss für jede Datei an JavaScript übergeben werden. Ein solcher Übergang kann den Geschwindigkeitsvorteil von Oxlint schnell wieder zunichtemachen. Das Werkzeug setzt dafür auf einen eigenen Mechanismus mit dem Namen Raw Transfer ein, der den Aufwand bei der Übergabe so klein wie möglich hält. Das Team hat das Repository von Node.js migriert, mit 104 nativen und 98 JavaScript-Regeln. Oxlint braucht dafür 21 Sekunden, ESLint 1 Minute und 43 Sekunden. Das ist knapp das Fünffache und damit weit entfernt vom Faktor 50, aber immer noch ein deutlicher Unterschied.
Eine eigene Regel in zwei Varianten
In vielen Projekten gilt die Regel, dass nur die Konfigurationsschicht auf process.env zugreifen darf und sich der Rest der Anwendung die Werte von dort holt. Durchsetzen können Sie eine solche Regel am besten mit einer eigenen Lint-Regel. In Listing 1 sehen Sie sie als ESLint-Plug-in umgesetzt.
Listing 1: Linter-Regel als ESLint-Plug-in
Die Funktion create bekommt den Kontext der aktuellen Datei und gibt ein Objekt mit Listenern zurück. Der Schlüssel ist ein Selektor, der auf jeden Zugriff auf process.env passt. Liegt die Datei im Verzeichnis config, gibt die Funktion ein leeres Objekt zurück und die Regel bleibt wirkungslos. Für Oxlint reichen die beiden Einträge in der Konfiguration aus Listing 2 aus, um die Regel zu aktivieren.
Listing 2: Einbindung in der .oxlintrc.json
Der Aufruf von npx oxlint src meldet den Zugriff in einer Servicedatei und lässt die Datei unter src/config unbehelligt auf die Umgebungsvariablen zugreifen. ESLint kommt mit dem Plug-in zum selben Ergebnis.
Die Funktion create macht dem Rust-Kern von Oxlint jedoch potenziell Probleme. ESLint ruft sie für jede Datei neu auf und sie kann jedes Mal andere Listener liefern. Im Beispiel passiert genau das, wenn je nach Dateiname ein leeres Objekt zurückgegeben wird. Oxlint kann deshalb nicht im Voraus wissen, für welche Knoten sich eine Regel interessiert, und muss für jede Datei nach JavaScript wechseln, auch wenn dort kein einziger passender Knoten vorkommt. Dafür gibt es eine zweite Schreibweise, die Sie in Listing 3 sehen.
Listing 3: Implementierung der Regel mit createOnce
createOnce wird nur einmal aufgerufen. Was der Linter pro Datei ausführen soll, liegt im before-Hook. Gibt dieser false zurück, überspringt Oxlint die Regel für diese Datei. Damit stehen die Listener fest. Auf dieser Grundlage soll die Rust-Seite zukünftig die passenden Knoten schon beim Durchlaufen des AST einsammeln und den Wechsel nach JavaScript vermeiden, wenn es keine gibt. Die Funktion eslintCompatPlugin ergänzt jede Regel um ein create, das an createOnce weiterreicht. Das Plug-in läuft also weiterhin auch in ESLint. Schneller ist die neue Schreibweise heute noch nicht, die Dokumentation sagt das ganz offen. Wer jetzt umstellt, bekommt die Optimierungen später ohne Anpassung mit einem Versionsupdate.
Wo es noch hakt
Die JavaScript-Plug-ins sind aktuell noch in der Alpha-Version. Das größte Problem sind eigene Dateiformate. Plug-ins, die einen eigenen Parser mitbringen, funktionieren nicht, und damit bleiben die Templates von Vue, Svelte und Angular ungeprüft. Bei Vue-Komponenten sieht Oxlint derzeit nur den Skriptteil. In Projekten mit diesen Frameworks bleibt ESLint deshalb vorerst unverzichtbar. Die zweite Lücke betrifft die Typen. Ein JavaScript-Plug-in kommt nicht an die Typinformationen heran, und tsgo nimmt keine eigenen Regeln auf. Eine eigene Regel, die den Type Checker braucht, können Sie im Moment mit Oxlint noch nicht umsetzen.
Beim typbasierten Linting selbst ist die Hürde TypeScript 7. Ältere Versionen werden nicht unterstützt, einige alte tsconfig-Optionen wie baseUrl ebenfalls nicht. Von den gut 60 typbasierten Regeln aus typescript-eslint fehlen noch naming-convention und prefer-destructuring. Dazu kommt, dass tsgolint über einen Umweg auf interne Schnittstellen von tsgo zugreift, weil es eine offizielle API noch nicht gibt. Jede neue TypeScript-Version braucht deshalb eine passende Version von tsgolint. An der Versionsnummer lässt sich das ablesen, die Version 7.0.2003 gehört zu TypeScript 7.0.2, wobei 003 die Patch-Version von tsgolint ist.
Der Umstieg
Für die Migration gibt es ein eigenes Werkzeug. Mit npx @oxlint/migrate lesen Sie eine bestehende eslint.config.js ein und erzeugen daraus eine .oxlintrc.json. Mit der Option –type-aware übernimmt es auch die typbasierten Regeln. Regeln, Schweregrad und Overrides bleiben erhalten, Plug-ins ohne natives Gegenstück landen unter jsPlugins. Zwei Dinge sollten Sie vorher wissen: Das Werkzeug kann nur mit der neueren Flat Config arbeiten. Haben Sie in Ihrem Projekt noch eine eslintrc-Datei, müssen Sie sie zuerst mit @eslint/migrate-config umwandeln. Um den Umbau der Konfiguration kommen Sie also auch mit Oxlint nicht herum. Außerdem übernimmt das Werkzeug lokale Plug-ins nicht. Sie müssen hier also von Hand nacharbeiten.
Sind Sie auf Plug-ins angewiesen, die Oxlint noch nicht ausführen kann, können Sie beide Linter nacheinander laufen lassen. Das Paket eslint-plugin-oxlint schaltet in ESLint alle Regeln ab, die Oxlint schon abdeckt, sodass für ESLint nur noch der Rest übrigbleibt.
Und was lernen wir daraus?
Ob sich der Wechsel auf Oxlint lohnt, hängt vor allem von Ihrem Projekt ab. Für eine TypeScript-Anwendung ohne Templates, die ohnehin auf TypeScript 7 umgestellt wird, spricht nichts dagegen. Das typbasierte Linting ist stabil, fast alle Regeln funktionieren und Sie können die Konfiguration weitestgehend automatisch übernehmen. Mit Vue, Svelte oder Angular ist ein Parallelbetrieb die realistischere Variante, bei der Oxlint die schnellen Prüfungen übernimmt und ESLint sich um die Templates kümmert. Haben Sie viele eigene Regeln oder ausgefallene Plug-ins im Einsatz, müssen Sie sie einzeln prüfen, bevor Sie ESLint aus dem Projekt nehmen.
Bleibt die Frage, auf wen Sie sich verlassen wollen. ESLint ist Teil der OpenJS Foundation und blickt auf mehr als 13 Jahre Entwicklungsgeschichte zurück. Es hat außerdem ein umfangreiches Ökosystem, das Oxlint bisher nur über die JavaScript-Plug-ins integriert. Hinter Oxlint steht mit VoidZero ein einzelnes Unternehmen, das auch Vite und Rolldown entwickelt. Das kann man als Risiko sehen oder aber als Grund dafür, dass die Werkzeuge so gut zusammenpassen. Die eigenen Regeln müssen Sie deswegen jedenfalls nicht zwei Mal schreiben, denn ein Plug-in, das heute für Oxlint entsteht, funktioniert auch in ESLint.
Author
🔍 Frequently Asked Questions (FAQ)
1. Was ist Oxlint und worin unterscheidet es sich von ESLint?
Oxlint ist ein schneller Linter für JavaScript und TypeScript. Während ESLint auf JavaScript basiert, nutzt Oxlint Rust für die reguläre Codeanalyse und Go für typbasierte Regeln. Dadurch kann es viele Prüfungen deutlich schneller ausführen.
2. Wie viel schneller ist Oxlint im Vergleich zu ESLint?
Laut den eigenen Benchmarks des Oxlint-Teams ist das Tool bei gewöhnlichen Lintingaufgaben 50- bis 100-mal schneller. Bei typbasierten Regeln beträgt der Vorsprung demnach das 10- bis 20-Fache. Die tatsächliche Performance hängt allerdings vom jeweiligen Projekt ab und sollte selbst gemessen werden.
3. Warum setzt Oxlint auf Rust und Go?
Rust übernimmt Dateihandling, Konfiguration und die meisten Linting-Regeln. Für typbasierte Prüfungen nutzt Oxlint tsgolint, das in Go geschrieben ist und direkt auf dem neuen TypeScript-Compiler tsgo aufbaut. So entfallen zusätzliche Umwandlungsschritte, die bei ESLint und typescript-eslint nötig sind.
4. Kann Oxlint bestehende ESLint-Plug-ins verwenden?
Ja. Oxlint bietet eine JavaScript-Plug-in-Schnittstelle, die auf der ESLint-Plug-in-API ab Version 9 basiert. Viele bestehende Plug-ins sollen dadurch ohne Anpassungen funktionieren. Die Unterstützung befindet sich allerdings noch in der Alpha-Phase und hat Einschränkungen.
5. Welche Einschränkungen hat Oxlint aktuell?
Plug-ins mit eigenen Parsern werden derzeit nicht unterstützt. Deshalb kann Oxlint beispielsweise Templates von Vue, Svelte und Angular nicht vollständig prüfen. Außerdem können JavaScript-Plug-ins aktuell nicht auf Typinformationen zugreifen. Eigene typbasierte Regeln lassen sich ebenfalls noch nicht umsetzen.
6. Wie funktioniert die Migration von ESLint zu Oxlint?
Mit npx @oxlint/migrate lässt sich eine bestehende ESLint-Flat-Config in eine Oxlint-Konfiguration umwandeln. Mit --type-aware werden auch typbasierte Regeln übernommen. Lokale Plug-ins müssen allerdings manuell nachgearbeitet werden. Projekte mit dem alten eslintrc-Format müssen dieses zunächst in eine Flat Config überführen.
7. Sollte man ESLint vollständig durch Oxlint ersetzen?
Das hängt von der eingesetzten Technologie und den verwendeten Plug-ins ab. Für TypeScript-Projekte ohne Template-Dateien kann ein vollständiger Wechsel sinnvoll sein. Bei Vue, Svelte oder Angular empfiehlt sich zunächst ein Parallelbetrieb: Oxlint übernimmt die schnellen Standardprüfungen, während ESLint die noch fehlenden Funktionen abdeckt.





