Highlights
Typed rule configuration in defineConfig
defineConfig() now provides autocomplete and type checking for ESLint core and @typescript-eslint rules. Editors suggest rule names, severity levels, and rule-specific options, and report invalid options before rslint runs.
import { defineConfig } from '@rslint/core';
export default defineConfig([
{
rules: {
// Rule names are autocompleted.
'no-console': [
'error',
{
// Option names and values are typed for this rule.
allow: ['warn'],
// allow: 123, // TypeScript error: expected string[].
},
],
},
},
]);Full typescript-eslint preset support
ts.configs now includes recommendedTypeChecked, strict, strictTypeChecked, stylistic, and stylisticTypeChecked, matching the upstream typescript-eslint presets. As a breaking change, ts.configs.recommended no longer includes ESLint core rules; add js.configs.recommended before it for a complete TypeScript setup.
What's Changed
Breaking Changes 🍭
JavaScript runtime globals must be declared
no-undef now follows ESLint's scope-based global resolution. For plain JavaScript files, Rslint no longer treats globals provided by TypeScript declaration files as implicitly available. ECMAScript built-ins such as Array and Promise remain available by default, but runtime-specific globals such as window, document, process, and __dirname must be declared through languageOptions.globals.
Because js.configs.recommended enables no-undef, projects using this preset may see new diagnostics after upgrading. The globals package can be used to declare the environments each file runs in:
import { defineConfig, js } from '@rslint/core';
import globals from 'globals';
export default defineConfig([
js.configs.recommended,
{
files: ['**/*.js', '**/*.jsx', '**/*.mjs', '**/*.cjs'],
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
},
]);Only include the environments that apply to those files. See languageOptions.globals for details.
Note: Rslint plans to provide built-in runtime globals presets in a future release, removing the need to install the standalone
globalspackage.
New Features 🎉
- feat(rstest): add no-conditional-expect rule by @elecmonkey in #1548
- feat(rstest): add expect assertion parser by @elecmonkey in #1595
- feat(jest,rstest): add shared AST utilities by @elecmonkey in #1594
- feat: resolve globals to off/readonly/writable levels by @swwind in #1551
- feat: port rule import/no-restricted-paths by @swwind in #1561
- feat: port rule unicode-bom by @swwind in #1560
- feat: port rule no-useless-return by @swwind in #1583
- feat(typescript-eslint): implement restrict-template-expressions by @swwind in #1558
- feat: port rule consistent-return by @swwind in #1580
- feat(typescript-eslint): port rule no-unnecessary-type-parameters by @swwind in #1612
- feat(config): ship the remaining typescript-eslint presets by @swwind in #1608
- feat(typescript-eslint): declare options JSON Schema for @typescript-eslint/ rules by @swwind in #1469
- feat(jest,rstest): parse setup and teardown hooks by @elecmonkey in #1593
- feat(rstest): add no-interpolation-in-snapshots rule by @elecmonkey in #1604
- feat(rstest): add valid-title rule by @elecmonkey in #1606
- feat: support languageOptions.ecmaVersion by @fansenze in #1603
- feat: support client-specified LSP config path by @fansenze in #1630
- feat(eslint): declare options JSON Schema for eslint core rules by @swwind in #1480
- feat: generate TypeScript types for native rule options by @swwind in #1279
Performance 🚀
- perf: port no-undef to ctx.Refs.Resolve, drop RequiresTypeInfo by @swwind in #1512
- perf: optimize ignore matcher by @fansenze in #1625
- perf: optimize prefer-const reference tracking by @fansenze in #1626
- perf: optimize no-restricted-syntax matching by @fansenze in #1627
- perf: optimize no-restricted-globals by @fansenze in #1628
- perf: reuse normalized paths during config matching by @fansenze in #1629
- perf: optimize curly hot paths by @fansenze in #1631
- perf: optimize naming convention rule by @fansenze in #1632
- perf: share prepared lint plans by @fansenze in #1633
- perf: optimize no-explicit-any reporting by @fansenze in #1635
- perf(rstest): optimize no-commented-out-tests rule by @elecmonkey in #1634
- perf: optimize jsx-no-literals by @fansenze in #1636
- perf: cache directory block decisions by @fansenze in #1637
- perf: optimize no-array-index-key checks by @fansenze in #1640
- perf: optimize unicode-bom detection by @fansenze in #1641
- perf: optimize destructuring-assignment checks by @fansenze in #1642
- perf: optimize no-useless-assignment liveness by @fansenze in #1645
- perf: optimize no-unused-vars used bindings by @fansenze in #1644
- perf(jest,rstest): optimize no-conditional-expect rule by @elecmonkey in #1643
- perf: optimize no-deprecated lookups by @fansenze in #1646
- perf: optimize max-lines-per-function fast paths by @fansenze in #1647
- perf: optimize no-magic-numbers checks by @fansenze in #1648
- perf: optimize explicit member accessibility by @fansenze in #1649
- perf: optimize require-optimization traversal by @fansenze in #1650
- perf: optimize one-var scope tracking by @fansenze in #1651
- perf: optimize explicit function return type by @fansenze in #1653
- perf(rstest): optimize no-interpolation-in-snapshots rule and improve test call infrastructure by @elecmonkey in #1652
- perf: optimize prefer-destructuring checks by @fansenze in #1655
- perf: optimize member ordering checks by @fansenze in #1654
- perf: optimize max-params parameter checks by @fansenze in #1656
- perf: optimize no-param-reassign binding checks by @fansenze in #1657
- perf: optimize init-declarations reporting by @fansenze in #1658
- perf: optimize parameter properties by @fansenze in #1668
- perf: optimize no-non-null-assertion reporting by @fansenze in #1666
- perf(lsp): collect after a lint pass drops what it derived by @swwind in #1676
- perf(import): derive the cross-file structures once per program by @swwind in #1611
- perf(linter,rstest): introduce CachedByFile and share rstest's call-analysis across rules by @elecmonkey in #1690
Bug Fixes 🐞
- fix: align error-message static evaluation by @fansenze in #1579
- fix(prefer-for-of): count shorthand property uses of the loop index by @swwind in #1591
- fix(cfg): lay out a for statement's incrementor before its body by @swwind in #1588
- fix: resolve require() calls TypeScript never recorded by @swwind in #1577
- fix: resolve type-only heritage qualifiers in RefStore by @fansenze in #1607
- fix(typescript-eslint): align type specifier matching by @fansenze in #1609
- fix: align core function display names with ESLint by @fansenze in #1615
- fix(jest): correct accessor ranges in matcher chains by @elecmonkey in #1576
- fix: preserve type parameter comments by @fansenze in #1616
- fix: decode restrict-plus-operands options by @fansenze in #1618
- fix: stabilize main branch CI tests by @fansenze in #1620
- fix: mark prefer-optional-chain as type-aware by @fansenze in #1621
- fix(jest): preserve semantics in accessor edits by @elecmonkey in #1463
- fix: ignore interpolation in inline snapshot messages by @fansenze in #1623
- fix: harden rstest valid-title handling by @fansenze in #1624
- fix: prevent prefer-array-some panic and reduce listener work by @fansenze in #1639
- fix: align and optimize no-restricted-syntax by @fansenze in #1672
- fix: apply file language defaults by @fansenze in #1675
- fix: align no-undef TypeScript references by @fansenze in #1670
- fix(rstest): widen registration parsing for
no-disabled-testsandno-identical-titleby @elecmonkey in #1674 - fix: align no-redeclare TypeScript globals by @fansenze in #1682
- fix(prefer-optional-chain): align chain analysis with typescript-eslint by @swwind in #1679
- fix: align no-label-var TypeScript scopes by @fansenze in #1683
- fix: align no-shadow with upstream by @fansenze in #1689
Refactor 🔨
- refactor(typescript-eslint): match no-deprecated allow specifiers with the shared matcher by @swwind in #1598
- refactor: use project-local core in VS Code by @fansenze in #1617
- refactor: remove legacy rule options compatibility code by @swwind in #1667
- refactor: parse rule options by type assertion instead of JSON round-trips by @swwind in #1677
Document 📖
- docs(website): group documentation sidebars by @SoonIter in #1613
- docs: update port-rule option parsing guidance by @fansenze in #1673
- docs(unicorn): record each rule's aligned upstream version by @swwind in #1680
- docs(import): record each rule's aligned upstream version by @swwind in #1681
- docs(promise): record each rule's aligned upstream version by @swwind in #1684
- docs(jsx-a11y): record each rule's aligned upstream version by @swwind in #1686
- docs(react): record each rule's aligned upstream version by @swwind in #1687
- docs(eslint): record each core ESLint rule's aligned upstream version by @swwind in #1694
- docs(typescript): record each rule's aligned upstream version by @swwind in #1693
- docs(jest): record each rule's aligned upstream version by @swwind in #1692
Other Changes
- test(vscode): stabilize parent-ignore catalog regression by @fansenze in #1592
- test: build the no-undef nil-checker program from the embedded fixtures root by @swwind in #1596
- test: pass the process cwd to lintSingleFile in the unicode-bom test by @swwind in #1599
- ci: increase Windows Go package parallelism to 32 by @fansenze in #1622
- chore(deps): update dependency memfs to ^4.68.0 by @renovate[bot] in #1661
- chore(deps): update dependency @types/node to ^26.2.0 by @renovate[bot] in #1660
- chore(deps): update dependency swr to ^2.5.0 by @renovate[bot] in #1662
- chore(deps): update module golang.org/x/tools to v0.48.0 by @renovate[bot] in #1664
- chore(deps): update rust crate insta to 1.48.0 by @renovate[bot] in #1665
- test: resolve rule source paths under -trimpath builds by @swwind in #1669
- chore: publish tsgo independently by @fansenze in #1699
- ci: prepare wasm artifacts for npm release by @fansenze in #1691
Full Changelog: v0.7.3...v0.8.0