Configuration
Rslint uses a flat config format (an array of config entries), aligned with ESLint v10. JS/TS configuration files are the recommended approach.
Configuration Files
During automatic discovery, Rslint checks config files in the following order:
rslint.config.jsrslint.config.mjsrslint.config.tsrslint.config.mts
Automatic discovery does not consider .cjs or .cts config files. They can
still be selected explicitly with --config or API overrideConfigFile.
Config Discovery
When you run rslint, it searches for a config file by walking upward from the target file or directory to the filesystem root. It uses the nearest candidate that loads successfully and falls back to an ancestor when a nearer candidate cannot be loaded.
rslint src/foo.ts— searches fromsrc/upwardrslint src/— searches fromsrc/upwardrslint(no args) — searches from the current working directory upward
In a monorepo, different files can automatically use different config files based on their location:
When linting from the monorepo root, rslint automatically discovers all nested configs and applies the nearest one to each file.
Global Ignores and Nested Configs
For directory or no-argument lint runs, global ignores in a parent config prevent nested configs in ignored directories from contributing lint targets.
With this config, a rslint.config.ts inside e2e/ or any fixtures/ directory is not used by a root directory traversal. An explicitly named file is still resolved from its nearest config, matching the explicit-target behavior described below.
Only global ignore entries (entries with only ignores and an optional name) block directory target discovery. Entry-level ignores do not affect config discovery.
You can also specify a config file explicitly (overrides automatic discovery):
For automatically discovered configs, relative files, ignores, and languageOptions.parserOptions.project patterns are resolved from the config file's directory.
For a config supplied with --config, those patterns are resolved from the current working directory.
To generate a default config, run:
Basic Configuration
A typical TypeScript project configuration:
When using both JavaScript and TypeScript recommended presets, place js.configs.recommended before ts.configs.recommended. The TypeScript preset disables ESLint core rules that are handled by TypeScript-aware rules, and later config entries override earlier ones.
For available presets, rule severity, and plugin configuration, see Rules & Presets.
Configuration Options
files
- Type:
(string | string[])[]
Glob selectors specifying which files this config entry applies to. Top-level selectors are ORed. Patterns in a nested array are ANDed, so files: [['**/*.js', '!**/*.test.js']] selects JavaScript files except test files. If omitted, the entry cascades across files selected by the config's implicit or explicit selectors.
If files is present, its outer array must be non-empty. Use an omitted files field for shared/default entries; files: [] is invalid. A nested empty AND group (files: [[]]) is valid and matches vacuously.
Lint targets are selected from the CLI/API target range and are limited to Rslint's supported script extensions. Rslint always includes its default extension baseline and adds other supported candidates selected by explicit files entries unless the same entry's ignores excludes them. A files selector cannot make an unsupported source extension lintable. Global ignores then remove targets; CLI and JavaScript API runs also apply .gitignore. An entry-level ignore cannot remove a path selected by the baseline or another entry; it only prevents its own selector and config contribution. Every selected target is parsed even when no config entry contributes rules, so syntax diagnostics can still be reported. This includes default-baseline files found by a directory or no-argument scan and explicitly requested supported files that do not match a config entry's files.
The implicit default baseline is:
.js.mjs.cjs.jsx.ts.tsx.mts.cts
This is independent of tsconfig's include: a file in tsconfig but outside rslint's lint target set will not run lint rules, while a selected file not covered by a tsconfig declared by its governing config still runs rules that do not require type information.
Selected files not covered by a tsconfig declared by their governing config automatically receive a reduced rule set: only rules that do not require type information run. To enable type-aware rules, add the file to one of that config's tsconfigs.
ignores
For file exclusion patterns, negation, and .gitignore integration, see Ignoring Files.
rules
- Type:
RuleSeverity | [RuleSeverity, ...unknown[]] - RuleSeverity:
'off' | 'warn' | 'error' | 0 | 1 | 2
The numeric levels follow ESLint: 0 disables a rule, 1 reports warnings, and 2 reports errors. Array entries pass every item after the severity to the rule as positional options, so configurations such as ['error', 'always', { exceptRange: true }] are supported. Invalid severities and rule value shapes are rejected while the configuration is loaded.
When a later matching entry changes only the severity, the rule keeps options from the earlier entry. Supplying any positional option in the later array replaces the earlier options.
For available rules, presets, and plugin configuration, see Rules & Presets.
plugins
- Type:
string[] | Record<string, ESLintPlugin>
Plugins enabled for this entry, in one of two forms.
Array of names — built-in (native) plugins. A name declares a rule namespace; its rules become available under the <plugin>/<rule> prefix inside rules.
Built-in plugin names: @typescript-eslint, import, jest, jsx-a11y, promise, react, react-hooks, rstest, unicorn.
Object of plugin instances — third-party ESLint plugins. Map a prefix key to an imported plugin object, then enable its rules under the <prefix>/<rule> namespace. These JavaScript rules run in the Node plugin worker and are routed through the same per-file flat config as native rules. This form requires a JS/TS config because JSON cannot carry a live plugin object.
A single entry uses one form. To combine built-in and third-party plugins, declare them in separate config entries; matching entries are merged before linting. A third-party prefix may not collide with a built-in plugin name.
ESLint core rules (unprefixed names like no-unused-vars or prefer-const) are not part of any plugin and can be enabled directly in rules without listing anything here. Presets like ts.configs.recommended already include their own plugins entry, so you only need this field when configuring plugin rules outside a preset.
See ESLint plugin compatibility for the supported and unsupported ESLint APIs.
languageOptions
- Type:
object
languageOptions.ecmaVersion
- Type:
number | 'latest' - Default:
'latest'
Selects the standard ECMAScript globals exposed to native rules. Accepted numbers match ESLint/Espree: 3, 5, edition aliases 6 through 17, or years 2015 through 2026. Edition aliases are normalized to their year (6 is ES2015 and 17 is ES2026). The 'latest' value remains semantic rather than being frozen into the config, so it follows the ESLint version targeted by rslint. This option currently selects globals; it does not change TypeScript's parser target.
languageOptions.parserOptions.projectService
- Type:
boolean
Enable TypeScript's project service for automatic tsconfig discovery. This is the default in ts.configs.recommended.
languageOptions.parserOptions.project
- Type:
string | string[]
Explicit tsconfig.json paths. Supports glob patterns for monorepos. Files included by these tsconfigs receive full type information, enabling type-aware rules (e.g. @typescript-eslint/no-floating-promises, @typescript-eslint/await-thenable). Files outside all tsconfigs are still linted, but only rules that do not require type information run.
languageOptions.globals
- Type:
Record<string, boolean | null | 'true' | 'false' | 'readonly' | 'readable' | 'writable' | 'writeable' | 'off'>
Declares globals available to matching files. Values are normalized before rules or third-party plugins receive the scope:
- Writable:
true,'true','writable','writeable' - Read-only:
false,null,'false','readonly','readable' - Disabled:
'off'
A disabled value removes a declaration inherited from an earlier matching entry, including an ECMAScript built-in. The read-only and writable levels are distinct wherever a rule acts on assignment: no-global-assign reports writes to a read-only global and allows them on a writable one.
ECMAScript built-ins are declared according to languageOptions.ecmaVersion (Array from ES3, Promise from ES2015, and so on). Globals a runtime adds on top of those — window and document in a browser, process and __dirname in Node.js — are not enabled by default. @rslint/core includes the globals catalog and exports its environment maps directly, so no extra dependency is required:
The export has the same set names, global names, and boolean access values as importing the npm package directly: false means read-only and true means writable. In the published package, each set is synchronously loaded and cached the first time its property is read, so importing @rslint/core does not parse the complete catalog. Compose multiple environments with ordinary object spreads; later spreads and explicit properties take precedence:
globals.node includes the CommonJS globals (require, module, exports, __dirname, and __filename); use globals.nodeBuiltin for Node.js ESM files that should not receive them. The included catalog also exposes the upstream builtin, es3, es5, and es20xx maps for API parity, but languageOptions.ecmaVersion is the preferred way to select standard-language globals because it keeps parsing and both rule runtimes on the same edition.
Every map is an explicit globals declaration. It does not change the parser edition, and it can intentionally override the edition-derived set. For example, an upstream host map containing Temporal declares that name even when ecmaVersion is 2025. Loaded maps are shared and cached, so compose and override them with object spreads instead of mutating globals.browser or another map in place. Enumerating only Object.keys(globals) remains lazy; reading or spreading the complete globals object necessarily loads every map.
Flat config continues to merge individual global names in matching-entry order. Scope environment maps with files, and use a later explicit { process: 'off' } when one inherited global must be removed.
TypeScript's compiler and type-aware rules can resolve declarations from lib.dom.d.ts, @types/node, and project .d.ts files. ESLint-compatible global rules such as no-undef and no-global-assign intentionally use the flat config's globals instead of TypeScript ambient declarations. The TypeScript presets disable no-undef; if you enable such a global rule for TypeScript files, configure their runtime environments too.
settings
- Type:
Record<string, unknown>
Shared settings accessible to all rules. Ordinary nested objects are merged recursively; later arrays and scalar values replace earlier values.
Config Merging
When multiple config entries match a file, they are merged in array order:
- Global ignores — entries containing only
ignoresand an optionalnameremove files from the target set - Selector union — the implicit default baseline and effective explicit
filesentries decide whether the config selects the file - Files matching — entries whose explicit
filespatterns don't match are skipped; entries withoutfilescascade across the selector union - Entry-level ignores — matching entries do not select or configure the file, but cannot remove a target selected elsewhere
- Rules — later entries override earlier ones; a severity-only value retains earlier options
- Plugins — union from all matching entries
- Settings — ordinary nested objects merge recursively; arrays and scalar values are replaced
- Language options — ordinary nested objects merge recursively; arrays and scalar values are replaced
If no entry matches a selected file, no lint rules run for it, but the file is still parsed and included in the result so parser diagnostics remain visible. This applies to default-baseline files found during directory discovery as well as explicitly requested supported files. Global ignores remove matching targets; CLI and JavaScript API runs apply .gitignore as an additional global ignore source.
JSON Configuration (Deprecated)
JSON config files (rslint.json, rslint.jsonc) are deprecated and will be removed in a future version. Run rslint --init to automatically migrate your JSON config to a JS/TS config. The migration preserves your custom rules and settings while deduplicating rules already covered by recommended presets.
Key difference: JSON configs automatically enable all core rules and declared plugin rules as "error". JS/TS configs only enable rules explicitly declared in presets or the rules field.