A from-the-ground-up reimplementation of @tsslint/compat-eslint and
a perf overhaul of the @tsslint/core hot path. Public API is unchanged;
you should see meaningfully faster lint and lower memory without
touching your config.
📝 Writeup: Running ESLint rules at 16× speed in TSSLint — https://gist.github.com/johnsoncodehk/dcd318b51b9102da97032abb73b11975
📊 Bench: tsslint-dify-bench
Performance
On Dify web/ (5860 .ts/.tsx, single type-aware rule, shared
ts.Program):
| Wall (min of 3) | Peak RSS | |
|---|---|---|
| TSSLint 3.0.4 | 23.0 s | 7.0 GB |
| TSSLint 3.1 | 1.5 s | 3.75 GB |
| ESLint Linter | 25.0 s | 7.0 GB |
≈15× faster than the previous release, ≈16× faster than ESLint Linter,
~50% lower peak memory than both.
Architecture
@tsslint/compat-eslintno longer depends on theeslintpackage
at runtime.CodePathAnalyzervendored underlib/code-path-analysis/;
SourceCodereimplemented asLazySourceCode; scope-manager
rewritten on top ofts.TypeChecker; visitor-keys inlined.- Lazy-materialized ESTree shim driven by direct walks over
ts.SourceFile; most ts.Nodes never become ESTree objects. @tsslint/cliruns on the main thread (droppedworker_threads,
dropped the live progress spinner).@tsslint/configimportESLintRuleslazy-loads individual rules
instead of importing the whole plugin module graph.
Diagnostic accuracy
no-undeffalse positives on cross-file declaration merging cut
~92% on TypeScript-repo measurement (lib redeclarations,
declare moduleaugmentations, interface+namespace merges).- Phantom
VariableDeclaratoroncatch (e)params removed. - JSX entity decoding parity restored across the full 252-entry
xhtml table ( → U+00A0 not 0x20, etc.). - ~15 lazy-estree shape parity gaps closed.
Internal API
@tsslint/core: removed the syntax-only fast path. Only matters
if you consume@tsslint/coredirectly. CLI / typescript-plugin
/ VSCode extension users see no change.
Known gaps
A small set of baselined divergences vs ESLint upstream remain — see
packages/compat-eslint/test/bench/baseline.json.
Most are cases where TSSLint follows TypeScript semantics and ESLint
is wrong for TS code (no-redeclare on declaration merging,
enum + interface, etc.).