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.
8.6× 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.
"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
Each project linted with its own config. Not like-for-like yet: ESLint also runs plugin rules ts-r-lint does not have (on TypeORM most of its problems come from jsdoc rules), and where ts-r-check's diagnostics differ from tsc's, ts-r-lint runs without type information (its parity gate), so its type-aware column is a type check plus the untyped rules. The rules themselves match ESLint's and typescript-eslint's test suites (see Correctness).
- ts-r
- Other tools
- ts-r
- Other tools
- ts-r
- Other tools
| Run | Time | Peak memory |
|---|---|---|
| Playwright core sources: ts-r-lint / no type check | 725 / 59 ms | 465 / 17 MB |
| Playwright core sources: ESLint | 5,441 ms | 2,341 MB |
| date-fns pkgs/core/src: ts-r-lint | 76 ms | 14 MB |
| date-fns pkgs/core/src: oxlint (its own config) | 348 ms | 301 MB |
| tRPC: ts-r-lint / ESLint | 186 / 2,566 ms | 148 / 992 MB |
| TypeORM: ts-r-lint / ESLint | 810 / 6,718 ms | 380 / 1,748 MB |
How we measured
- Measured
- Wall time of the whole command with hyperfine (cargo xtask bench --repos), median of 3 to 5 runs; peak RSS of one extra run
- Machine
- Apple M-series MacBook (macOS arm64, 16 cores, 48 GB), shared with other jobs while measuring; release build, 4 threads
- Software
- ts-r-lint release build with 4 threads; each repo's own ESLint or oxlint from its lockfile
- Input
- tRPC, TypeORM, Playwright and date-fns at the commits pinned in bench/repos.toml, with their own lint configs
- Command
cargo xtask bench --fetch-repos --repos trpc,typeorm,playwright,date-fns && cargo xtask bench --repos trpc,typeorm,playwright,date-fns --memory lint-- Recorded in
- commit
9c3a371
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 [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