ts-r-lint

Linter. Replaces ESLint + typescript-eslint.

  • Pre-alpha
  • Works from source

ts-r-lint runs ESLint-compatible rules over JavaScript and TypeScript. It reads the config you already have, reports in ESLint’s formats and exits with ESLint’s codes, so it can stand in for eslint in scripts and CI when your config only uses the rules it has.

All 103 ts-r-lint rules, same configShorter is faster. Pre-release build, real app.
  • ts-r-lint, config cached47 ms
  • ESLint 10.12 + typescript-eslint2,790 ms

59× faster linting

What switching looks like

Nothing is on npm yet. Once it is, switching looks like this: ts-r-lint reads the config you already have, so the change is to the command, not the project.

package.json
  "scripts": {
-   "lint": "eslint .",
+   "lint": "ts-r-lint .",
-   "lint:fix": "eslint --fix .",
+   "lint:fix": "ts-r-lint --fix .",
  }

What works, and what doesn’t yet

Works today

  • 103 rules: all 64 of ESLint 10’s recommended set and typescript-eslint’s recommended and strict rules that don’t need types
  • Every case of the published ESLint and typescript-eslint tests for those rules matches
  • ESLint flat config, .oxlintrc.json and biome.json
  • --fix, eslint-disable comments and inline config, with unused-disable reports
  • Output as stylish, json, sarif or GitHub Actions annotations

Not yet

  • No type-aware rules; they are skipped and listed on stderr
  • No ESLint plugins other than typescript-eslint

Measured

Every run, on the same reference app as the home page, with the command and commit that recorded it.

ts-r-lint against ESLint and oxlint

Linting private-app (690 files). ts-r-lint reports the same problems as ESLint for every rule it implements (1,458 match, 0 missed, 0 extra with all rules on). ESLint's project configs also run type-aware rules that ts-r-lint does not have yet, so the second chart flatters ts-r-lint: it does less work there.

All 103 ts-r-lint rules, same configShorter is faster, in ms
  • ts-r
  • Other tools
  • ts-r-lint, config cached47 ms
  • ts-r-lint, config run by Node360 ms
  • ESLint 10.12 + typescript-eslint2,790 ms
The project's own configs (23 packages)Shorter is faster, in ms
  • ts-r
  • Other tools
  • ts-r-lint, config cached52 ms
  • ts-r-lint, config run by Node390 ms
  • ESLint, 23 runs, type-aware18,900 ms
oxlint (not like-for-like)
RunTimeNotes
oxlint 1.88, its default rules, binary50 msDifferent rule set from the runs above, so not a like-for-like comparison
npx -y oxlint, default rules470 msIncludes npx start-up
ts-r-lint, all 103 rules, config cached47 msFor reference
How we measured
Measured
Wall time of the whole command, median of 3 to 5 runs, 4 threads
Machine
Apple M-series Mac, macOS arm64, release build (the exact chip was not recorded)
Software
ts-r-lint release build; ESLint 10.12 with typescript-eslint; oxlint 1.88
Input
A copy of private-app (690 files) with dependencies stubbed so configs load
Command
python3 -I crates/ts_r_lint/tests/oracle/project/bench.py <runs> <cwd> -- <command> (setup in crates/ts_r_lint/tests/oracle/project/setup.py)
Recorded in
commit adeb864

Correctness

Compared with the tool ts-r-lint replaces, on its own tests and on real code.

  • Lint rules100%

    8,597 of 8,597 cases match

    Every case of the published ESLint and typescript-eslint tests for the 103 rules. Commit 27c280e.

Command line

An excerpt of ts-r-lint --help. You can also run it through the launcher as ts-r lint.

Next to ESLint

A common split: run ts-r-lint on every save or commit for the fast rules, and keep ESLint in CI for type-aware rules and plugins ts-r-lint doesn’t have yet. In the editor, ts-r-lsp shows the same diagnostics.

ts-r-lint --help
ts-r-lint [options] [paths...]

  -f, --format <name>      stylish (default), json, sarif, github
  -c, --config <path>      Use this config for every file
      --fix                Apply fixes
      --max-warnings <n>   Exit 1 above this many warnings
      --list-rules         Print the rules ts-r-lint has