--- url: /sponsor.md --- # 🌟 Become an Oxc Sponsor ## 🤝 How to Sponsor You can sponsor us on [GitHub Sponsors](https://github.com/sponsors/oxc-project) or [OpenCollective](https://opencollective.com/oxc). ## 💚 Why sponsor? Sponsorship lets us keep improving the JavaScript and Rust ecosystems without burning out. Everything we receive on OpenCollective is paid out to core team members who are not part of [VoidZero](https://voidzero.dev). As a sponsor, your avatar is displayed across all [oxc-project repositories](https://github.com/oxc-project) and on the [landing page](/) of this website. If our work has improved your development experience, your CI pipelines, your build times, or your learning, please consider sponsoring. It helps more than you might think, and it keeps the motivation alive. ## Current Sponsors --- --- url: /docs/learn/parser_in_rust/ast.md --- # AST The parser in the upcoming chapter is responsible for turning Tokens into an abstract syntax tree (AST). It is much nicer to work on the AST compared to the source text. All JavaScript toolings work on the AST level, for example: * A linter (e.g. ESLint) checks the AST for errors * A formatter (e.g.prettier) prints the AST back to JavaScript text * A minifier (e.g. terser) transforms the AST * A bundler connects all import and export statements between ASTs from different files In this chapter, let's construct a JavaScript AST by using Rust structs and enums. ## Getting familiar with the AST To get ourselves comfortable with an AST, let's visit [ASTExplorer](https://astexplorer.net/) and see what it looks like. On the top panel, select JavaScript, and then `acorn`, type in `var a` and we will see a tree view and a JSON view. ```json { "type": "Program", "start": 0, "end": 5, "body": [ { "type": "VariableDeclaration", "start": 0, "end": 5, "declarations": [ { "type": "VariableDeclarator", "start": 4, "end": 5, "id": { "type": "Identifier", "start": 4, "end": 5, "name": "a" }, "init": null } ], "kind": "var" } ], "sourceType": "script" } ``` Since this is a tree, every object is a node with a type name (e.g. `Program`, `VariableDeclaration`, `VariableDeclarator`, `Identifier`). `start` and `end` are the offsets from the source. ## estree [estree](https://github.com/estree/estree) is a community standard grammar specification for JavaScript, it defines [all the AST nodes](https://github.com/estree/estree/blob/master/es5.md) so different tools can be compatible with each other. The basic building block for any AST node is the `Node` type: ```rust #[derive(Debug, Default, Clone, Copy, Serialize, PartialEq, Eq)] pub struct Node { /// Start offset in source pub start: usize, /// End offset in source pub end: usize, } impl Node { pub fn new(start: usize, end: usize) -> Self { Self { start, end } } } ``` AST for `var a` is defined as ```rust pub struct Program { pub node: Node, pub body: Vec, } pub enum Statement { VariableDeclarationStatement(VariableDeclaration), } pub struct VariableDeclaration { pub node: Node, pub declarations: Vec, } pub struct VariableDeclarator { pub node: Node, pub id: BindingIdentifier, pub init: Option, } pub struct BindingIdentifier { pub node: Node, pub name: String, } pub enum Expression { } ``` Rust does not have inheritance, so `Node` is added to each struct (this is called "composition over Inheritance"). `Statement`s and `Expression`s are enums because they will be expanded with a lot of other node types, for example: ```rust pub enum Expression { AwaitExpression(AwaitExpression), YieldExpression(YieldExpression), } pub struct AwaitExpression { pub node: Node, pub expression: Box, } pub struct YieldExpression { pub node: Node, pub expression: Box, } ``` The `Box` is needed because self-referential structs are not allowed in Rust. :::info JavaScript grammar has a lot of nuisances, read the [grammar tutorial](/docs/learn/ecmascript/grammar.html) for amusement. ::: ## Rust Optimizations ### Memory Allocations We need to look out for heap-allocated structs such as `Vec` and `Box` because heap allocations are not cheap. Take a look at the [real world implementation from swc](https://github.com/swc-project/swc/blob/main/crates/swc_ecma_ast/src/expr.rs), we can see that an AST can have lots of `Box`s and `Vec`s, and also note that the `Statement` and `Expression` enums contain a dozen of enum variants. ### Memory Arena Using the global memory allocator for the AST is actually not really efficient. Every `Box` and `Vec` are allocated on demand and then dropped separately. What we would like to do is pre-allocate memory and drop it in wholesale. :::info See also [Arenas in Rust](https://manishearth.github.io/blog/2021/03/15/arenas-in-rust) and [Flattening ASTs](https://www.cs.cornell.edu/~asampson/blog/flattening.html) for more background on storing ASTs in memory arenas. ::: [`bumpalo`](https://docs.rs/bumpalo/latest/bumpalo/) is a very good candidate for our use case, according to its documentation: > Bump allocation is a fast, but limited approach to allocation. > We have a chunk of memory, and we maintain a pointer within that memory. Whenever we allocate an object, > we do a quick check that we have enough capacity left in our chunk to allocate the object and then update the pointer by the object’s size. That’s it! > > The disadvantage of bump allocation is that there is no general way to deallocate individual objects or reclaim the memory region for a no-longer-in-use object. > > These trade offs make bump allocation well-suited for phase-oriented allocations. That is, a group of objects that will all be allocated during the same program phase, used, and then can all be deallocated together as a group. By using `bumpalo::collections::Vec` and `bumpalo::boxed::Box`, our AST will have lifetimes added to it: ```rust use bumpalo::collections::Vec; use bumpalo::boxed::Box; pub enum Expression<'a> { AwaitExpression(Box<'a, AwaitExpression>), YieldExpression(Box<'a, YieldExpression>), } pub struct AwaitExpression<'a> { pub node: Node, pub expression: Expression<'a>, } pub struct YieldExpression<'a> { pub node: Node, pub expression: Expression<'a>, } ``` :::info Please be cautious if we are not comfortable dealing with lifetimes at this stage. Our program will work fine without a memory arena. Code in the following chapters does not demonstrate the use of a memory arena for simplicity. ::: ### Enum Size The first optimization we are going to make is to reduce the size of the enums. It is known that the byte size of a Rust enum is the union of all its variants. For example, the following enum will take up 56 bytes (1 byte for the tag, 48 bytes for the payload, and 8 bytes for alignment). ```rust enum Name { Anonymous, // 0 byte payload Nickname(String), // 24 byte payload FullName{ first: String, last: String }, // 48 byte payload } ``` :::info This example is taken from [this blog post](https://adeschamps.github.io/enum-size) ::: As for the `Expression` and `Statement` enums, they can take up to more than 200 bytes with our current setup. These 200 bytes need to be passed around, or accessed every time we do a `matches!(expr, Expression::AwaitExpression(_))` check, which is not very cache friendly for performance. A better approach would be to box the enum variants and only carry 16 bytes around. ```rust pub enum Expression { AwaitExpression(Box), YieldExpression(Box), } pub struct AwaitExpression { pub node: Node, pub expression: Expression, } pub struct YieldExpression { pub node: Node, pub expression: Expression, } ``` To make sure the enums are indeed 16 bytes on 64-bit systems, we can use `std::mem::size_of`. ```rust #[test] fn no_bloat_enum_sizes() { use std::mem::size_of; assert_eq!(size_of::(), 16); assert_eq!(size_of::(), 16); } ``` "no bloat enum sizes" test cases can often be seen in the Rust compiler source code for ensuring small enum sizes. ```rust // https://github.com/rust-lang/rust/blob/9c20b2a8cc7588decb6de25ac6a7912dcef24d65/compiler/rustc_ast/src/ast.rs#L3033-L3042 // Some nodes are used a lot. Make sure they don't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] mod size_asserts { use super::*; use rustc_data_structures::static_assert_size; // These are in alphabetical order, which is easy to maintain. static_assert_size!(AssocItem, 160); static_assert_size!(AssocItemKind, 72); static_assert_size!(Attribute, 32); static_assert_size!(Block, 48); ``` To find other large types, we can run ```bash RUSTFLAGS=-Zprint-type-sizes cargo +nightly build -p name_of_the_crate --release ``` and see ``` print-type-size type: `ast::js::Statement`: 16 bytes, alignment: 8 bytes print-type-size discriminant: 8 bytes print-type-size variant `BlockStatement`: 8 bytes print-type-size field `.0`: 8 bytes print-type-size variant `BreakStatement`: 8 bytes print-type-size field `.0`: 8 bytes print-type-size variant `ContinueStatement`: 8 bytes print-type-size field `.0`: 8 bytes print-type-size variant `DebuggerStatement`: 8 bytes print-type-size field `.0`: 8 bytes ``` ## JSON Serialization [serde](https://serde.rs/) can be used serialize the AST to JSON. Some techniques are needed to make it `estree` compatible. Here are some examples: ```rust use serde::Serialize; #[derive(Debug, Clone, Serialize, PartialEq)] #[serde(tag = "type")] #[cfg_attr(feature = "estree", serde(rename = "Identifier"))] pub struct IdentifierReference { #[serde(flatten)] pub node: Node, pub name: Atom, } #[derive(Debug, Clone, Serialize, PartialEq, Hash)] #[serde(tag = "type")] #[cfg_attr(feature = "estree", serde(rename = "Identifier"))] pub struct BindingIdentifier { #[serde(flatten)] pub node: Node, pub name: Atom, } #[derive(Debug, Serialize, PartialEq)] #[serde(untagged)] pub enum Expression<'a> { ... } ``` * `serde(tag = "type")` is used to make the struct name a "type" field, i.e. `{ "type" : "..." }` * `cfg_attr` + `serde(rename)` is used to rename different struct names to the same name, since `estree` does not distinguish different identifiers * `serde(untagged)` on the enum is used to not create an extra JSON object for the enum --- --- url: /docs/contribute/linter/adding-rules.md --- # Adding Linter Rules The best and easiest way to contribute to Oxlint is by adding new linter rules. This guide will walk you through this process, using ESLint's [`no-debugger`](https://eslint.org/docs/latest/rules/no-debugger) rule as an example. :::tip Make sure you've read the [setup instructions](../development.md) first. ::: ## Step 1: Pick a Rule Our [Linter product plan and progress](https://github.com/oxc-project/oxc/issues/481) issue tracks the status of all rules we want to implement from existing ESLint plugins. From there, pick a plugin that looks interesting to you and find a rule that has not been implemented. **Important**: Since ESLint-compatible JavaScript plugin support is now available, we do not plan to add new Rust-based plugins. However, contributions that add rules to existing plugins are **highly encouraged**. If you think a rule or plugin would benefit from being written in rust, please open a discussion first, before making a pull request. Most documentation pages for ESLint rules include a link to the rule's [source code](https://eslint.org/docs/latest/rules/no-debugger#resources). Using this as a reference will help you with your implementation. ## Step 2: Rule Generation Next, run the rulegen script to generate boilerplate code for your new rule. ```bash just new-rule no-debugger ``` This will: 1. Create a new file in `crates/oxc_linter/src/rules//.rs` with the start of your rule's implementation and all test cases ported from ESLint 2. Register the rule in the appropriate `mod` in [`rules.rs`](https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rules.rs) 3. Add the rule to `oxc_macros::declare_all_lint_rules!` For rules that are part of a different plugin, you'll need to use that plugin's own rulegen script. :::tip Run `just` with no arguments to see all available commands. ::: ```bash just new-rule [name] # for eslint core rules just new-jest-rule [name] # for eslint-plugin-jest just new-ts-rule [name] # for @typescript-eslint/eslint-plugin just new-unicorn-rule [name] # for eslint-plugin-unicorn just new-import-rule [name] # for eslint-plugin-import just new-react-rule [name] # for eslint-plugin-react and eslint-plugin-react-hooks just new-jsx-a11y-rule [name] # for eslint-plugin-jsx-a11y just new-oxc-rule [name] # for oxc's own rules just new-nextjs-rule [name] # for eslint-plugin-next just new-jsdoc-rule [name] # for eslint-plugin-jsdoc just new-react-perf-rule [name] # for eslint-plugin-react-perf just new-n-rule [name] # for eslint-plugin-n just new-promise-rule [name] # for eslint-plugin-promise just new-vitest-rule [name] # for eslint-plugin-vitest ``` The generated file will look something like this: ::: code-group ````rust [rules/eslint/no_debugger.rs] use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; use crate::{ context::LintContext, fixer::{RuleFix, RuleFixer}, rule::Rule, AstNode, }; #[derive(Debug, Default, Clone)] pub struct NoDebugger; declare_oxc_lint!( /// ### What it does /// /// /// ### Why is this bad? /// /// /// ### Examples /// /// Examples of **incorrect** code for this rule: /// ```js /// FIXME: Tests will fail if examples are missing or syntactically incorrect. /// ``` /// /// Examples of **correct** code for this rule: /// ```js /// FIXME: Tests will fail if examples are missing or syntactically incorrect. /// ``` NoDebugger, nursery, // TODO: change category to `correctness`, `suspicious`, `pedantic`, `perf`, `restriction`, or `style` // See for details pending // TODO: describe fix capabilities. Remove if no fix can be done, // keep at 'pending' if you think one could be added but don't know how. // Options are 'fix', 'fix_dangerous', 'suggestion', and 'conditional_fix_suggestion' ); impl Rule for NoDebugger { fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) {} } #[test] fn test() { use crate::tester::Tester; let pass = vec!["var test = { debugger: 1 }; test.debugger;"]; let fail = vec!["if (foo) debugger"]; Tester::new(NoDebugger::NAME, pass, fail).test_and_snapshot(); } ```` ::: Your rule should now be ready to run! You can try it out with `cargo test -p oxc_linter`. The tests should fail, since you haven't implemented the rule yet. ## Step 3: Fill Out the Template ### Documentation Fill out the various documentation sections. * Provide a clear and concise summary of what the rule does. * Explain why the rule is important and what undesirable behavior it prevents. * Provide examples of code that violates the rule and code that does not. Remember, we use this documentation to generate the [rule documentation pages](/docs/guide/usage/linter/rules) for this website, so make sure your documentation is clear and helpful! #### Configuration Documentation If your rule has configuration options, you will need to document them. You should do so via the system for auto-generating documentation. This should be partially generated for you automatically by the rulegen script. Each configuration option should be defined by adding fields to the rule's struct: ```rust pub struct RuleName { option_name: bool, another_option: String, yet_another_option: Vec, } ``` Alternatively, you can instead define a separate `Config` struct to hold all configuration options: ```rust pub struct RuleName(Box); pub struct RuleNameConfig { option_name: bool, } ``` The configuration options should have `JsonSchema` derived for them and also a serde decoration, like so: ```rust use schemars::JsonSchema; #[derive(Debug, Default, Clone, JsonSchema)] #[serde(rename_all = "camelCase", default)] pub struct RuleName { option_name: bool, } ``` Add documentation comments (`///`) to each field to describe the option, for example: ```rust use schemars::JsonSchema; #[derive(Debug, Default, Clone, JsonSchema)] #[serde(rename_all = "camelCase", default)] pub struct RuleName { /// Whether to check for foo and bar when evaluating baz. /// The comment can be as long as you need to fully describe the option. option_name: bool, } ``` The default value and the type of each option will be automatically extracted from the struct definition, and should not be mentioned in the documentation comments. See [this issue](https://github.com/oxc-project/oxc/issues/14743) for dozens of examples of how to properly document configuration options in all kinds of rules. You can view the generated documentation by running `cargo run -p website -- linter-rules --rule-docs target/rule-docs --git-ref $(git rev-parse HEAD)` and then opening `target/rule-docs//.md`. ### Rule Category First, pick a [rule category](../linter.md#rule-category) that best fits the rule. Remember that `correctness` rules will be run by default, so be careful when choosing this category. Set your category within the `declare_oxc_lint!` macro. ### Fixer Status If the rule has a fixer, register what kind of fixes it provides within `declare_oxc_lint!`. If you're not comfortable with implementing a fixer, you can also use `pending` as a placeholder. This helps other contributors find and implement missing fixers down the line. ### Diagnostics Create a function to create diagnostics for rule violations. Follow these principles: 1. The `message` should be an imperative statement about what is wrong, not a description of what the rule does. 2. The `help` message should be a command-like statement that tells the user how to fix the issue. ::: code-group ```rust [good] fn no_debugger_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("`debugger` statement is not allowed") .with_help("Remove this `debugger` statement") .with_label(span) } ``` ```rust [bad] fn no_debugger_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("Disallow `debugger` statements") .with_help("`debugger` statements are not allowed.") .with_label(span) ``` ::: ## Step 4: Rule Implementation Read the rule's source code to understand how it works. Although Oxlint works similarly to ESLint, it is unlikely that the rule can be ported directly. ESLint rules have a `create` function that returns an object whose keys are AST nodes that trigger the rule and values are functions that run lints on those nodes. Oxlint rules run on one of a few triggers, each of which come from the [`Rule`](https://github.com/oxc-project/oxc/blob/main/crates/oxc_linter/src/rule.rs) trait: 1. Run on each AST node (via `run`) 2. Run on each symbol (via `run_on_symbol`) 3. Run a single time on the entire file (via `run_once`) In the case of `no-debugger`, we are looking for `DebuggerStatement` nodes, so we'll use `run`. Here's a simplified version of the rule: ::: code-group ````rust [rules/eslint/no_debugger.rs] use oxc_ast::AstKind; use oxc_diagnostics::OxcDiagnostic; use oxc_macros::declare_oxc_lint; use oxc_span::Span; use crate::{context::LintContext, rule::Rule, AstNode}; fn no_debugger_diagnostic(span: Span) -> OxcDiagnostic { OxcDiagnostic::warn("`debugger` statement is not allowed") .with_label(span) } #[derive(Debug, Default, Clone)] pub struct NoDebugger; declare_oxc_lint!( /// ### What it does /// Checks for usage of the `debugger` statement /// /// ### Why is this bad? /// `debugger` statements do not affect functionality when a /// debugger isn't attached. They're most commonly an /// accidental debugging leftover. /// /// ### Example /// /// Examples of **incorrect** code for this rule: /// ```js /// async function main() { /// const data = await getData(); /// const result = complexCalculation(data); /// debugger; /// } /// ``` NoDebugger, correctness ); impl Rule for NoDebugger { // Runs on each node in the AST fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { // `debugger` statements have their own AST kind if let AstKind::DebuggerStatement(stmt) = node.kind() { // Report a violation ctx.diagnostic(no_debugger_diagnostic(stmt.span)); } } } ```` ::: :::tip You will want to get familiar with the data stored in [`Semantic`](https://github.com/oxc-project/oxc/blob/main/crates/oxc_semantic/src/lib.rs#L59), which is where all data extracted during semantic analysis is stored. You will also want to familiarize yourself with the AST structure. The two most important data structures here are [`AstNode`](https://github.com/oxc-project/oxc/blob/main/crates/oxc_semantic/src/node/mod.rs) and [`AstKind`](https://github.com/oxc-project/oxc/blob/main/crates/oxc_ast/src/generated/ast_kind.rs) ::: ## Step 5: Testing To test your rule whenever you make a change, run: ```bash just watch "cargo test -p oxc_linter -- rule-name" ``` Or to just test it once, run: ```bash cargo test -p oxc_linter -- rule-name # Or cargo insta test -p oxc_linter -- rule-name ``` Oxlint uses [`cargo insta`](https://insta.rs/docs) for snapshot testing. `cargo test` will fail if snapshots have changed or have just been created. You can run `cargo insta test -p oxc_linter` to not see diffs in your test results. You can review the snapshots by running `cargo insta review`, or skip the review and just accept all changes using `cargo insta accept`. When you are ready to submit your PR, run `just ready` or `just r` to run CI checks locally. You can also run `just fix` to auto-fix any lint, format, or typo problems. Once `just ready` is passing, create a PR and a maintainer will review your changes. ## General Advice ### Pin point the error message to the shortest code span We want the user to focus on the problematic code rather than deciphering the error message to identify which part of the code is erroneous. ### Use `let-else` statements If you find yourself deeply nesting [`if-let`](https://doc.rust-lang.org/rust-by-example/flow_control/if_let.html) statements, consider using [`let-else`](https://doc.rust-lang.org/rust-by-example/flow_control/let_else.html) instead. :::tip CodeAesthetic's [never-nesting video](https://www.youtube.com/watch?v=CFRhGnuXG-4) explains this concept in more detail. ::: ::: code-group ```rust [good] // let-else is easier to read fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { let AstKind::JSXOpeningElement(jsx_opening_elem) = node.kind() else { return; }; let Some(expr) = container.expression.as_expression() else { return; }; let Expression::BooleanLiteral(expr) = expr.without_parenthesized() else { return; }; // ... } ``` ```rust [bad] // deep nesting is hard to read fn run<'a>(&self, node: &AstNode<'a>, ctx: &LintContext<'a>) { if let AstKind::JSXOpeningElement(jsx_opening_elem) = node.kind() { if let Some(expr) = container.expression.as_expression() { if let Expression::BooleanLiteral(expr) = expr.without_parenthesized() { // ... } } } } ``` ::: ### Use `CompactStr` where possible Reducing allocations as much as possible is critical for performance in `oxc`. The `String` type requires allocating memory on the heap, which costs memory and CPU cycles. It is possible to [store small strings inline](https://oxc.rs/docs/learn/performance.html#string-inlining) (up to 24 bytes on 64-bit systems) on the stack using `CompactStr`, which means we don't need to allocate memory. If the string is too large to store inline, it will allocate the necessary space. Using `CompactStr` can be used almost anywhere that has the type `String` or `&str`, and can save a significant amount memory and CPU cycles compared to the `String` type. ::: code-group ```rust [good] struct Element { name: CompactStr } let element = Element { name: "div".into() }; ``` ```rust [bad] struct Element { name: String } let element = Element { name: "div".to_string() }; ``` ::: --- --- url: /docs/guide/benchmarks.md --- # All Benchmarks ## Parser Oxc's parser is at least 3x faster than swc and 5x faster than Biome. Please note that it is not an apple-to-apple comparison with Biome. Biome's parser [produces a CST](https://biomejs.dev/internals/architecture) instead of an AST, which requires a lot more work. See repository [bench-javascript-parser-written-in-rust](https://github.com/oxc-project/bench-javascript-parser-written-in-rust). ## Transformer * Compared to swc, oxc transformer is 4x faster, uses 20% less memory, and is 35 MB smaller in package size (from swc's 37MB). * Compared to babel, oxc transformer is 40x faster, uses 70% less memory, and is 19 MB smaller with 168 npm packages less to install. See repository [bench-transformer](https://github.com/oxc-project/bench-transformer). ## Linter Oxlint is 50x - 100x faster than ESLint depending on the number of CPU cores. See repository [bench-javascript-linter](https://github.com/oxc-project/bench-javascript-linter). ## Formatter Oxfmt is 3x faster than Biome, 35x faster than prettier. See repository [bench-formatter](https://github.com/oxc-project/bench-formatter). ## Resolver `oxc-resolver` is 30x faster than webpack's `enhanced-resolve`. See repository [bench-resolver](https://github.com/oxc-project/bench-resolver). --- --- url: /docs/contribute/parser/ast.md --- # Abstract Syntax Tree (AST) The Oxc AST is the foundation of all Oxc tools. Understanding its structure and how to work with it is essential for contributing to parser, linter, transformer, and other components. ## AST Architecture ### Design Principles The Oxc AST is designed with the following principles: 1. **Performance First**: Optimized for speed and memory efficiency 2. **Type Safety**: Leverages Rust's type system to prevent common errors 3. **Spec Compliance**: Closely follows ECMAScript specification 4. **Clear Semantics**: Removes ambiguity present in other AST formats ## Working with the AST ### Generate AST Related Code When you modify AST definitions, run the code generation tool: ```bash just ast ``` This generates: * **Visitor patterns**: For traversing the AST * **Builder methods**: For constructing AST nodes * **Trait implementations**: For common operations * **TypeScript types**: For Node.js bindings ### AST Node Structure Every AST node follows a consistent pattern: ```rust #[ast(visit)] pub struct FunctionDeclaration<'a> { pub span: Span, pub id: Option>, pub generator: bool, pub r#async: bool, pub params: FormalParameters<'a>, pub body: Option>, pub type_parameters: Option>, pub return_type: Option>, } ``` Key components: * **`span`**: Source location information * **`#[ast(visit)]`**: Generates visitor methods * **Lifetime `'a`**: References to arena-allocated memory ### Memory Management The AST uses a memory arena for efficient allocation: ```rust use oxc_allocator::Allocator; let allocator = Allocator::default(); let ast = parser.parse(&allocator, source_text, source_type)?; ``` Benefits: * **Fast allocation**: No individual malloc calls * **Fast deallocation**: Drop entire arena at once * **Cache friendly**: Linear memory layout * **No reference counting**: Simple lifetime management ## AST Traversal ### Visitor Pattern Use the generated visitor for AST traversal: ```rust use oxc_ast::visit::{Visit, walk_mut}; struct MyVisitor; impl<'a> Visit<'a> for MyVisitor { fn visit_function_declaration(&mut self, func: &FunctionDeclaration<'a>) { println!("Found function: {:?}", func.id); walk_mut::walk_function_declaration(self, func); } } // Usage let mut visitor = MyVisitor; visitor.visit_program(&program); ``` ### Mutable Visitor `VisitMut` can be used to modify the AST during traversal. For example, to transform binary addition of string literals into a single string literal: ```rust use oxc_ast::AstBuilder; use oxc_ast_visit::{VisitMut, walk_mut}; use oxc_str::Str; struct MyTransformer<'a> { pub builder: &'a AstBuilder<'a>, } impl<'a> VisitMut<'a> for MyTransformer<'a> { fn visit_expression(&mut self, expr: &mut Expression<'a>) { // Detect the expression type which you want to modify when changing from one enum variant to another. if let Expression::BinaryExpression(bin_expr) = expr && let ( BinaryOperator::Addition, Expression::StringLiteral(sl), Expression::StringLiteral(sr), ) = (bin_expr.operator, &bin_expr.left, &bin_expr.right) { let value = Str::from_strs_array_in( [sl.value.as_str(), sr.value.as_str()], self.builder.allocator, ); *expr = self.builder.expression_string_literal(SPAN, value, None); } walk_mut::walk_expression(self, expr); } } ``` For example, to modify a binary expression without changing its type: ```rust use oxc_ast::AstBuilder; use oxc_ast_visit::{VisitMut, walk_mut}; struct MyTransformer<'a> { pub builder: &'a AstBuilder<'a>, } impl<'a> VisitMut<'a> for MyTransformer<'a> { fn visit_binary_expression(&mut self, expr: &mut BinaryExpression<'a>) { if expr.operator == BinaryOperator::Addition { // Modify the AST node. You can modify only left/right and operator parts, not the type of expression itself. } walk_mut::walk_binary_expression(self, expr); } } ``` ## AST Construction ### Builder Pattern Use the AST builder for creating nodes: ```rust use oxc_ast::AstBuilder; let ast = AstBuilder::new(&allocator); // Create a binary expression: a + b let left = ast.expression_identifier_reference(SPAN, "a"); let right = ast.expression_identifier_reference(SPAN, "b"); let expr = ast.expression_binary_expression( SPAN, left, BinaryOperator::Addition, right, ); ``` ### Helper Functions Common patterns are provided as helpers: ```rust impl<'a> AstBuilder<'a> { pub fn expression_numeric_literal(&self, span: Span, value: f64) -> Expression<'a> { self.alloc(Expression::NumericLiteral( self.alloc(NumericLiteral { span, value, raw: None }) )) } } ``` ## Development Workflow ### Adding New AST Nodes 1. **Define the struct**: ```rust #[ast(visit)] pub struct MyNewNode<'a> { pub span: Span, pub name: Atom<'a>, pub value: Expression<'a>, } ``` 2. **Add to enum**: ```rust pub enum Statement<'a> { // ... existing variants MyNewStatement(Box<'a, MyNewNode<'a>>), } ``` 3. **Run code generation**: ```bash just ast ``` 4. **Implement parsing logic**: ```rust impl<'a> Parser<'a> { fn parse_my_new_node(&mut self) -> Result> { // Parsing implementation } } ``` ## Comparing AST Formats ### Use AST Explorer For comparing with other parsers, use [ast-explorer.dev](https://ast-explorer.dev): 1. **Better UI**: Modern interface with syntax highlighting 2. **Up-to-date**: Latest parser versions 3. **Multiple parsers**: Compare Oxc, Babel, TypeScript, etc. 4. **Export formats**: JSON, code generation ## Performance Considerations ### Memory Layout The AST is designed for cache efficiency: ```rust // Good: Compact representation struct CompactNode<'a> { span: Span, // 8 bytes flags: u8, // 1 byte name: Atom<'a>, // 8 bytes } // Avoid: Large enums without boxing enum LargeEnum { Small, Large { /* 200 bytes of data */ }, } ``` ### Arena Allocation All AST nodes are allocated in the arena: ```rust // Automatically handled by #[ast] macro let node = self.ast.alloc(MyNode { span: SPAN, value: 42, }); ``` ### Enum Size Testing We enforce small enum sizes: ```rust #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] #[test] fn no_bloat_enum_sizes() { use std::mem::size_of; assert_eq!(size_of::(), 16); assert_eq!(size_of::(), 16); assert_eq!(size_of::(), 16); } ``` ## Advanced Topics ### Custom AST Attributes Add custom attributes for specific tools: ```rust #[ast(visit)] #[cfg_attr(feature = "serialize", derive(Serialize))] pub struct MyNode<'a> { #[cfg_attr(feature = "serialize", serde(skip))] pub internal_data: u32, pub public_field: Atom<'a>, } ``` ### Integration with Semantic Analysis Link AST nodes with semantic information: ```rust #[ast(visit)] pub struct IdentifierReference<'a> { pub span: Span, pub name: Atom<'a>, #[ast(ignore)] pub reference_id: Cell>, } ``` This allows tools to access binding information, scope context, and type information during AST traversal. ## Debugging Tips ### Pretty Printing Use the debug formatter to inspect AST: ```rust println!("{:#?}", ast_node); ``` ### Span Information Track source locations for error reporting: ```rust let span = node.span(); println!("Error at {}:{}", span.start, span.end); ``` --- --- url: /docs/learn/architecture/ast-tools.md --- # AST Tools The [AST Tools](https://github.com/oxc-project/oxc/tree/main/tasks/ast_tools) task serves as our secret weapon for managing all generated files. These tools include the AST builder, visitors, traits like `ContentEq` and `ContentHash`, and TypeScript types - all of which are machine-generated. For instance, the following files are automatically generated: * `crates/oxc_ast/src/generated/ast_builder.rs` * `crates/oxc_ast/src/generated/visit.rs` * `crates/oxc_ast/src/generated/visit_mut.rs` * `crates/oxc_ast/src/generated/derive_content_eq.rs` * `crates/oxc_ast/src/generated/derive_content_hash.rs` * `npm/oxc-types/src/generated/types.d.ts` ## Background Rust's compile time is notoriously slow, and using procedural macros to generate this much code worsens the issue. Requiring users to wait for code generation to complete at build time would significantly hinder the development experience for downstream projects. Both cold and incremental build times [can regress drastically](https://github.com/swc-project/swc/issues/7071). ## The RFC The team discussed the topic in [RFC: codegen AST related codes](https://github.com/oxc-project/oxc/issues/4134) and agreed on the following requirements and user story: ### Requirements * No build.rs published to the user. * All generated code are checked into git. * No nightly. * Rust code is source of truth, need to parse types marked `#[ast]`. * Avoid compile-time procedural macros as much as possible. ### Workflow * A user changes code in repo. * A watch change picks it up. * Parse all types marked `#[ast]`. * Record details of all AST types in a schema. * Generate code from schema and save to files. ## Infrastructure More details to follow. --- --- url: /docs/guide/usage/linter/automatic-fixes.md description: Apply safe, suggested, and dangerous fixes with Oxlint. --- # Automatic fixes Oxlint can automatically fix some lint violations. Automatic fixes are only applied when passing the relevant CLI flags. You choose when to apply them. In code editor integrations (such as VS Code, Zed, etc.), automatic fixes are exposed as "code actions" that you can apply in-editor. You can see all rules which have fixers in [the rules list](/docs/guide/usage/linter/rules). ## Safe fixes Safe fixes are changes that do not alter program behavior. Apply safe fixes: ```bash oxlint --fix ``` ## Suggestions Suggestions are changes that may alter behavior or may not match your intent. Apply suggestions: ```bash oxlint --fix-suggestions ``` ## Dangerous fixes Dangerous fixes are aggressive changes that may break your code. Apply dangerous fixes: ```bash oxlint --fix-dangerously ``` ## Combining fix modes You can combine safe fixes and suggestions: ```bash oxlint --fix --fix-suggestions ``` You can also include dangerous fixes: ```bash oxlint --fix --fix-suggestions --fix-dangerously ``` ## Rule support Not all rules provide fixes. Some rules support safe fixes, some provide suggestions, and some do not provide fixes yet. For some rules, a fixer is not realistically possible and cannot or should not be added. If a rule is missing a fixer and you believe it warrants one, contributions are welcome. ## Type-aware linting and fixes Fixers can be applied with [type-aware lint rules](/docs/guide/usage/linter/type-aware) as well. You can apply safe fixes with type-aware linting enabled like so: ```bash oxlint --type-aware --fix ``` Or with just `oxlint --fix` if you have type-aware linting enabled via your config file. ## JS Plugins [JS Plugins](/docs/guide/usage/linter/js-plugins) that provide fixers or suggestions can also be applied by Oxlint. --- --- url: /docs/guide/usage/transformer/plugins.md --- # Built-in Plugins Oxc transformer includes built-in support for popular transformation plugins to improve developer experience and build performance. ## Tagged Template Escape When enabled, `` sequences inside tagged template literals are escaped to prevent browsers from prematurely closing a surrounding `` can break when embedded in HTML `` `` is transformed into a helper call where the `` sequence is escaped to `<\/script>`. ## Styled Components The styled-components plugin adds comprehensive support for styled-components with server-side rendering, style minification, and enhanced debugging capabilities. ### Basic Usage ```javascript import { transform } from "oxc-transform"; const result = await transform("Component.jsx", sourceCode, { plugins: { styledComponents: { displayName: true, ssr: true, fileName: true, minify: true, }, }, }); ``` ### Example **Input:** ```jsx import styled from "styled-components"; const Button = styled.div` color: blue; padding: 10px; `; ``` **Output (with default options):** ```jsx import styled from "styled-components"; const Button = styled.div.withConfig({ displayName: "Button", componentId: "sc-1234567-0", })(["color:blue;padding:10px;"]); ``` ### Configuration Options #### Core Options | Option | Type | Default | Description | | ------------- | --------- | ------- | ----------------------------------------------------------------------------------- | | `displayName` | `boolean` | `true` | Enhances the attached CSS class name with component names for easier debugging | | `ssr` | `boolean` | `true` | Adds unique component IDs to avoid checksum mismatches during server-side rendering | | `fileName` | `boolean` | `true` | Controls whether the displayName is prefixed with the filename | #### Template Literal Options | Option | Type | Default | Description | | --------------------------- | --------- | ------- | ------------------------------------------------------------------------------ | | `transpileTemplateLiterals` | `boolean` | `true` | Converts template literals to a smaller representation for reduced bundle size | | `minify` | `boolean` | `true` | Minifies CSS content by removing whitespace and comments | #### Advanced Options | Option | Type | Default | Description | | ---------------------- | ---------- | ----------- | ------------------------------------------------------------- | | `pure` | `boolean` | `false` | Adds `/*#__PURE__*/` comments for better tree-shaking | | `namespace` | `string` | `undefined` | Adds a namespace prefix to component IDs | | `meaninglessFileNames` | `string[]` | `["index"]` | List of filenames considered meaningless for component naming | #### Not Yet Implemented | Option | Type | Default | Description | | --------------------- | ---------- | ------- | ------------------------------------- | | `cssProp` | `boolean` | `true` | JSX css prop transformation (planned) | | `topLevelImportPaths` | `string[]` | `[]` | Custom import path handling (planned) | ### Supported Import Patterns The plugin works with various styled-components import patterns: ```javascript // Default import import styled from "styled-components"; // Namespace import import * as styled from "styled-components"; // Named imports import { createGlobalStyle, css, keyframes } from "styled-components"; // Native and primitives import styled from "styled-components/native"; import styled from "styled-components/primitives"; ``` ### Features **✅ Fully Supported:** * Display names for debugging * Filename prefixing in display names * Server-side rendering support * Template literal transpilation * CSS minification * Namespace prefixes * Pure annotations for call expressions **⚠️ Partially Supported:** * Pure annotations (call expressions only, not tagged templates due to bundler limitations) **❌ Not Yet Implemented:** * JSX css prop transformation * Custom import path handling --- --- url: /docs/guide/usage/linter/plugins.md description: >- Enable built in plugin rule sets and extend Oxlint with ESLint compatible JavaScript plugins. --- # Built-in Plugins Oxlint includes built-in implementations of many popular ESLint plugin rule sets. Most rules in the `recommended` configs are already implemented, so you can get useful results without extra setup. Oxlint also supports plugins written in JavaScript with an ESLint-compatible API. See [JS Plugins](./js-plugins.md). ## What a plugin means in Oxlint A plugin is a named group of rules. Enabling a plugin makes its rules available, and category flags control which rules are enabled and at what severity. If you are migrating from ESLint, plugins map to the ecosystems you already know, such as import, react, jsx-a11y, jest, unicorn, and more. ## Enable a plugin It is **strongly recommended** to use a config file to enable plugins, as it makes it considerably easier to manage and share with other developers on a project. ### Enable in a config file You can also enable plugins in your config file using the `plugins` field: ::: code-group ```json [.oxlintrc.json] { "plugins": ["import"] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ plugins: ["import"], }); ``` ::: Setting `plugins` **overwrites the default plugin set**. The list should include every plugin you want enabled. ### Enable with the CLI You can also enable a plugin using a `---plugin` CLI flag. Example, enable the import plugin: ```bash oxlint --import-plugin ``` Once enabled, category flags determine what is turned on. Example, enable import plugin rules in the correctness category as errors and suspicious as warnings: ```bash oxlint --import-plugin -D correctness -W suspicious ``` Correctness rules are enabled by default. Tip: run `oxlint --help` to see the full list of plugin flags. ## Disable default plugins ### Disable default plugins in a config file To disable all default plugins in a config file, set `plugins` to an empty array: ::: code-group ```json [.oxlintrc.json] { "plugins": [] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ plugins: [], }); ``` ::: This disables all default plugins and uses only the base rule set. ### Disable default plugins with the CLI Several plugins are enabled by default. You can disable a default plugin with `--disable--plugin`. Example, disable unicorn: ```bash oxlint --disable-unicorn-plugin ``` Only default plugins support being disabled. Non-default plugins can simply be omitted. ## Supported plugins This table lists the built-in plugins and where they come from. | Plugin name | Default | Source | | ------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `eslint` | Yes | [ESLint](https://eslint.org/) core rules | | `typescript` | Yes | TypeScript rules from [typescript-eslint](https://typescript-eslint.io/) (aka `@typescript-eslint/plugin`). Type-aware rules are available using [the type-aware mode](./type-aware.md). | | `unicorn` | Yes | [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) | | `react` | No | [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react), [eslint-plugin-react-hooks](https://www.npmx.dev/package/eslint-plugin-react-hooks), [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh), and the React Compiler rules\* | | `react-perf` | No | [eslint-plugin-react-perf](https://github.com/cvazac/eslint-plugin-react-perf) | | `nextjs` | No | [@next/eslint-plugin-next](https://www.npmx.dev/package/@next/eslint-plugin-next) | | `oxc` | Yes | Oxc-specific rules and selected rules ported from deepscan | | `import` | No | [eslint-plugin-import](https://github.com/import-js/eslint-plugin-import) (also equivalent to [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x)) | | `jsdoc` | No | [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) | | `jsx-a11y` | No | [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) | | `node` | No | [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) | | `promise` | No | [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise) | | `jest` | No | [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) | | `vitest` | No | [@vitest/eslint-plugin](https://github.com/vitest-dev/eslint-plugin-vitest) aka eslint-plugin-vitest | | `vue` | No | [eslint-plugin-vue](https://eslint.vuejs.org/) rules that work with script tags | For the current status of rule coverage, see the linter [product plan issue](https://github.com/oxc-project/oxc/issues/481). For framework and file type support, see the [compatibility matrix](/compatibility). \* The React Compiler rules are implemented natively as the [`react/react-compiler`](./rules/react/react-compiler) rule, which runs the React Compiler's analysis in lint-only mode. It is experimental and off by default, so it must be enabled explicitly. ## Adding new plugins Oxlint focuses on supporting the ecosystem through built-in plugins and ESLint-compatible JavaScript plugins. [Contributions that add rules](/docs/contribute/linter/adding-rules) to existing built-in plugins are encouraged. If you think a rule set should be implemented as a built-in plugin, please [open a GitHub discussion](https://github.com/oxc-project/oxc/discussions/new?category=feature-request) first. --- --- url: /docs/guide/usage/formatter/cli.md --- # Command-line Interface ## Usage **`oxfmt`** \[**`-c`**=*`PATH`*] \[*`PATH`*]... ## Mode Options: * **` --init`** — Initialize `.oxfmtrc.json` with default values * **` --migrate`**=*`SOURCE`* — Migrate configuration to `.oxfmtrc.json` from specified source Available sources: prettier, biome * **` --lsp`** — Start language server protocol (LSP) server * **` --stdin-filepath`**=*`PATH`* — Specify the file name to use to infer which parser to use ## Output Options: * **` --write`** — Format and write files in place (default) * **` --check`** — Check if files are formatted, also show statistics * **` --list-different`** — List files that would be changed ## Config Options * **`-c`**, **`--config`**=*`PATH`* — Path to the configuration file (.json, .jsonc, .ts, .mts, .cts, .js, .mjs, .cjs) * **` --disable-nested-config`** — Do not search for configuration files in subdirectories ## Ignore Options * **` --ignore-path`**=*`PATH`* — Path to ignore file(s). Can be specified multiple times. If not specified, .gitignore and .prettierignore in the current directory are used. * **` --with-node-modules`** — Format code in node\_modules directory (skipped by default) ## Runtime Options * **` --no-error-on-unmatched-pattern`** — Do not exit with error when pattern is unmatched * **` --threads`**=*`INT`* — Number of threads to use. Set to 1 for using only 1 CPU core. ## Available positional items: * *`PATH`* — Single file, path or list of paths. Glob patterns are also supported. (Be sure to quote them, otherwise your shell may expand them before passing.) Exclude patterns with `!` prefix like `'!**/fixtures/*.js'` are also supported. If not provided, current working directory is used. ## Available options: * **`-h`**, **`--help`** — Prints help information * **`-V`**, **`--version`** — Prints version information --- --- url: /docs/guide/usage/linter/cli.md --- # Command-line Interface ## Usage **`oxlint`** \[**`-c`**=*`<./.oxlintrc.json>`*] \[*`PATH`*]... ## Basic Configuration * **`-c`**, **`--config`**=*`<./.oxlintrc.json>`* — Oxlint configuration file - `.json` and `.jsonc` config files are supported in all runtimes - JavaScript/TypeScript config files are experimental and require running via Node.js - you can use comments in configuration files. - tries to be compatible with ESLint v8's format If not provided, Oxlint will look for a `.oxlintrc.json`, `.oxlintrc.jsonc`, `oxlint.config.ts`, or `oxlint.config.mts` file in the current working directory. * **` --tsconfig`**=*`<./tsconfig.json>`* — Override the TypeScript config used for import resolution. Oxlint automatically discovers the relevant `tsconfig.json` for each file. Use this only when your project uses a non-standard tsconfig name or location. ::: warning Avoid using this option. It can cause differences between import resolution, and type-aware linting. Type aware linting **does not** respect this option, and will always discover the appropriate `tsconfig.json` for each file automatically. ::: * **` --init`** — Initialize oxlint configuration with default values ## Allowing / Denying Multiple Lints Accumulate rules and categories from left to right on the command-line. For example `-D correctness -A no-debugger` or `-A all -D no-debugger`. The categories are: * `correctness` - Code that is outright wrong or useless (default) * `suspicious` - Code that is most likely wrong or useless * `pedantic` - Lints which are rather strict or have occasional false positives * `perf` - Code that could be written in a more performant way * `style` - Code that should be written in a more idiomatic way * `restriction` - Lints which prevent the use of language and library features * `nursery` - New lints that are still under development * `all` - All categories listed above except `nursery`. Does not enable plugins automatically. Arguments: * **`-A`**, **`--allow`**=*`NAME`* — Allow the rule or category (suppress the lint) * **`-W`**, **`--warn`**=*`NAME`* — Warn on the rule or category (emit a warning) * **`-D`**, **`--deny`**=*`NAME`* — Deny the rule or category (emit an error) ## Enable/Disable Plugins * **` --disable-unicorn-plugin`** — Disable unicorn plugin, which is turned on by default * **` --disable-oxc-plugin`** — Disable oxc unique rules, which is turned on by default * **` --disable-typescript-plugin`** — Disable TypeScript plugin, which is turned on by default * **` --import-plugin`** — Enable import plugin and detect ESM problems. * **` --react-plugin`** — Enable react plugin, which is turned off by default * **` --jsdoc-plugin`** — Enable jsdoc plugin and detect JSDoc problems * **` --jest-plugin`** — Enable the Jest plugin and detect test problems * **` --vitest-plugin`** — Enable the Vitest plugin and detect test problems * **` --jsx-a11y-plugin`** — Enable the JSX-a11y plugin and detect accessibility problems * **` --nextjs-plugin`** — Enable the Next.js plugin and detect Next.js problems * **` --react-perf-plugin`** — Enable the React performance plugin and detect rendering performance problems * **` --promise-plugin`** — Enable the promise plugin and detect promise usage problems * **` --node-plugin`** — Enable the node plugin and detect node usage problems * **` --vue-plugin`** — Enable the vue plugin and detect vue usage problems ## Fix Problems * **` --fix`** — Fix as many issues as possible. Only unfixed issues are reported in the output. * **` --fix-suggestions`** — Apply auto-fixable suggestions. May change program behavior. * **` --fix-dangerously`** — Apply dangerous fixes and suggestions ## Ignore Files * **` --ignore-path`**=*`PATH`* — Specify the file to use as your `.eslintignore` * **` --ignore-pattern`**=*`PAT`* — Specify patterns of files to ignore (in addition to those in `.eslintignore`) The supported syntax is the same as for `.eslintignore` and `.gitignore` files. You should quote your patterns in order to avoid shell interpretation of glob patterns. * **` --no-ignore`** — Disable excluding files from `.eslintignore` files, **`--ignore-path`** flags and **`--ignore-pattern`** flags ## Handle Warnings * **` --quiet`** — Disable reporting on warnings, only errors are reported * **` --deny-warnings`** — Ensure warnings produce a non-zero exit code * **` --max-warnings`**=*`INT`* — Specify a warning threshold, which can be used to force exit with an error status if there are too many warning-level rule violations in your project ## Output * **`-f`**, **`--format`**=*`ARG`* — Use a specific output format. Possible values: `checkstyle`, `default`, `agent`, `github`, `gitlab`, `json`, `junit`, `sarif`, `stylish`, `unix` * **` --debug`**=*`OPTIONS`* — Enable debug output options. Options are comma-separated. Possible values: - `files` - Print the list of files that will be linted, then exit. - `timings` - Enable per-rule timing information. ## Miscellaneous * **` --silent`** — Do not display any diagnostics * **` --no-error-on-unmatched-pattern`** — Do not exit with an error when no files are selected for linting (for example, after applying ignore patterns) * **` --threads`**=*`INT`* — Number of threads to use. Set to 1 for using only 1 CPU core. * **` --print-config`** — This option outputs the configuration to be used. When present, no linting is performed and only config-related options are valid. ## Inline Configuration Comments * **` --report-unused-disable-directives`** — Report directive comments like `// oxlint-disable-line`, when no errors would have been reported on that line anyway * **` --report-unused-disable-directives-severity`**=*`SEVERITY`* — Same as `--report-unused-disable-directives`, but allows you to specify the severity level of the reported errors. Only one of these two options can be used at a time. ## Available positional items: * *`PATH`* — Single file, single path or list of paths ## Available options: * **` --rules`** — List all the rules that are currently registered * **` --lsp`** — Start the language server * **` --disable-nested-config`** — Disable the automatic loading of nested configuration files * **` --type-aware`** — Enable rules that require type information * **` --type-check`** — Enable experimental type checking (includes TypeScript compiler diagnostics) * **`-h`**, **`--help`** — Prints help information * **`-V`**, **`--version`** — Prints version information --- --- url: /docs/guide/usage/linter/config-file-reference.md --- # Oxlint Configuration File This configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`). Usage: `oxlint -c oxlintrc.json` Example `.oxlintrc.json` ```json { "$schema": "./node_modules/oxlint/configuration_schema.json", "plugins": ["import", "typescript", "unicorn"], "env": { "browser": true }, "globals": { "foo": "readonly" }, "settings": { "react": { "version": "18.2.0" }, "custom": { "option": true } }, "rules": { "eqeqeq": "warn", "import/no-cycle": "error", "react/self-closing-comp": [ "error", { "html": false } ] }, "overrides": [ { "files": ["*.test.ts", "*.spec.ts"], "rules": { "@typescript-eslint/no-explicit-any": "off" } } ] } ``` `oxlint.config.ts` ```ts import { defineConfig } from "oxlint"; export default defineConfig({ plugins: ["import", "typescript", "unicorn"], env: { browser: true, }, globals: { foo: "readonly", }, settings: { react: { version: "18.2.0", }, custom: { option: true }, }, rules: { eqeqeq: "warn", "import/no-cycle": "error", "react/self-closing-comp": ["error", { html: false }], }, overrides: [ { files: ["*.test.ts", "*.spec.ts"], rules: { "@typescript-eslint/no-explicit-any": "off", }, }, ], }); ``` ## $schema type: `string` Schema URI for editor tooling. ## categories type: `object` Configure an entire category of rules all at once. Rules enabled or disabled this way will be overwritten by individual rules in the `rules` field. Example ```json { "$schema": "./node_modules/oxlint/configuration_schema.json", "categories": { "correctness": "warn" }, "rules": { "eslint/no-unused-vars": "error" } } ``` ### categories.correctness ### categories.nursery ### categories.pedantic ### categories.perf ### categories.restriction ### categories.style ### categories.suspicious ## env type: `Record` Environments enable and disable collections of global variables. Predefine global variables. Environments specify what global variables are predefined. Available environments: * amd - require() and define() globals. * applescript - AppleScript globals. * astro - Astro globals. * atomtest - Atom test globals. * audioworklet - AudioWorklet globals. * browser - browser globals. * builtin - Latest ECMAScript globals, equivalent to es2026. * commonjs - CommonJS globals and scoping. * embertest - Ember test globals. * es2015 - ECMAScript 2015 globals. * es2016 - ECMAScript 2016 globals. * es2017 - ECMAScript 2017 globals. * es2018 - ECMAScript 2018 globals. * es2019 - ECMAScript 2019 globals. * es2020 - ECMAScript 2020 globals. * es2021 - ECMAScript 2021 globals. * es2022 - ECMAScript 2022 globals. * es2023 - ECMAScript 2023 globals. * es2024 - ECMAScript 2024 globals. * es2025 - ECMAScript 2025 globals. * es2026 - ECMAScript 2026 globals. * es6 - ECMAScript 6 globals except modules. * greasemonkey - GreaseMonkey globals. * jasmine - Jasmine globals. * jest - Jest globals. * jquery - jQuery globals. * meteor - Meteor globals. * mocha - Mocha globals. * mongo - MongoDB globals. * nashorn - Java 8 Nashorn globals. * node - Node.js globals and scoping. * phantomjs - PhantomJS globals. * prototypejs - Prototype.js globals. * protractor - Protractor globals. * qunit - QUnit globals. * serviceworker - Service Worker globals. * shared-node-browser - Node.js and Browser common globals. * shelljs - ShellJS globals. * svelte - Svelte globals. * vitest - Vitest globals. * vue - Vue globals. * webextensions - WebExtensions globals. * worker - Web Workers globals. ## extends type: `string[]` Configurations that this configuration file extends (inherits from). In `.oxlintrc.json`, `extends` has type `string[]`. Each string is a path to a configuration file, resolved relative to the location of the configuration file that contains the `extends` property. In `oxlint.config.ts`, `extends` has type `OxlintConfig[]`. Import each configuration and pass the configuration object directly: ```ts import { defineConfig } from "oxlint"; import baseConfig from "./base-config.ts"; export default defineConfig({ extends: [baseConfig] }); ``` Configurations are merged from the first to the last, with the last configuration overriding the previous ones. ## globals type: `Record` Enabled or disabled specific global variables. Add or remove global variables. For each global variable, set the corresponding value equal to `"writable"` to allow the variable to be overwritten or `"readonly"` to disallow overwriting. Globals can be disabled by setting their value to `"off"`. For example, in an environment where most Es2015 globals are available but `Promise` is unavailable, you might use this config: ```json { "$schema": "./node_modules/oxlint/configuration_schema.json", "env": { "es6": true }, "globals": { "Promise": "off" } } ``` You may also use `"readable"` or `false` to represent `"readonly"`, and `"writeable"` or `true` to represent `"writable"`. ## ignorePatterns type: `string[]` default: `[]` Globs to ignore during linting. Patterns use gitignore-style matching, rooted at the directory containing the configuration file. Files outside that directory cannot be matched; patterns containing `..` are rejected as a configuration error. ## jsPlugins type: `array` JS plugins, allows usage of ESLint plugins with Oxlint. Read more about JS plugins in [the docs](https://oxc.rs/docs/guide/usage/linter/js-plugins.html). Note: JS plugins are in alpha and not subject to semver. Examples: Basic usage with a local plugin path. ```json { "jsPlugins": ["./custom-plugin.js"], "rules": { "custom/rule-name": "warn" } } ``` Basic usage with a TypeScript plugin and a local plugin path. TypeScript plugin files are supported in the following environments: * Deno and Bun: TypeScript files are supported natively. * Node.js >=22.18.0 and Node.js ^20.19.0: TypeScript files are supported natively with built-in type-stripping enabled by default. For older Node.js versions, TypeScript plugins are not supported. Please use JavaScript plugins or upgrade your Node version. ```json { "jsPlugins": ["./custom-plugin.ts"], "rules": { "custom/rule-name": "warn" } } ``` Using a built-in Rust plugin alongside a JS plugin with the same name by giving the JS plugin an alias. ```json { "plugins": ["import"], "jsPlugins": [ { "name": "import-js", "specifier": "eslint-plugin-import" } ], "rules": { "import/no-cycle": "error", "import-js/no-unresolved": "warn" } } ``` ### jsPlugins\[n] type: `object | string` #### jsPlugins\[n].name type: `string` Custom name/alias for the plugin. Note: The following plugin names are reserved because they are implemented natively in Rust within oxlint and cannot be used for JS plugins: * react (includes react-hooks) * unicorn * typescript (includes @typescript-eslint) * oxc * import (includes import-x) * jsdoc * jest * vitest * jsx-a11y (includes jsx-a11y-x) * nextjs * react-perf * promise * node * vue * eslint If you need to use the JavaScript version of any of these plugins, provide a custom alias to avoid conflicts. #### jsPlugins\[n].specifier type: `string` Path or package name of the plugin ## options type: `object` Oxlint config options. Options for the linter. ### options.denyWarnings type: `boolean` Ensure warnings produce a non-zero exit code. Equivalent to passing `--deny-warnings` on the CLI. ### options.maxWarnings type: `integer` Specify a warning threshold. Exits with an error status if warnings exceed this value. Equivalent to passing `--max-warnings` on the CLI. ### options.reportUnusedDisableDirectives type: `"allow" | "off" | "warn" | "error" | "deny" | integer` Report unused disable directives (e.g. `// oxlint-disable-line` or `// eslint-disable-line`). Equivalent to passing `--report-unused-disable-directives-severity` on the CLI. CLI flags take precedence over this value when both are set. Only supported in the root configuration file. ### options.respectEslintDisableDirectives type: `boolean` Whether oxlint should respect `eslint-disable*` and `eslint-enable*` directives in addition to its native `oxlint-*` directives. Defaults to `true`. Only supported in the root configuration file. ### options.typeAware type: `boolean` Enable rules that require type information. Equivalent to passing `--type-aware` on the CLI. Note that this requires the `oxlint-tsgolint` package to be installed. ### options.typeCheck type: `boolean` Enable experimental type checking (includes TypeScript compiler diagnostics). Equivalent to passing `--type-check` on the CLI. Note that this requires the `oxlint-tsgolint` package to be installed. ## overrides type: `array` Add, remove, or otherwise reconfigure rules for specific files or groups of files. ### overrides\[n] type: `object` #### overrides\[n].env type: `object` Environments enable and disable collections of global variables. #### overrides\[n].excludeFiles type: `string[]` A list of glob patterns to exclude from this override. Files matching these patterns are not globally ignored; this override simply does not apply to them. ## Example `[ "*.generated.ts", "fixtures/**" ]` A set of glob patterns. Patterns are matched against paths relative to the configuration file's directory. #### overrides\[n].files type: `string[]` A list of glob patterns to override. ## Example `[ "*.test.ts", "*.spec.ts" ]` A set of glob patterns. Patterns are matched against paths relative to the configuration file's directory. #### overrides\[n].globals type: `object` Enabled or disabled specific global variables. #### overrides\[n].jsPlugins type: `array` JS plugins for this override, allows usage of ESLint plugins with Oxlint. Read more about JS plugins in [the docs](https://oxc.rs/docs/guide/usage/linter/js-plugins.html). Note: JS plugins are in alpha and not subject to semver. ##### overrides\[n].jsPlugins\[n] type: `object | string` ###### overrides\[n].jsPlugins\[n].name type: `string` Custom name/alias for the plugin. Note: The following plugin names are reserved because they are implemented natively in Rust within oxlint and cannot be used for JS plugins: * react (includes react-hooks) * unicorn * typescript (includes @typescript-eslint) * oxc * import (includes import-x) * jsdoc * jest * vitest * jsx-a11y (includes jsx-a11y-x) * nextjs * react-perf * promise * node * vue * eslint If you need to use the JavaScript version of any of these plugins, provide a custom alias to avoid conflicts. ###### overrides\[n].jsPlugins\[n].specifier type: `string` Path or package name of the plugin #### overrides\[n].plugins type: `array` default: `null` Optionally change what plugins are enabled for this override. When omitted, the base config's plugins are used. ##### overrides\[n].plugins\[n] type: `"eslint" | "react" | "unicorn" | "typescript" | "oxc" | "import" | "jsdoc" | "jest" | "vitest" | "jsx-a11y" | "nextjs" | "react-perf" | "promise" | "node" | "vue"` #### overrides\[n].rules type: `object` See [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter/rules.html) ## plugins type: `array` default: `null` Enabled built-in plugins for Oxlint. You can view the list of available plugins on [the website](https://oxc.rs/docs/guide/usage/linter/plugins.html#supported-plugins). NOTE: Setting the `plugins` field will overwrite the base set of plugins. The `plugins` array should reflect all of the plugins you want to use. ### plugins\[n] type: `"eslint" | "react" | "unicorn" | "typescript" | "oxc" | "import" | "jsdoc" | "jest" | "vitest" | "jsx-a11y" | "nextjs" | "react-perf" | "promise" | "node" | "vue"` ## rules type: `object` Example `.oxlintrc.json` ```json { "$schema": "./node_modules/oxlint/configuration_schema.json", "rules": { "eqeqeq": "warn", "import/no-cycle": "error", "prefer-const": [ "error", { "ignoreReadBeforeAssign": true } ] } } ``` See [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter/rules.html) for the list of rules. See [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter/rules.html) ## settings type: `object` Plugin-specific configuration for both built-in and custom plugins. This includes settings for built-in plugins such as `react` and `jsdoc` as well as configuring settings for JS custom plugins loaded via `jsPlugins`. Configure the behavior of linter plugins. Here's an example if you're using Next.js in a monorepo: ```json { "settings": { "next": { "rootDir": "apps/dashboard/" }, "react": { "linkComponents": [ { "name": "Link", "linkAttribute": "to" } ] }, "jsx-a11y": { "components": { "Link": "a", "Button": "button" } } } } ``` ### settings.jest type: `object` Configure Jest plugin rules. See [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest)'s configuration for a full reference. #### settings.jest.version type: `integer | string` default: `null` Jest version — accepts a number (`29`) or a semver string (`"29.1.0"` or `"v29.1.0"`), storing only the major version. ::: warning Using this config will override the `no-deprecated-functions` config set. ::: ### settings.jsdoc type: `object` #### settings.jsdoc.augmentsExtendsReplacesDocs type: `boolean` default: `false` Only for `require-(yields|returns|description|example|param|throws)` rule #### settings.jsdoc.exemptDestructuredRootsFromChecks type: `boolean` default: `false` Only for `require-param-type` and `require-param-description` rule #### settings.jsdoc.ignoreInternal type: `boolean` default: `false` For all rules but NOT apply to `empty-tags` rule #### settings.jsdoc.ignorePrivate type: `boolean` default: `false` For all rules but NOT apply to `check-access` and `empty-tags` rule #### settings.jsdoc.ignoreReplacesDocs type: `boolean` default: `true` Only for `require-(yields|returns|description|example|param|throws)` rule #### settings.jsdoc.implementsReplacesDocs type: `boolean` default: `false` Only for `require-(yields|returns|description|example|param|throws)` rule #### settings.jsdoc.overrideReplacesDocs type: `boolean` default: `true` Only for `require-(yields|returns|description|example|param|throws)` rule #### settings.jsdoc.tagNamePreference type: `object` default: `{}` ### settings.jsx-a11y type: `object` Configure JSX A11y plugin rules. See [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#configurations)'s configuration for a full reference. #### settings.jsx-a11y.attributes type: `Record` default: `{}` Map of attribute names to their DOM equivalents. This is useful for non-React frameworks that use different attribute names. Example: ```json { "settings": { "jsx-a11y": { "attributes": { "for": ["htmlFor", "for"] } } } } ``` #### settings.jsx-a11y.components type: `Record` default: `{}` To have your custom components be checked as DOM elements, you can provide a mapping of your component names to the DOM element name. Example: ```json { "settings": { "jsx-a11y": { "components": { "Link": "a", "IconButton": "button" } } } } ``` #### settings.jsx-a11y.polymorphicPropName type: `string` An optional setting that define the prop your code uses to create polymorphic components. This setting will be used to determine the element type in rules that require semantic context. For example, if you set the `polymorphicPropName` to `as`, then this element: ```jsx Hello ``` Will be treated as an `h3`. If not set, this component will be treated as a `Box`. ### settings.next type: `object` Configure Next.js plugin rules. #### settings.next.rootDir type: `array | string` The root directory of the Next.js project. This is particularly useful when you have a monorepo and your Next.js project is in a subfolder. Example: ```json { "settings": { "next": { "rootDir": "apps/dashboard/" } } } ``` ##### settings.next.rootDir\[n] type: `string` ### settings.react type: `object` Configure React plugin rules. Derived from [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react#configuration-legacy-eslintrc-) #### settings.react.componentWrapperFunctions type: `string[]` default: `[]` Functions that wrap React components and should be treated as HOCs. Example: ```jsonc { "settings": { "react": { "componentWrapperFunctions": ["observer", "withRouter"], }, }, } ``` #### settings.react.formComponents type: `array` default: `[]` Components used as alternatives to `
` for forms, such as ``. Example: ```jsonc { "settings": { "react": { "formComponents": [ "CustomForm", // OtherForm is considered a form component and has an endpoint attribute { "name": "OtherForm", "formAttribute": "endpoint" }, // allows specifying multiple properties if necessary { "name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"] }, ], }, }, } ``` ##### settings.react.formComponents\[n] type: `object | string` ###### settings.react.formComponents\[n].attribute type: `string` ###### settings.react.formComponents\[n].name type: `string` #### settings.react.linkComponents type: `array` default: `[]` Components used as alternatives to `` for linking, such as ``. Example: ```jsonc { "settings": { "react": { "linkComponents": [ "HyperLink", // Use `linkAttribute` for components that use a different prop name // than `href`. { "name": "MyLink", "linkAttribute": "to" }, // allows specifying multiple properties if necessary { "name": "Link", "linkAttribute": ["to", "href"] }, ], }, }, } ``` ##### settings.react.linkComponents\[n] type: `object | string` ###### settings.react.linkComponents\[n].attribute type: `string` ###### settings.react.linkComponents\[n].name type: `string` #### settings.react.version type: `string` default: `null` React version to use for version-specific rules. Accepts semver versions (e.g., "18.2.0", "17.0"). Example: ```jsonc { "settings": { "react": { "version": "18.2.0", }, }, } ``` ### settings.vitest type: `object` Configure Vitest plugin rules. See [eslint-plugin-vitest](https://github.com/vitest-dev/eslint-plugin-vitest)'s configuration for a full reference. #### settings.vitest.typecheck type: `boolean` default: `false` Whether to enable typecheck mode for Vitest rules. When enabled, some rules will skip certain checks for describe blocks to accommodate TypeScript type checking scenarios. --- --- url: /docs/guide/usage/formatter/config.md description: Configure Oxfmt using a .oxfmtrc.json file. --- # Configuration Oxfmt works out of the box, but most teams commit a configuration file to keep formatting consistent across local runs, editors, and CI. This page focuses on project configuration: formatting options, ignore patterns, and experimental features. ## Create a config file To generate a starter config in the current directory: ```sh oxfmt --init ``` Oxfmt automatically looks for the following files starting from the directory of the file being formatted and walking up the tree: * `.oxfmtrc.json` * `.oxfmtrc.jsonc` * `oxfmt.config.ts` * `oxfmt.config.mts` You can use only one config file per directory: JSON and TypeScript configs cannot coexist, nor can `oxfmt.config.ts` and `oxfmt.config.mts`. The nearest config file to each formatted file wins. This means you can place different config files at different levels of your project tree. For example, a root config for the whole repo and a more specific one inside a subdirectory: ``` my-repo/ ├── oxfmt.config.ts # default for the whole repo ├── src/ │ └── app.ts # uses root config └── packages/ └── fancy-app/ ├── .oxfmtrc.json # overrides for this package └── index.ts # uses packages/fancy-app/.oxfmtrc.json ``` If you don't need nested config, pass `--disable-nested-config` to only look upward from the current working directory. This is faster because Oxfmt can resolve the config once instead of per file. You can also pass a config explicitly with `-c`, which also disables nested config lookup. This accepts any supported format (`.json`, `.jsonc`, `.ts`, `.mts`, `.cts`, `.js`, `.mjs`, `.cjs`): ```sh oxfmt -c path/to/yourconfig.json ``` A minimal JSON configuration looks like this: ```json [.oxfmtrc.json] { "$schema": "./node_modules/oxfmt/configuration_schema.json", "printWidth": 80 } ``` JavaScript / TypeScript config files use a default export. `defineConfig` is optional but gives you type checking and editor autocomplete: ```ts [oxfmt.config.ts] import { defineConfig } from "oxfmt"; export default defineConfig({ printWidth: 80, }); ``` ## Configuration file format A configuration file is a JSON object. The most common top-level fields are: * `printWidth`: Line width limit (default: 100) * `tabWidth`: Spaces per indentation level (default: 2) * `useTabs`: Use tabs instead of spaces (default: false) * `semi`: Add semicolons (default: true) * `singleQuote`: Use single quotes (default: false) * `trailingComma`: Trailing commas in multi-line structures (default: "all") * `ignorePatterns`: Glob patterns to exclude from formatting * `sortImports`: Configure import sorting (disabled by default) * `sortTailwindcss`: Configure Tailwind class sorting (disabled by default) * `sortPackageJson`: Configure package.json sorting (enabled by default) For a complete list of fields, see the [Config file reference](./config-file-reference). ## JSON schema Add a `$schema` field for editor validation and autocomplete: ```json [.oxfmtrc.json] { "$schema": "./node_modules/oxfmt/configuration_schema.json" } ``` ## `.editorconfig` Oxfmt reads these `.editorconfig` properties: * `end_of_line` → `endOfLine` * `indent_style` → `useTabs` * `indent_size` → `tabWidth` * `max_line_length` → `printWidth` * `insert_final_newline` → `insertFinalNewline` Both root section and glob-based overrides are supported. ``` [*] indent_size = 4 [*.{js,ts}] indent_size = 2 ``` Oxfmt uses only the nearest `.editorconfig` from the current directory: * `root = true` is not respected * Nested `.editorconfig` files are not merged ## Overrides Use the `overrides` field to apply different formatting options to specific files: ::: code-group ```json [.oxfmtrc.json] { "printWidth": 100, "overrides": [ { "files": ["*.test.js", "*.spec.ts"], "options": { "printWidth": 120 } }, { "files": ["*.md", "*.html"], "excludeFiles": ["*.min.js"], "options": { "tabWidth": 4 } } ] } ``` ```ts [oxfmt.config.ts] import { defineConfig } from "oxfmt"; export default defineConfig({ printWidth: 100, overrides: [ { files: ["*.test.js", "*.spec.ts"], options: { printWidth: 120, }, }, { files: ["*.md", "*.html"], excludeFiles: ["*.min.js"], options: { tabWidth: 4, }, }, ], }); ``` ::: Each override entry has: * `files` (required): Glob patterns to match files * `excludeFiles` (optional): Glob patterns to exclude from this override * `options`: Formatting options to apply Glob patterns are resolved relative to the directory containing the Oxfmt config file. ## Precedence Options are applied in order (lowest to highest priority): 1. Defaults 2. Config file root options 3. Config file `overrides` options 4. fallback to options supported by `.editorconfig` for unset fields ## Oxfmt-specific options ### `insertFinalNewline` Controls whether a final newline is added to formatted files. Defaults to `true`. This is a [frequently requested Prettier feature](https://github.com/prettier/prettier/issues/6360), as some environments (e.g., Salesforce) strip trailing newlines. ### `printWidth` Oxfmt defaults to `printWidth: 100` (Prettier uses 80). Reasons: * TypeScript code is longer due to type annotations * Import statements often have many specifiers * Modern screens are wider * Fewer line breaks mean fewer LLM tokens To match Prettier's default: ::: code-group ```json [.oxfmtrc.json] { "printWidth": 80 } ``` ```ts [oxfmt.config.ts] import { defineConfig } from "oxfmt"; export default defineConfig({ printWidth: 80, }); ``` ::: ## Next steps * [Ignore files](./ignore-files): Ignore files and patterns, `.gitignore` and `.prettierignore` workflows. * [Inline ignore comments](./ignore-comments): Inline suppressions for specific code. * [Config file reference](./config-file-reference): Full schema and field documentation. * [CLI reference](./cli): Complete list of flags. --- --- url: /docs/guide/usage/linter/config.md description: Configure Oxlint using .oxlintrc.json or oxlint.config.ts. --- # Configuration Oxlint works out of the box, but most teams commit a configuration file (`.oxlintrc.json` or `oxlint.config.ts`) to keep linting consistent across local runs, editors, and CI. This page focuses on project configuration: rules, categories, plugins, overrides, and shared settings. ## Create a config file To generate a starter config in the current directory (JSON): ```sh oxlint --init ``` Oxlint automatically looks for a `.oxlintrc.json`, `.oxlintrc.jsonc`, `oxlint.config.ts`, or `oxlint.config.mts` in the current working directory. You can also pass a config explicitly (note that this will disable nested config lookup): ```sh oxlint -c ./.oxlintrc.json # or oxlint --config ./.oxlintrc.json ``` Notes: * `.oxlintrc.json` supports comments (like jsonc). * The configuration format aims to be compatible with ESLint v8's format (`eslintrc.json`). * You can use only one config file per directory: JSON and TypeScript configs cannot coexist, nor can `oxlint.config.ts` and `oxlint.config.mts`. A minimal configuration looks like this: ```json [.oxlintrc.json] { "$schema": "./node_modules/oxlint/configuration_schema.json", "categories": { "correctness": "warn" }, "rules": { "eslint/no-unused-vars": "error" } } ``` ### TypeScript config file (`oxlint.config.ts`) Oxlint also supports a TypeScript configuration file named `oxlint.config.ts` or `oxlint.config.mts`. ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ categories: { correctness: "warn", }, rules: { "eslint/no-unused-vars": "error", }, }); ``` Notes: * For auto-discovery, the file must be named `oxlint.config.ts` or `oxlint.config.mts`. When passed via `--config`, any path with a JS/TS extension (`.js`, `.mjs`, `.cjs`, `.ts`, `.mts`, `.cts`) is accepted. * The default export must be an object and should be wrapped with `defineConfig` for typing. * TypeScript configs require the Node-based `oxlint` package (JS runtime). If you're using a standalone binary, use `.oxlintrc.json` instead. * TypeScript configs require a Node runtime that can execute TypeScript (Node v22.18+ or v24+). ## Configuration file format A configuration file is either a JSON object (`.oxlintrc.json`) or a TypeScript module that default-exports a config object (`oxlint.config.ts`). The most common top-level fields are: * `rules`: Enable or disable rules, set severity, and configure rule options. * `categories`: Enable groups of rules with similar intent. * `plugins`: Enable built-in plugins that provide additional rules. * `jsPlugins`: Configure JavaScript plugins (alpha). * `overrides`: Apply different configuration to different file patterns. * `extends`: Inherit configuration from other files. * `ignorePatterns`: Ignore additional files from the config file. * `env`: Enable predefined globals for common environments. * `globals`: Declare custom globals as read-only or writable. * `settings`: Plugin-wide configuration shared by multiple rules. * `options`: Linter-level options (for example, `options.typeAware` and `options.typeCheck`). For a complete list of fields, see the [Config file reference](/docs/guide/usage/linter/config-file-reference.html). ## Configure linter options Use `options` for linter-level behavior. See the [Config file reference](/docs/guide/usage/linter/config-file-reference.html#options) for the full list. Example: ::: code-group ```json [.oxlintrc.json] { "options": { "typeAware": true, "typeCheck": true, "maxWarnings": 10 } } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ options: { typeAware: true, typeCheck: true, maxWarnings: 10, }, }); ``` ::: * `options.typeAware` is equivalent to passing `--type-aware` on the CLI. * `options.typeCheck` (experimental) is equivalent to passing `--type-check` on the CLI. * `options.maxWarnings` is equivalent to passing `--max-warnings` on the CLI. CLI flags take precedence when both CLI and config values are present. `options.typeAware` and `options.typeCheck` are only supported in the root config file. ## Configure rules Rules are configured under `rules`. A rule value is either: * a severity (`"off"`, `"warn"`, `"error"`), or * an array of `[severity, options]` If a rule is from ESLint core and its name is unique, you can configure it without a plugin prefix. For example, `no-console` is the same as `eslint/no-console`. ::: code-group ```json [.oxlintrc.json] { "rules": { "no-alert": "error", "oxc/approx-constant": "warn", "no-plusplus": "off", "eslint/prefer-const": ["error", { "destructuring": "any" }] } } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ rules: { "no-alert": "error", "oxc/approx-constant": "warn", "no-plusplus": "off", "eslint/prefer-const": ["error", { destructuring: "any" }], }, }); ``` ::: ### Severity values Oxlint accepts ESLint-style severities: * Disable rule: `"off"` or `"allow"` * Warning on rule: `"warn"` * Error on rule: `"error"` or `"deny"` ### Rule options To configure rule options, use an array: ::: code-group ```json [.oxlintrc.json] { "rules": { "no-plusplus": ["error", { "allowForLoopAfterthoughts": true }] } } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ rules: { "no-plusplus": ["error", { allowForLoopAfterthoughts: true }], }, }); ``` ::: All available rules, and their configuration options, are listed in the [Rules reference](/docs/guide/usage/linter/rules). ### Override severity from the CLI For quick experiments, you can adjust severity from the command line using: * `-A` / `--allow` * `-W` / `--warn` * `-D` / `--deny` Arguments are applied from left to right: ```sh oxlint -D no-alert -W oxc/approx-constant -A no-plusplus ``` ## Enable groups of rules with categories Categories let you enable or disable sets of rules with similar intent. By default, Oxlint enables rules in the `correctness` category. Configure categories using `categories`: ::: code-group ```json [.oxlintrc.json] { "categories": { "correctness": "error", "suspicious": "warn", "pedantic": "off" } } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ categories: { correctness: "error", suspicious: "warn", pedantic: "off", }, }); ``` ::: Available categories include: * `correctness`: Code that is definitely wrong or useless * `suspicious`: Code that is likely to be wrong or useless * `pedantic`: Extra strict rules that may have false positives * `perf`: Rules that aim to improve runtime performance * `style`: Idiomatic and consistent style rules * `restriction`: Rules that ban specific patterns or features * `nursery`: Rules under development that may change You can also change categories from the CLI with the same `-A`, `-W`, and `-D` options: ```sh oxlint -D correctness -D suspicious ``` ## Configure plugins Plugins extend the set of available rules. Oxlint supports many popular plugins natively in Rust. This provides broad rule coverage without a large JavaScript dependency tree. See [Native Plugins](/docs/guide/usage/linter/plugins). Configure plugins using `plugins`. Setting `plugins` overwrites the default plugin set, so the array should include everything you want enabled: ::: code-group ```json [.oxlintrc.json] { "plugins": ["unicorn", "typescript", "oxc"] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ plugins: ["unicorn", "typescript", "oxc"], }); ``` ::: To disable all default plugins: ::: code-group ```json [.oxlintrc.json] { "plugins": [] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ plugins: [], }); ``` ::: For plugin details and CLI flags such as `--import-plugin`, see [Native Plugins](/docs/guide/usage/linter/plugins). ## Configure JS plugins (alpha) Oxlint also supports JavaScript plugins via `jsPlugins`. This is intended for compatibility with existing ESLint plugins and advanced integrations. Notes: * JS plugins are in alpha and not subject to semver. JS plugins can be declared as strings, or as objects with an alias: ::: code-group ```json [.oxlintrc.json] { "jsPlugins": [ "eslint-plugin-playwright", { "name": "my-eslint-react", "specifier": "eslint-plugin-react" } ] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ jsPlugins: [ "eslint-plugin-playwright", { name: "my-eslint-react", specifier: "eslint-plugin-react" }, ], }); ``` ::: Some plugin names are reserved because they are implemented natively in Rust (for example `react`, `unicorn`, `typescript`, `oxc`, `import`, `jest`, `vitest`, `jsx-a11y`, `nextjs`). If you need the JavaScript version of a reserved plugin, give it a custom `name` to avoid conflicts. For details, see [JS plugins](/docs/guide/usage/linter/js-plugins). ## Apply configuration by file pattern Use `overrides` to apply different configuration to different files, such as tests, scripts, or TypeScript-only paths. `overrides` is an array of objects. Each override can include: * `files`: glob patterns * `rules`: rule configuration (same shape as top-level `rules`) * `env`: environment configuration (same shape as top-level `env`) * `globals`: globals configuration (same shape as top-level `globals`) * `plugins`: optionally change what plugins are enabled for this override * `jsPlugins`: JS plugins for this override (alpha) Example: ::: code-group ```json [.oxlintrc.json] { "$schema": "./node_modules/oxlint/configuration_schema.json", "rules": { "no-console": "error" }, "overrides": [ { "files": ["scripts/*.js"], "rules": { "no-console": "off" } }, { "files": ["**/*.{ts,tsx}"], "plugins": ["typescript"], "rules": { "typescript/no-explicit-any": "error" } }, { "files": ["**/test/**"], "plugins": ["jest"], "env": { "jest": true }, "rules": { "jest/no-disabled-tests": "off" } } ] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ rules: { "no-console": "error", }, overrides: [ { files: ["scripts/*.js"], rules: { "no-console": "off", }, }, { files: ["**/*.{ts,tsx}"], plugins: ["typescript"], rules: { "typescript/no-explicit-any": "error", }, }, { files: ["**/test/**"], plugins: ["jest"], env: { jest: true, }, rules: { "jest/no-disabled-tests": "off", }, }, ], }); ``` ::: ## Extend shared configs Use `extends` to inherit from other configuration files. Paths in `extends` are resolved relative to the configuration file that declares `extends`. Configs are merged from first to last, with later entries overriding earlier ones. Use `oxlint.config.ts` when extending config objects imported from a shared package. Package imports are not supported in the `.oxlintrc.json` format. ::: code-group ```json [.oxlintrc.json] { "extends": ["./configs/base.json", "./configs/frontend.json"] } ``` ```ts [oxlint.config.ts] import baseConfig from "./configs/base.ts"; import frontendConfig from "./configs/frontend.ts"; import { defineConfig } from "oxlint"; export default defineConfig({ extends: [baseConfig, frontendConfig], }); ``` ::: For example, a shared package can export a config object that you import and extend: ```ts [oxlint.config.ts] import config from "@example-org/oxlint-config"; import { defineConfig } from "oxlint"; export default defineConfig({ extends: [config], }); ``` ## Configure environments and globals Use `env` to enable predefined globals for common environments such as browser or node. Use `globals` to declare project-specific globals, mark them writable or readonly, or disable a global that would otherwise be present. ::: code-group ```json [.oxlintrc.json] { "env": { "es6": true }, "globals": { "MY_GLOBAL": "readonly", "Promise": "off" } } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ env: { es6: true, }, globals: { MY_GLOBAL: "readonly", Promise: "off", }, }); ``` ::: `globals` accepts: * `"readonly"` or `"readable"` or `false` * `"writable"` or `"writeable"` or `true` * `"off"` to disable a global ## Plugin settings Use `settings` for plugin-wide configuration shared by multiple rules. Example (monorepo + React + jsx-a11y): ::: code-group ```json [.oxlintrc.json] { "settings": { "next": { "rootDir": "apps/dashboard/" }, "react": { "linkComponents": [{ "name": "Link", "linkAttribute": "to" }] }, "jsx-a11y": { "components": { "Link": "a", "Button": "button" } } } } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ settings: { next: { rootDir: "apps/dashboard/", }, react: { linkComponents: [{ name: "Link", linkAttribute: "to" }], }, "jsx-a11y": { components: { Link: "a", Button: "button", }, }, }, }); ``` ::: ## Next steps * [Ignore files](/docs/guide/usage/linter/ignore-files): Ignore files and patterns, `.gitignore` and `.eslintignore` workflows, and symlink behavior. * [Inline ignore comments](/docs/guide/usage/linter/ignore-comments): Inline suppressions and scoped exceptions. * [Nested configs](/docs/guide/usage/linter/nested-config): Monorepos and per-package configuration. * [Config file reference](/docs/guide/usage/linter/config-file-reference.html): Full schema and field documentation. * [CLI reference](/docs/guide/usage/linter/cli.html): Complete list of flags and output formats. --- --- url: /docs/guide/usage/formatter/config-file-reference.md --- # Configuration options for the Oxfmt. Most options are the same as Prettier's options, but not all of them. In addition, some options are our own extensions. ## arrowParens type: `"always" | "avoid"` Include parentheses around a sole arrow function parameter. * Languages: JS, JSX, TS, TSX * Default: `"always"` ## bracketSameLine type: `boolean` Put the `>` of a multi-line HTML (HTML, JSX, Vue, Angular) element at the end of the last line, instead of being alone on the next line (does not apply to self closing elements). * Languages: JSX, TSX, HTML, Angular, Vue, MJML, Svelte * Default: `false` ## bracketSpacing type: `boolean` Print spaces between brackets in object literals. * Languages: JS, JSX, TS, TSX, JSON, JSONC, JSON5, GraphQL, YAML * Default: `true` ## embeddedLanguageFormatting type: `"auto" | "off"` Control whether to format embedded parts (For example, CSS-in-JS, or JS-in-Vue, etc.) in the file. * Languages: JS, JSX, TS, TSX, HTML, Vue, Angular, Svelte, Markdown, MDX (languages with embedded code) * Default: `"auto"` ## endOfLine type: `"lf" | "crlf" | "cr"` Which end of line characters to apply. NOTE: `"auto"` is not supported. * Languages: All * Default: `"lf"` * Overrides `.editorconfig.end_of_line` ## htmlWhitespaceSensitivity type: `"css" | "strict" | "ignore"` Specify the global whitespace sensitivity for HTML, Vue, Angular, and Handlebars. * Languages: HTML, Angular, Vue, Handlebars, Svelte * Default: `"css"` ## ignorePatterns type: `string[]` Ignore files matching these glob patterns. Patterns use gitignore-style matching, rooted at the directory containing the configuration file. Files outside that directory cannot be matched; patterns containing `..` are rejected as a configuration error. * Default: `[]` ## insertFinalNewline type: `boolean` Whether to insert a final newline at the end of the file. * Languages: All * Default: `true` * Overrides `.editorconfig.insert_final_newline` ## jsdoc type: `object | boolean` Enable JSDoc comment formatting. When enabled, JSDoc comments are normalized and reformatted: tag aliases are canonicalized, descriptions are capitalized, long lines are wrapped, and short comments are collapsed to single-line. Pass `true` or an object to enable with defaults, or omit/set `false` to disable. * Languages: JS, JSX, TS, TSX * Default: Disabled ### jsdoc.addDefaultToDescription type: `boolean` Append default values to `@param` descriptions (e.g. "Default is `value`"). * Default: `true` ### jsdoc.bracketSpacing type: `boolean` Add spaces inside JSDoc type braces: `{string}` → `{ string }`. * Default: `false` ### jsdoc.capitalizeDescriptions type: `boolean` Capitalize the first letter of tag descriptions. * Default: `true` ### jsdoc.commentLineStrategy type: `"singleLine" | "multiline" | "keep"` How to format comment blocks. * `"singleLine"` — Convert to single-line `/** content */` when possible. * `"multiline"` — Always use multi-line format. * `"keep"` — Preserve original formatting. * Default: `"singleLine"` ### jsdoc.descriptionTag type: `boolean` Emit `@description` tag instead of inline description. * Default: `false` ### jsdoc.descriptionWithDot type: `boolean` Add a trailing dot to the end of descriptions. * Default: `false` ### jsdoc.keepUnparsableExampleIndent type: `boolean` Preserve indentation in unparsable `@example` code. * Default: `false` ### jsdoc.lineWrappingStyle type: `"greedy" | "balance"` Strategy for wrapping description lines at print width. * `"greedy"` — Always re-wrap text to fit within print width. * `"balance"` — Preserve original line breaks if all lines fit within print width. * Default: `"greedy"` ### jsdoc.preferCodeFences type: `boolean` Use fenced code blocks (` ``` `) instead of 4-space indentation for code without a language tag. * Default: `false` ### jsdoc.separateReturnsFromParam type: `boolean` Add a blank line between the last `@param` and `@returns`. * Default: `false` ### jsdoc.separateTagGroups type: `boolean` Add blank lines between different tag groups (e.g. between `@param` and `@returns`). * Default: `false` ## jsxSingleQuote type: `boolean` Use single quotes instead of double quotes in JSX. * Languages: JSX, TSX * Default: `false` ## objectWrap type: `"preserve" | "collapse"` How to wrap object literals when they could fit on one line or span multiple lines. By default, formats objects as multi-line if there is a newline prior to the first property. Authors can use this heuristic to contextually improve readability, though it has some downsides. * Languages: JS, JSX, TS, TSX, JSON, JSONC, JSON5 * Default: `"preserve"` ## overrides type: `array` File-specific overrides. When a file matches multiple overrides, the later override takes precedence (array order matters). * Default: `[]` ### overrides\[n] type: `object` #### overrides\[n].excludeFiles type: `string[]` Glob patterns to exclude from this override. A set of glob patterns. Patterns are matched against paths relative to the configuration file's directory. #### overrides\[n].files type: `string[]` Glob patterns to match files for this override. A set of glob patterns. Patterns are matched against paths relative to the configuration file's directory. #### overrides\[n].options type: `object` Format options to apply for matched files. ##### overrides\[n].options.arrowParens type: `"always" | "avoid"` Include parentheses around a sole arrow function parameter. * Languages: JS, JSX, TS, TSX * Default: `"always"` ##### overrides\[n].options.bracketSameLine type: `boolean` Put the `>` of a multi-line HTML (HTML, JSX, Vue, Angular) element at the end of the last line, instead of being alone on the next line (does not apply to self closing elements). * Languages: JSX, TSX, HTML, Angular, Vue, MJML, Svelte * Default: `false` ##### overrides\[n].options.bracketSpacing type: `boolean` Print spaces between brackets in object literals. * Languages: JS, JSX, TS, TSX, JSON, JSONC, JSON5, GraphQL, YAML * Default: `true` ##### overrides\[n].options.embeddedLanguageFormatting type: `"auto" | "off"` Control whether to format embedded parts (For example, CSS-in-JS, or JS-in-Vue, etc.) in the file. * Languages: JS, JSX, TS, TSX, HTML, Vue, Angular, Svelte, Markdown, MDX (languages with embedded code) * Default: `"auto"` ##### overrides\[n].options.endOfLine type: `"lf" | "crlf" | "cr"` Which end of line characters to apply. NOTE: `"auto"` is not supported. * Languages: All * Default: `"lf"` * Overrides `.editorconfig.end_of_line` ##### overrides\[n].options.htmlWhitespaceSensitivity type: `"css" | "strict" | "ignore"` Specify the global whitespace sensitivity for HTML, Vue, Angular, and Handlebars. * Languages: HTML, Angular, Vue, Handlebars, Svelte * Default: `"css"` ##### overrides\[n].options.insertFinalNewline type: `boolean` Whether to insert a final newline at the end of the file. * Languages: All * Default: `true` * Overrides `.editorconfig.insert_final_newline` ##### overrides\[n].options.jsdoc type: `object | boolean` Enable JSDoc comment formatting. When enabled, JSDoc comments are normalized and reformatted: tag aliases are canonicalized, descriptions are capitalized, long lines are wrapped, and short comments are collapsed to single-line. Pass `true` or an object to enable with defaults, or omit/set `false` to disable. * Languages: JS, JSX, TS, TSX * Default: Disabled ###### overrides\[n].options.jsdoc.addDefaultToDescription type: `boolean` Append default values to `@param` descriptions (e.g. "Default is `value`"). * Default: `true` ###### overrides\[n].options.jsdoc.bracketSpacing type: `boolean` Add spaces inside JSDoc type braces: `{string}` → `{ string }`. * Default: `false` ###### overrides\[n].options.jsdoc.capitalizeDescriptions type: `boolean` Capitalize the first letter of tag descriptions. * Default: `true` ###### overrides\[n].options.jsdoc.commentLineStrategy type: `"singleLine" | "multiline" | "keep"` How to format comment blocks. * `"singleLine"` — Convert to single-line `/** content */` when possible. * `"multiline"` — Always use multi-line format. * `"keep"` — Preserve original formatting. * Default: `"singleLine"` ###### overrides\[n].options.jsdoc.descriptionTag type: `boolean` Emit `@description` tag instead of inline description. * Default: `false` ###### overrides\[n].options.jsdoc.descriptionWithDot type: `boolean` Add a trailing dot to the end of descriptions. * Default: `false` ###### overrides\[n].options.jsdoc.keepUnparsableExampleIndent type: `boolean` Preserve indentation in unparsable `@example` code. * Default: `false` ###### overrides\[n].options.jsdoc.lineWrappingStyle type: `"greedy" | "balance"` Strategy for wrapping description lines at print width. * `"greedy"` — Always re-wrap text to fit within print width. * `"balance"` — Preserve original line breaks if all lines fit within print width. * Default: `"greedy"` ###### overrides\[n].options.jsdoc.preferCodeFences type: `boolean` Use fenced code blocks (` ``` `) instead of 4-space indentation for code without a language tag. * Default: `false` ###### overrides\[n].options.jsdoc.separateReturnsFromParam type: `boolean` Add a blank line between the last `@param` and `@returns`. * Default: `false` ###### overrides\[n].options.jsdoc.separateTagGroups type: `boolean` Add blank lines between different tag groups (e.g. between `@param` and `@returns`). * Default: `false` ##### overrides\[n].options.jsxSingleQuote type: `boolean` Use single quotes instead of double quotes in JSX. * Languages: JSX, TSX * Default: `false` ##### overrides\[n].options.objectWrap type: `"preserve" | "collapse"` How to wrap object literals when they could fit on one line or span multiple lines. By default, formats objects as multi-line if there is a newline prior to the first property. Authors can use this heuristic to contextually improve readability, though it has some downsides. * Languages: JS, JSX, TS, TSX, JSON, JSONC, JSON5 * Default: `"preserve"` ##### overrides\[n].options.printWidth type: `integer` Specify the line length that the printer will wrap on. If you don't want line wrapping when formatting Markdown, you can set the `proseWrap` option to disable it. * Languages: All * Default: `100` * Overrides `.editorconfig.max_line_length` ##### overrides\[n].options.proseWrap type: `"always" | "never" | "preserve"` How to wrap prose. By default, formatter will not change wrapping in markdown text since some services use a linebreak-sensitive renderer, e.g. GitHub comments and BitBucket. To wrap prose to the print width, change this option to "always". If you want to force all prose blocks to be on a single line and rely on editor/viewer soft wrapping instead, you can use "never". * Languages: Markdown, MDX, YAML * Default: `"preserve"` ##### overrides\[n].options.quoteProps type: `"as-needed" | "consistent" | "preserve"` Change when properties in objects are quoted. * Languages: JS, JSX, TS, TSX * Default: `"as-needed"` ##### overrides\[n].options.semi type: `boolean` Print semicolons at the ends of statements. * Languages: JS, JSX, TS, TSX * Default: `true` ##### overrides\[n].options.singleAttributePerLine type: `boolean` Enforce single attribute per line in HTML, Vue, and JSX. * Languages: JSX, TSX, HTML, Angular, Vue, MJML, Svelte * Default: `false` ##### overrides\[n].options.singleQuote type: `boolean` Use single quotes instead of double quotes. For JSX, you can set the `jsxSingleQuote` option. * Languages: JS, JSX, TS, TSX, CSS, Less, SCSS, Markdown, MDX, YAML, Handlebars, Svelte * Default: `false` * Overrides `.editorconfig.quote_type` ##### overrides\[n].options.sortImports type: `object | boolean` Sort import statements. Using the similar algorithm as [eslint-plugin-perfectionist/sort-imports](https://perfectionist.dev/rules/sort-imports). For details, see each field's documentation. Pass `true` or an object to enable with defaults, or omit/set `false` to disable. * Languages: JS, JSX, TS, TSX * Default: Disabled ###### overrides\[n].options.sortImports.customGroups type: `array` Define your own groups for matching very specific imports. The `customGroups` list is ordered: The first definition that matches an element will be used. Custom groups have a higher priority than any predefined group. If you want a predefined group to take precedence over a custom group, you must write a custom group definition that does the same as what the predefined group does, and put it first in the list. If you specify multiple conditions like `elementNamePattern`, `selector`, and `modifiers`, all conditions must be met for an import to match the custom group (AND logic). * Default: `[]` \####### overrides\[n].options.sortImports.customGroups\[n] type: `object` \######## overrides\[n].options.sortImports.customGroups\[n].elementNamePattern type: `string[]` default: `[]` List of glob patterns to match import sources for this group. \######## overrides\[n].options.sortImports.customGroups\[n].groupName type: `string` default: `""` Name of the custom group, used in the `groups` option. \######## overrides\[n].options.sortImports.customGroups\[n].modifiers type: `array` Modifiers to match the import characteristics. All specified modifiers must be present (AND logic). \######### overrides\[n].options.sortImports.customGroups\[n].modifiers\[n] type: `"side_effect" | "type" | "value" | "default" | "wildcard" | "named"` Modifier matching the import characteristics in `customGroups` (see `sortImports.groups` for semantics). \######## overrides\[n].options.sortImports.customGroups\[n].selector type: `"type" | "side_effect_style" | "side_effect" | "style" | "index" | "sibling" | "parent" | "subpath" | "internal" | "builtin" | "external" | "import"` Selector to match the import kind. ###### overrides\[n].options.sortImports.groups type: `array` Specifies a list of predefined import groups for sorting. Each import will be assigned a single group specified in the groups option (or the `unknown` group if no match is found). The order of items in the `groups` option determines how groups are ordered. Within a given group, members will be sorted according to the type, order, ignoreCase, etc. options. Individual groups can be combined together by placing them in an array. The order of groups in that array does not matter. All members of the groups in the array will be sorted together as if they were part of a single group. Predefined groups are characterized by a single selector and potentially multiple modifiers. You may enter modifiers in any order, but the selector must always come at the end. The list of selectors is sorted from most to least important: * `type` — TypeScript type imports. * `side_effect_style` — Side effect style imports. * `side_effect` — Side effect imports. * `style` — Style imports. * `index` — Main file from the current directory. * `sibling` — Modules from the same directory. * `parent` — Modules from the parent directory. * `subpath` — Node.js subpath imports. * `internal` — Your internal modules. * `builtin` — Node.js Built-in Modules. * `external` — External modules installed in the project. * `import` — Any import. The list of modifiers is sorted from most to least important: * `side_effect` — Side effect imports. * `type` — TypeScript type imports. * `value` — Value imports. * `default` — Imports containing the default specifier. * `wildcard` — Imports containing the wildcard (`* as`) specifier. * `named` — Imports containing at least one named specifier. * Default: See below ```json ["builtin", "external", ["internal", "subpath"], ["parent", "sibling", "index"], "style", "unknown"] ``` Also, you can override the global `newlinesBetween` setting for specific group boundaries by including a `{ "newlinesBetween": boolean }` marker object in the `groups` list at the desired position. \####### overrides\[n].options.sortImports.groups\[n] type: `object | array | string` \######## overrides\[n].options.sortImports.groups\[n].newlinesBetween type: `boolean` ###### overrides\[n].options.sortImports.ignoreCase type: `boolean` Specifies whether sorting should be case-sensitive. * Default: `true` ###### overrides\[n].options.sortImports.internalPattern type: `string[]` Specifies a prefix for identifying internal imports. This is useful for distinguishing your own modules from external dependencies. * Default: `["~/", "@/", "#"]` ###### overrides\[n].options.sortImports.newlinesBetween type: `boolean` Specifies whether to add newlines between groups. When `false`, no newlines are added between groups. * Default: `true` ###### overrides\[n].options.sortImports.order type: `"asc" | "desc"` Specifies whether to sort items in ascending or descending order. * Default: `"asc"` ###### overrides\[n].options.sortImports.partitionByComment type: `boolean` Enables the use of comments to separate imports into logical groups. When `true`, all comments will be treated as delimiters, creating partitions. ```js import { b1, b2 } from "b"; // PARTITION import { a } from "a"; import { c } from "c"; ``` * Default: `false` ###### overrides\[n].options.sortImports.partitionByNewline type: `boolean` Enables the empty line to separate imports into logical groups. When `true`, formatter will not sort imports if there is an empty line between them. This helps maintain the defined order of logically separated groups of members. ```js import { b1, b2 } from "b"; import { a } from "a"; import { c } from "c"; ``` * Default: `false` ###### overrides\[n].options.sortImports.sortSideEffects type: `boolean` Specifies whether side effect imports should be sorted. By default, sorting side-effect imports is disabled for security reasons. * Default: `false` ##### overrides\[n].options.sortPackageJson type: `object | boolean` Sort `package.json` keys. The algorithm is NOT compatible with [prettier-plugin-sort-packagejson](https://github.com/matzkoh/prettier-plugin-packagejson). But we believe it is clearer and easier to navigate. For details, see each field's documentation. * Languages: JSON (`package.json` only) * Default: `true` ###### overrides\[n].options.sortPackageJson.sortScripts type: `boolean` Sort the `scripts` field alphabetically. * Default: `false` ##### overrides\[n].options.sortTailwindcss type: `object | boolean` Sort Tailwind CSS classes. Using the same algorithm as [prettier-plugin-tailwindcss](https://github.com/tailwindlabs/prettier-plugin-tailwindcss). Option names omit the `tailwind` prefix used in the original plugin (e.g., `config` instead of `tailwindConfig`). For details, see each field's documentation. Pass `true` or an object to enable with defaults, or omit/set `false` to disable. * Languages: JS, JSX, TS, TSX, HTML, Vue, Angular, Handlebars, CSS, SCSS, Less, Svelte * Default: Disabled ###### overrides\[n].options.sortTailwindcss.attributes type: `string[]` List of additional attributes to sort beyond `class` and `className` (exact match). NOTE: Regex patterns are not yet supported. * Default: `[]` * Example: `["myClassProp", ":class"]` ###### overrides\[n].options.sortTailwindcss.config type: `string` Path to your Tailwind CSS configuration file (v3). NOTE: Paths are resolved relative to the Oxfmt configuration file. * Default: Automatically find `"tailwind.config.js"` ###### overrides\[n].options.sortTailwindcss.functions type: `string[]` List of custom function names whose arguments should be sorted (exact match). NOTE: Regex patterns are not yet supported. * Default: `[]` * Example: `["clsx", "cn", "cva", "tw"]` ###### overrides\[n].options.sortTailwindcss.preserveDuplicates type: `boolean` Preserve duplicate classes. * Default: `false` ###### overrides\[n].options.sortTailwindcss.preserveWhitespace type: `boolean` Preserve whitespace around classes. * Default: `false` ###### overrides\[n].options.sortTailwindcss.stylesheet type: `string` Path to your Tailwind CSS stylesheet (v4). NOTE: Paths are resolved relative to the Oxfmt configuration file. * Default: Installed Tailwind CSS's `theme.css` ##### overrides\[n].options.svelte type: `object | boolean` Options for `prettier-plugin-svelte`. Pass `true` or an object to enable `.svelte` file formatting, or `false` (handy in overrides) / omit to disable. Setting `true` resets to defaults — any options inherited from a parent scope are dropped. NOTE: `prettier-plugin-svelte` requires the `svelte` package (`svelte/compiler`) at runtime, but Oxfmt does NOT bundle or auto-install it. You must install `svelte` yourself in your project, formatting will fail at runtime otherwise. * Languages: Svelte * Default: Disabled ###### overrides\[n].options.svelte.allowShorthand type: `boolean` Whether to allow attribute shorthand if attribute name and expression are same. * Default: `true` ###### overrides\[n].options.svelte.indentScriptAndStyle type: `boolean` Whether to indent code inside ` ``` --- --- url: /endorsements.md --- # Endorsements ### [Evan You](https://x.com/youyuxi/status/1734439543280128030), creator of [Vue.js](https://vuejs.org) and [Vite](https://vitejs.dev): > Ran oxlint on the Vue 3 codebase, ~200 rules + ~590 files finished in 50ms 🤯 (30ms re-runs) > > The performance is absolutely nuts ### [Jason Miller](https://github.com/developit), creator of [Preact](https://preactjs.com): > oxlint has been a massive win for us at Shopify. Our previous linting setup took 75 minutes to run, so we were fanning it out across 40+ workers in CI. > > By comparison, oxlint takes around 10 seconds to lint the same codebase on a single worker, and the output is easier to interpret. > > We even caught a few bugs that were hidden or skipped by our old setup when we migrated! ### [Luke Edwards](https://x.com/lukeed05/status/1829527267162345651) > For a while now, @boshen\_c has been crushing it, setting the foundation for the next generation of JS tooling. > > There's just so much to learn from the OXC source code. Everything is meticulously measured and benchmarked, then formalized into simple, elegant, non-frightening APIs. > > This guy is brilliant, a team player, and is + has been doing thankless, hard work. ### [Yagiz Nizipli](https://github.com/sponsors/anonrig), founder of [Node.js performance team](https://github.com/nodejs/performance): > I'm impressed by how oxc is actively encouraging JavaScript tools to improve their performance. ### [Eric Simons](https://x.com/ericsimons40/status/1766525300584947999), CEO of [StackBlitz](https://stackblitz.com/): > Oxc is slept on rn > > Most JS/TS toolchains will be using it within the next few yrs imo ### [Miles Johnson](https://x.com/mileswjohnson/status/1734698340791800283), creator of [Moonrepo](https://moonrepo.dev): > It's crazy how good oxlint (and oxc tools) is. Not just in performance, but ease of use. Banking on Rust was a good choice! ### [Joe Savona](https://x.com/en_JS/status/1676467920334094336), [React](https://react.dev) team member: > For…reasons I am experimenting w various Rust-based JS compilers. I don’t agree w every design decision but overall oxc is really well done. ### [Sathya Gunasekaran](https://x.com/_gsathya/status/1676453430263701506), [React](https://react.dev) team member: > oxc is kinda neat --- --- url: /docs/guide/usage/linter/rules/eslint/accessor-pairs.md --- ### What it does Enforces getter/setter pairs in objects and classes. ### Why is this bad? It's a common mistake in JavaScript to create an object with just a setter for a property but never have a corresponding getter defined for it. Without a getter, you cannot read the property, so it ends up not being used. ### Examples Examples of **incorrect** code for this rule: ```js var o = { set a(value) { this.val = value; }, }; class C { set a(value) { this.val = value; } } ``` Examples of **correct** code for this rule: ```js var o = { set a(value) { this.val = value; }, get a() { return this.val; }, }; class C { set a(value) { this.val = value; } get a() { return this.val; } } ``` ## Configuration This rule accepts a configuration object with the following properties: ### enforceForClassMembers type: `boolean` default: `true` Enforce the rule for class members. ### enforceForTSTypes type: `boolean` default: `false` Enforce the rule for TypeScript interfaces and types. ### getWithoutSet type: `boolean` default: `false` Report a getter without a setter. ### setWithoutGet type: `boolean` default: `true` Report a setter without a getter. ## How to use ## Version This rule was added in v1.33.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/array-callback-return.md --- ### What it does Enforce return statements in callbacks of array methods. ### Why is this bad? Array has several methods for filtering, mapping, and folding. If we forget to write return statement in a callback of those, it’s probably a mistake. If you don’t want to use a return or don’t need the returned results, consider using .forEach instead. ### Examples Examples of **incorrect** code for this rule: ```javascript let foo = [1, 2, 3, 4]; foo.map((a) => { console.log(a); }); ``` Examples of **correct** code for this rule: ```javascript let foo = [1, 2, 3, 4]; foo.map((a) => { console.log(a); return a; }); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowImplicit type: `boolean` default: `false` When set to true, allows callbacks of methods that require a return value to implicitly return undefined with a return statement containing no expression. ### allowVoid type: `boolean` default: `false` When set to true, rule will not report the return value with a void operator. Works only if `checkForEach` option is set to true. ### checkForEach type: `boolean` default: `false` When set to true, rule will also report forEach callbacks that return a value. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/arrow-body-style.md --- ### What it does This rule can enforce or disallow the use of braces around arrow function body. Arrow functions can use either: * a block body `() => { ... }` * or a concise body `() => expression` with an implicit return. ### Why is this bad? Inconsistent use of block vs. concise bodies makes code harder to read. Concise bodies are limited to a single expression, whose value is implicitly returned. ### Examples #### `"never"` Examples of **incorrect** code for this rule with the `never` option: ```js /* arrow-body-style: ["error", "never"] */ /* ✘ Bad: */ const foo = () => { return 0; }; ``` Examples of **correct** code for this rule with the `never` option: ```js /* arrow-body-style: ["error", "never"] */ /* ✔ Good: */ const foo = () => 0; const bar = () => ({ foo: 0 }); ``` #### `"always"` Examples of **incorrect** code for this rule with the `always` option: ```js /* arrow-body-style: ["error", "always"] */ /* ✘ Bad: */ const foo = () => 0; ``` Examples of **correct** code for this rule with the `always` option: ```js /* arrow-body-style: ["error", "always"] */ /* ✔ Good: */ const foo = () => { return 0; }; ``` #### `"as-needed"` (default) Examples of **incorrect** code for this rule with the `as-needed` option: ```js /* arrow-body-style: ["error", "as-needed"] */ /* ✘ Bad: */ const foo = () => { return 0; }; ``` Examples of **correct** code for this rule with the `as-needed` option: ```js /* arrow-body-style: ["error", "as-needed"] */ /* ✔ Good: */ const foo1 = () => 0; const foo2 = (retv, name) => { retv[name] = true; return retv; }; const foo3 = () => { bar(); }; ``` #### `"as-needed"` with `requireReturnForObjectLiteral` Examples of **incorrect** code for this rule with the `{ "requireReturnForObjectLiteral": true }` option: ```js /* arrow-body-style: ["error", "as-needed", { "requireReturnForObjectLiteral": true }] */ /* ✘ Bad: */ const foo = () => ({}); const bar = () => ({ bar: 0 }); ``` Examples of **correct** code for this rule with the `{ "requireReturnForObjectLiteral": true }` option: ```js /* arrow-body-style: ["error", "as-needed", { "requireReturnForObjectLiteral": true }] */ /* ✔ Good: */ const foo = () => {}; const bar = () => { return { bar: 0 }; }; ``` ## Configuration ### The 1st option type: `"as-needed" | "always" | "never"` #### `"as-needed"` Enforces no braces where they can be omitted (default). #### `"always"` Enforces braces around the function body. #### `"never"` Enforces no braces around the function body (constrains arrow functions to the role of returning an expression). ### The 2nd option This option is an object with the following properties: #### requireReturnForObjectLiteral type: `boolean` default: `false` Requires braces and an explicit return for object literals. This option only applies when the first option is `"as-needed"`. ## How to use ## Version This rule was added in v1.4.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/block-scoped-var.md --- ### What it does Enforces that variables are both **declared** and **used** within the same block scope. This rule prevents accidental use of variables outside their intended block, mimicking C-style block scoping in JavaScript. ### Why is this bad? JavaScript’s `var` declarations are hoisted to the top of their enclosing function, which can cause variables declared in a block (e.g., inside an `if` or `for`) to be accessible outside of it. This can lead to hard-to-find bugs. By enforcing block scoping, this rule helps avoid hoisting issues and aligns more closely with how other languages treat block variables. ### Examples Examples of **incorrect** code for this rule: ```js /* block-scoped-var: "error" */ function doIf() { if (true) { var build = true; } console.log(build); } function doLoop() { for (var i = 0; i < 10; i++) { // do something } console.log(i); // i is accessible here } function doSomething() { if (true) { var foo = 1; } if (false) { foo = 2; } } function doTry() { try { var foo = 1; } catch (e) { console.log(foo); } } ``` Examples of **correct** code for this rule: ```js /* block-scoped-var: "error" */ function doIf() { var build; if (true) { build = true; } console.log(build); } function doLoop() { var i; for (i = 0; i < 10; i++) { // do something } console.log(i); } function doSomething() { var foo; if (true) { foo = 1; } if (false) { foo = 2; } } function doTry() { var foo; try { foo = 1; } catch (e) { console.log(foo); } } ``` ## How to use ## Version This rule was added in v0.16.9. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/capitalized-comments.md --- ### What it does Enforces or disallows capitalization of the first letter of a comment. ### Why is this bad? Inconsistent capitalization of comments can make code harder to read. This rule helps enforce a consistent style across the codebase. ### Examples Examples of **incorrect** code for this rule with the default `"always"` option: ```js // lowercase comment /* lowercase block comment */ ``` Examples of **correct** code for this rule with the default `"always"` option: ```js // Capitalized comment /* Capitalized block comment */ // 123 - comments starting with non-letters are ignored ``` ## Configuration Configuration for the capitalized-comments rule. The first element specifies whether comments should `"always"` or `"never"` begin with a capital letter. The second element is an optional object containing additional options. ### The 1st option type: `"always" | "never"` ### The 2nd option This option is an object with the following properties: #### ignoreConsecutiveComments type: `boolean` If true, consecutive comments will be ignored after the first comment. #### ignoreInlineComments type: `boolean` If true, inline comments (comments in the middle of code) will be ignored. #### ignorePattern type: `string` A regex pattern. Comments that match the pattern will not cause violations. ## How to use ## Version This rule was added in v1.34.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/class-methods-use-this.md --- ### What it does Enforce that class methods utilize `this`. ### Why is this bad? For class methods that do not use `this`, you should consider converting them to `static` methods. This is not always possible or desirable, but it can help clarify that the method does not rely on instance state. If you do convert the method into a `static` function, instances of the class that call that particular method have to be converted to a `static` call as well. ### Examples Examples of **incorrect** code for this rule: ```js class A { foo() { console.log("Hello World"); } } ``` Examples of **correct** code for this rule: ```js class A { foo() { this.bar = "Hello World"; // OK, this is used } } class B { constructor() { // OK. constructor is exempt } } class C { static foo() { // OK. static methods aren't expected to use this. } } ``` ## Configuration This rule accepts a configuration object with the following properties: ### enforceForClassFields type: `boolean` default: `true` Enforce this rule for class fields that are functions. ### exceptMethods type: `string[]` default: `[]` List of method names to exempt from this rule. Names can include the hash for private methods. Example: `save`, `#rerender` ### ignoreClassesWithImplements type: `"all" | "public-fields"` default: `null` Whether to ignore classes that implement interfaces. ### ignoreOverrideMethods type: `boolean` default: `false` Whether to ignore methods that are overridden. ## How to use ## Version This rule was added in v1.16.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/complexity.md --- ### What it does Enforces a maximum [cyclomatic complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) in a program, which is the number of linearly independent paths in a program. ### Why is this bad? Having high code complexity reduces code readability. This rule aims to make the code easier to follow by reducing the number of branches in the program. ### Examples Examples of **incorrect** code for this rule with `{ "max": 2 }` ```js function foo() { if (foo1) { return x1; // 1st path } else if (foo2) { return x2; // 2nd path } else { return x3; // 3rd path } } function bar() { // there are 2 paths - when bar1 is falsy, and when bar1 is truthy, in which bar1 = bar1 && bar2; bar1 &&= bar2; // there are 2 paths - when bar3 is truthy, and when bar3 is falsy, in which bar3 = 4; bar3 ||= 4; } // there are 2 paths - when baz1 is defined, and when baz1 is undefined and is assigned 'a' function baz(baz1 = "a") { const { baz2 = "b" } = baz3; // there are 2 additional paths - when baz2 is defined and when baz2 is not } function d() { d1 = d2?.d3?.(); // optional chaining creates 2 paths each - when object is defined and when it is not } ``` Examples of **correct** code for this rule with `{ "max": 2 }` ```js // This example is taken directly from ESLint documentation function foo() { // this function has complexity = 1 class C { x = a + b; // this initializer has complexity = 1 y = c || d; // this initializer has complexity = 2 z = e && f; // this initializer has complexity = 2 static p = g || h; // this initializer has complexity = 2 static q = i ? j : k; // this initializer has complexity = 2 static { // this static block has complexity = 2 if (foo) { baz = bar; } } static { // this static block has complexity = 2 qux = baz || quux; } } } ``` ## Configuration ### max type: `integer` default: `20` Maximum amount of cyclomatic complexity ### variant type: `"classic" | "modified"` The cyclomatic complexity variant to use #### `"classic"` Classic means McCabe cyclomatic complexity #### `"modified"` Modified means classic cyclomatic complexity but a switch statement increases complexity by 1 irrespective of the number of `case` statements ## How to use ## Version This rule was added in v1.37.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/constructor-super.md --- ### What it does Requires `super()` calls in constructors of derived classes and disallows `super()` calls in constructors of non-derived classes. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? In JavaScript, calling `super()` in the constructor of a derived class (a class that extends another class) is required. Failing to do so will result in a ReferenceError at runtime. Conversely, calling `super()` in a non-derived class is a syntax error. ### Examples Examples of **incorrect** code for this rule: ```js // Missing super() call class A extends B { constructor() { } } // super() in non-derived class class A { constructor() { super(); } } // super() only in some code paths class C extends D { constructor() { if (condition) { super(); } } } ``` Examples of **correct** code for this rule: ```js // Proper super() call in derived class class A extends B { constructor() { super(); } } // No super() in non-derived class class A { constructor() {} } // super() in all code paths class C extends D { constructor() { if (condition) { super(); } else { super(); } } } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/curly.md --- ### What it does This rule enforces the use of curly braces `{}` for all control statements (`if`, `else`, `for`, `while`, `do`, `with`). It ensures that all blocks are enclosed in curly braces to improve code clarity and maintainability. ### Why is this bad? Omitting curly braces can reduce code readability and increase the likelihood of errors, especially in deeply nested or indented code. It can also lead to bugs if additional statements are added later without properly enclosing them in braces. Using curly braces consistently makes the code safer and easier to modify. ### Examples #### `"all"` (default) Examples of **incorrect** code for this rule: ```js /* curly: ["error", "all"] */ if (foo) foo++; while (bar) bar--; do foo(); while (bar); ``` Examples of **correct** code for this rule: ```js /* curly: ["error", "all"] */ if (foo) { foo++; } while (bar) { bar--; } do { foo(); } while (bar); ``` #### `"multi"` Examples of **incorrect** code for this rule with the `"multi"` option: ```js /* curly: ["error", "multi"] */ if (foo) { foo(); } if (foo) bar(); else { foo(); } ``` Examples of **correct** code for this rule with the `"multi"` option: ```js /* curly: ["error", "multi"] */ if (foo) foo(); else bar(); ``` #### `"multi-line"` Examples of **incorrect** code for this rule with the `"multi-line"` option: ```js /* curly: ["error", "multi-line"] */ if (foo) foo(); else bar(); if (foo) foo(bar, baz); ``` Examples of **correct** code for this rule with the `"multi-line"` option: ```js /* curly: ["error", "multi-line"] */ if (foo) foo(); else bar(); while (foo) foo(); while (true) { doSomething(); doSomethingElse(); } ``` #### `"multi-or-nest"` Examples of **incorrect** code for this rule with the `"multi-or-nest"` option: ```js /* curly: ["error", "multi-or-nest"] */ while (true) if (foo) foo(); else bar(); if (foo) { foo++; } ``` Examples of **correct** code for this rule with the `"multi-or-nest"` option: ```js /* curly: ["error", "multi-or-nest"] */ if (foo) { if (bar) bar(); } while (foo) { while (bar) bar(); } ``` #### `"consistent"` When enabled, `"consistent"` enforces consistent use of braces within an `if-else` chain. If one branch of the chain uses braces, then all branches must use braces, even if not strictly required by the first option. Examples of **incorrect** code with `"multi"` and `"consistent"`: ```js /* curly: ["error", "multi", "consistent"] */ if (foo) { bar(); baz(); } else qux(); if (foo) bar(); else { baz(); qux(); } ``` Examples of **correct** code with `"multi"` and `"consistent"`: ```js /* curly: ["error", "multi", "consistent"] */ if (foo) { bar(); baz(); } else { qux(); } if (foo) { bar(); } else { baz(); qux(); } ``` Examples of **incorrect** code with `"multi-line"` and `"consistent"`: ```js /* curly: ["error", "multi-line", "consistent"] */ if (foo) { bar(); } else baz(); ``` Examples of **correct** code with `"multi-line"` and `"consistent"`: ```js /* curly: ["error", "multi-line", "consistent"] */ if (foo) { bar(); } else { baz(); } ``` Examples of **incorrect** code with `"multi-or-nest"` and `"consistent"`: ```js /* curly: ["error", "multi-or-nest", "consistent"] */ if (foo) { if (bar) baz(); } else qux(); ``` Examples of **correct** code with `"multi-or-nest"` and `"consistent"`: ```js /* curly: ["error", "multi-or-nest", "consistent"] */ if (foo) { if (bar) baz(); } else { qux(); } ``` ## Configuration Configuration for the curly rule, specified as an array of one or two elements. Examples: * `["all"]` - Require braces in all cases (default) * `["multi"]` - Require braces only for multi-statement blocks * `["multi-line"]` - Require braces for multi-line blocks * `["multi-or-nest"]` - Require braces for nested or multi-line blocks * `["multi", "consistent"]` - Multi mode with consistent braces in if-else chains ### The 1st option type: `"all" | "multi" | "multi-line" | "multi-or-nest"` The enforcement type for the curly rule. #### `"all"` Require braces in all cases (default) #### `"multi"` Require braces only when there are multiple statements in the block #### `"multi-line"` Require braces when the block spans multiple lines #### `"multi-or-nest"` Require braces when the block is nested or spans multiple lines ### The 2nd option type: `"consistent"` ## How to use ## Version This rule was added in v0.15.13. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/default-case.md --- ### What it does Enforces that all `switch` statements include a `default` case, unless explicitly marked with a configured comment. ### Why is this bad? Without a `default` case, it is unclear whether the omission was intentional or an oversight. Adding a `default` or a special comment makes the code more explicit and reduces mistakes. You may optionally include a `// no default` after the last case if there is no default case. The comment may be in any desired case, such as `// No Default`. Example configuration: ```json { "default-case": ["error", { "commentPattern": "^skip\\sdefault" }] } ``` ### Examples Examples of **incorrect** code for this rule: ```js switch (foo) { case 1: break; } ``` Examples of **correct** code for this rule: ```js switch (a) { case 1: break; default: break; } switch (a) { case 1: break; // no default } ``` ## Configuration This rule accepts a configuration object with the following properties: ### commentPattern type: `string` A regex pattern used to detect comments that mark the absence of a `default` case as intentional. Default value: `no default`. Examples of **incorrect** code for this rule with the `{ "commentPattern": "^skip\\sdefault" }` option: ```js switch (a) { case 1: break; // no default } ``` Examples of **correct** code for this rule with the `{ "commentPattern": "^skip\\sdefault" }` option: ```js switch (a) { case 1: break; // skip default } ``` ## How to use ## Version This rule was added in v0.4.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/default-case-last.md --- ### What it does Requires the `default` clause in `switch` statements to be the last one. ### Why is this bad? By convention and for readability, the `default` clause should be the last one in a `switch`. While it is legal to place it before or between `case` clauses, doing so is confusing and may lead to unexpected "fall-through" behavior. ### Examples Examples of **incorrect** code for this rule: ```js /* default-case-last: "error" */ switch (foo) { default: bar(); break; case "a": baz(); break; } switch (foo) { case 1: bar(); break; default: baz(); break; case 2: qux(); break; } ``` Examples of **correct** code for this rule: ```js /* default-case-last: "error" */ switch (foo) { case 1: bar(); break; case 2: qux(); break; default: baz(); break; } switch (foo) { case "x": bar(); break; case "y": default: baz(); break; } ``` ## How to use ## Version This rule was added in v0.0.16. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/default-param-last.md --- ### What it does Requires default parameters in functions to be the last ones. ### Why is this bad? Placing default parameters last allows function calls to omit optional trailing arguments, which improves readability and consistency. This rule applies equally to JavaScript and TypeScript functions. ### Examples Examples of **incorrect** code for this rule: ```js /* default-param-last: "error" */ function f(a = 0, b) {} function f(a, b = 0, c) {} function createUser(isAdmin = false, id) {} createUser(undefined, "tabby"); ``` Examples of **correct** code for this rule: ```js /* default-param-last: "error" */ function f(a, b = 0) {} function f(a = 0, b = 0) {} function createUser(id, isAdmin = false) {} createUser("tabby"); ``` Examples of **incorrect** TypeScript code for this rule: ```ts /* default-param-last: "error" */ function greet(message: string = "Hello", name: string) {} function combine(a: number = 1, b: number, c: number) {} function combine(a: number, b: number = 2, c: number) {} function combine(a: number = 1, b?: number, c: number) {} ``` Examples of **correct** TypeScript code for this rule: ```ts /* default-param-last: "error" */ function greet(name: string, message: string = "Hello") {} function combine(a: number, b: number = 2, c: number = 3) {} function combine(a: number, b?: number, c: number = 3) {} ``` ## How to use ## Version This rule was added in v0.2.15. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/eqeqeq.md --- ### What it does Requires the use of the `===` and `!==` operators, disallowing the use of `==` and `!=`. ### Why is this bad? Using non-strict equality operators leads to unexpected behavior due to type coercion, which can cause hard-to-find bugs. ### Examples Example JSON configuration: ```json { "eqeqeq": ["error", "always", { "null": "ignore" }] } ``` #### `"always"` (default) Examples of **incorrect** code for this rule: ```js /* eqeqeq: "error" */ if (x == 42) { } if ("" == text) { } if (obj.getStuff() != undefined) { } ``` Examples of **correct** code for this rule: ```js /* eqeqeq: "error" */ if (x === 42) { } if ("" === text) { } if (obj.getStuff() !== undefined) { } ``` #### `"smart"` Examples of **incorrect** code for this rule with the `"smart"` option: ```js /* eqeqeq: ["error", "smart"] */ if (x == 42) { } if ("" == text) { } ``` Examples of **correct** code for this rule with the `"smart"` option: ```js /* eqeqeq: ["error", "smart"] */ if (typeof foo == "undefined") { } if (foo == null) { } if (foo != null) { } ``` #### `{"null": "ignore"}` (with `"always"` first option) Examples of **incorrect** code for this rule with the `{ "null": "ignore" }` option: ```js /* eqeqeq: ["error", "always", { "null": "ignore" }] */ if (x == 42) { } if ("" == text) { } ``` Examples of **correct** code for this rule with the `{ "null": "ignore" }` option: ```js /* eqeqeq: ["error", "always", { "null": "ignore" }] */ if (foo == null) { } if (foo != null) { } ``` #### `{"null": "always"}` (default - with `"always"` first option) Examples of **incorrect** code for this rule with the `{ "null": "always" }` option: ```js /* eqeqeq: ["error", "always", { "null": "always" }] */ if (foo == null) { } if (foo != null) { } ``` Examples of **correct** code for this rule with the `{ "null": "always" }` option: ```js /* eqeqeq: ["error", "always", { "null": "always" }] */ if (foo === null) { } if (foo !== null) { } ``` #### `{"null": "never"}` (with `"always"` first option) Examples of **incorrect** code for this rule with the `{ "null": "never" }` option: ```js /* eqeqeq: ["error", "always", { "null": "never" }] */ if (x == 42) { } if ("" == text) { } if (foo === null) { } if (foo !== null) { } ``` Examples of **correct** code for this rule with the `{ "null": "never" }` option: ```js /* eqeqeq: ["error", "always", { "null": "never" }] */ if (x === 42) { } if ("" === text) { } if (foo == null) { } if (foo != null) { } ``` ## Configuration ### The 1st option type: `"always" | "smart"` #### `"always"` Always require triple-equal comparisons, `===`/`!==`. This is the default. #### `"smart"` Allow certain safe comparisons to use `==`/`!=` (`typeof`, literals, nullish). ### The 2nd option This option is an object with the following properties: #### null type: `"always" | "never" | "ignore"` Configuration for whether to allow/disallow comparisons against `null`, e.g. `foo == null` or `foo != null` ##### `"always"` Always require triple-equals when comparing with null, `=== null`/`!== null`. This is the default. ##### `"never"` Never require triple-equals when comparing with null, always use `== null`/`!= null`. ##### `"ignore"` Ignore null comparisons, allow either `== null`/`!= null` or `=== null`/`!== null`. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/for-direction.md --- ### What it does Disallow `for` loops where the update clause moves the counter in the wrong direction, preventing the loop from reaching its stop condition. ### Why is this bad? A `for` loop with a stop condition that can never be reached will run infinitely. While infinite loops can be intentional, they are usually written as `while` loops. More often, an infinite `for` loop is a bug. ### Examples Examples of **incorrect** code for this rule: ```js /* for-direction: "error" */ for (var i = 0; i < 10; i--) {} for (var i = 10; i >= 0; i++) {} for (var i = 0; i > 10; i++) {} for (var i = 0; 10 > i; i--) {} const n = -2; for (let i = 0; i < 10; i += n) {} ``` Examples of **correct** code for this rule: ```js /* for-direction: "error" */ for (var i = 0; i < 10; i++) {} for (var i = 0; 10 > i; i++) { // with counter "i" on the right } for (let i = 10; i >= 0; i += this.step) { // direction unknown } for (let i = MIN; i <= MAX; i -= 0) { // not increasing or decreasing } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/func-name-matching.md --- ### What it does Requires function expression names to match the variable or property names they are assigned to, or disallows such matches with `"never"`. ### Why is this bad? Matching names keep stack traces and source code easier to connect. If a project prefers distinct names, the `"never"` option enforces that convention consistently. ### Examples Examples of **incorrect** code for this rule: ```js /*eslint func-name-matching: "error"*/ let foo = function bar() {}; foo = function bar() {}; const obj = { foo: function bar() {} }; obj.foo = function bar() {}; obj["foo"] = function bar() {}; class C { foo = function bar() {}; } /*eslint func-name-matching: ["error", "never"] */ let foo = function foo() {}; foo = function foo() {}; const obj = { foo: function foo() {} }; obj.foo = function foo() {}; obj["foo"] = function foo() {}; class C { foo = function foo() {}; } ``` Examples of **correct** code for this rule: ```js /*eslint func-name-matching: "error"*/ // equivalent to /*eslint func-name-matching: ["error", "always"]*/ const foo = function foo() {}; const foo1 = function () {}; const foo2 = () => {}; foo = function foo() {}; const obj = { foo: function foo() {} }; obj.foo = function foo() {}; obj["foo"] = function foo() {}; const obj1 = { [foo]: function bar() {} }; const obj3 = { foo: function () {} }; obj["x" + 2] = function bar() {}; const [bar] = [function bar() {}]; class C { foo = function foo() {}; baz = function () {}; } // private names are ignored class D { #foo = function foo() {}; #bar = function foo() {}; baz() { this.#foo = function foo() {}; this.#foo = function bar() {}; } } module.exports = function foo(name) {}; /*eslint func-name-matching: ["error", "never"] */ let foo = function bar() {}; const foo1 = function () {}; const foo2 = () => {}; foo = function bar() {}; const obj = { foo: function bar() {} }; obj.foo = function bar() {}; obj["foo"] = function bar() {}; const obj1 = { foo: function bar() {} }; const obj2 = { [foo]: function foo() {} }; const obj4 = { foo: function () {} }; obj["x" + 2] = function bar() {}; const [bar] = [function bar() {}]; class C { foo = function bar() {}; baz = function () {}; } // private names are ignored class D { #foo = function foo() {}; #bar = function foo() {}; baz() { this.#foo = function foo() {}; this.#foo = function bar() {}; } } module.exports = function foo(name) {}; ``` ## Configuration ### \[0] type: `"always" | "never"` ### \[1] type: `object` #### \[1].considerPropertyDescriptor type: `boolean` default: `false` If `considerPropertyDescriptor` is set to `true`, the check will take into account the use of `Object.create`, `Object.defineProperty`, `Object.defineProperties`, and `Reflect.defineProperty`. #### \[1].includeCommonJSModuleExports type: `boolean` default: `false` If `includeCommonJSModuleExports` is set to `true`, `module.exports` and `module["exports"]` will be checked by this rule. ## How to use ## Version This rule was added in v1.62.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/func-names.md --- ### What it does Require or disallow named function expressions. ### Why is this bad? Leaving the name off a function will cause `` to appear in stack traces of errors thrown in it or any function called within it. This makes it more difficult to find where an error is thrown. Providing an explicit name also improves readability and consistency. Example configuration: ```json { "func-names": ["error", "as-needed", { "generators": "never" }] } ``` ### Examples Examples of **incorrect** code for this rule: ```js /* func-names: ["error", "always"] */ Foo.prototype.bar = function () {}; const cat = { meow: function () {} }; (function () { /* ... */ })(); export default function () {} ``` Examples of **correct** code for this rule: ```js /* func-names: ["error", "always"] */ Foo.prototype.bar = function bar() {}; const cat = { meow() {} }; (function bar() { /* ... */ })(); export default function foo() {} ``` #### `as-needed` Examples of **incorrect** code for this rule with the `"as-needed"` option: ```js /* func-names: ["error", "as-needed"] */ Foo.prototype.bar = function () {}; (function () { /* ... */ })(); export default function () {} ``` Examples of **correct** code for this rule with the `"as-needed"` option: ```js /* func-names: ["error", "as-needed"] */ const bar = function () {}; const cat = { meow: function () {} }; class C { #bar = function () {}; baz = function () {}; } quux ??= function () {}; (function bar() { /* ... */ })(); export default function foo() {} ``` #### `never` Examples of **incorrect** code for this rule with the `"never"` option: ```js /* func-names: ["error", "never"] */ Foo.prototype.bar = function bar() {}; (function bar() { /* ... */ })(); ``` Examples of **correct** code for this rule with the `"never"` option: ```js /* func-names: ["error", "never"] */ Foo.prototype.bar = function () {}; (function () { /* ... */ })(); ``` #### `generators` Examples of **incorrect** code for this rule with the `"always", { "generators": "as-needed" }` options: ```js /* func-names: ["error", "always", { "generators": "as-needed" }] */ (function* () { /* ... */ })(); ``` Examples of **correct** code for this rule with the `"always", { "generators": "as-needed" }` options: ```js /* func-names: ["error", "always", { "generators": "as-needed" }] */ const foo = function* () {}; ``` Examples of **incorrect** code for this rule with the `"always", { "generators": "never" }` options: ```js /* func-names: ["error", "always", { "generators": "never" }] */ const foo = bar(function* baz() {}); ``` Examples of **correct** code for this rule with the `"always", { "generators": "never" }` options: ```js /* func-names: ["error", "always", { "generators": "never" }] */ const foo = bar(function* () {}); ``` Examples of **incorrect** code for this rule with the `"as-needed", { "generators": "never" }` options: ```js /* func-names: ["error", "as-needed", { "generators": "never" }] */ const foo = bar(function* baz() {}); ``` Examples of **correct** code for this rule with the `"as-needed", { "generators": "never" }` options: ```js /* func-names: ["error", "as-needed", { "generators": "never" }] */ const foo = bar(function* () {}); ``` Examples of **incorrect** code for this rule with the `"never", { "generators": "always" }` options: ```js /* func-names: ["error", "never", { "generators": "always" }] */ const foo = bar(function* () {}); ``` Examples of **correct** code for this rule with the `"never", { "generators": "always" }` options: ```js /* func-names: ["error", "never", { "generators": "always" }] */ const foo = bar(function* baz() {}); ``` ## Configuration ### The 1st option type: `"always" | "as-needed" | "never"` #### `"always"` Requires all function expressions to have a name. #### `"as-needed"` Requires a name only if one is not automatically inferred. #### `"never"` Disallows names for function expressions. ### The 2nd option This option is an object with the following properties: #### generators type: `"always" | "as-needed" | "never"` Configuration for generator function expressions. If not specified, uses the primary configuration. Accepts `always`, `as-needed`, or `never`. Generator functions are those defined using the `function*` syntax. ```js function* foobar(i) { yield i; yield i + 10; } ``` ## How to use ## Version This rule was added in v0.7.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/func-style.md --- ### What it does Enforce the consistent use of either function declarations or expressions assigned to variables. ### Why is this bad? This rule enforces a particular type of function style, either function declarations or expressions assigned to variables. You can specify which you prefer in the configuration. ### Examples ```js // function declaration function doSomething() { // ... } // arrow function expression assigned to a variable const doSomethingElse = () => { // ... }; // function expression assigned to a variable const doSomethingAgain = function () { // ... }; ``` Examples of **incorrect** code for this rule with the default `"expression"` option: ```js /* func-style: ["error", "expression"] */ function foo() { // ... } ``` Examples of **incorrect** code for this rule with the `"declaration"` option: ```js /* func-style: ["error", "declaration"] */ var foo = function () { // ... }; var foo = () => {}; ``` Examples of **incorrect** code for this rule with the `"declaration"` and `{"overrides": { "namedExports": "expression" }}` option: ```js /* func-style: ["error", "declaration", { "overrides": { "namedExports": "expression" } }] */ export function foo() { // ... } ``` Examples of **incorrect** code for this rule with the `"expression"` and `{"overrides": { "namedExports": "declaration" }}` option: ```js /* func-style: ["error", "expression", { "overrides": { "namedExports": "declaration" } }] */ export var foo = function () { // ... }; export var bar = () => {}; ``` Examples of **correct** code for this rule with the default `"expression"` option: ```js /* func-style: ["error", "expression"] */ var foo = function () { // ... }; ``` Examples of **correct** code for this rule with the `"declaration"` option: ```js /* func-style: ["error", "declaration"] */ function foo() { // ... } // Methods (functions assigned to objects) are not checked by this rule SomeObject.foo = function () { // ... }; ``` Examples of additional correct code for this rule with the `"declaration"`, `{ "allowArrowFunctions": true }` options: ```js /* func-style: ["error", "declaration", { "allowArrowFunctions": true }] */ var foo = () => {}; ``` Examples of **correct** code for this rule with the `"declaration"` and `{"overrides": { "namedExports": "expression" }}` option: ```js /* func-style: ["error", "declaration", { "overrides": { "namedExports": "expression" } }] */ export var foo = function () { // ... }; export var bar = () => {}; ``` Examples of **correct** code for this rule with the `"expression"` and `{"overrides": { "namedExports": "declaration" }}` option: ```js /* func-style: ["error", "expression", { "overrides": { "namedExports": "declaration" } }] */ export function foo() { // ... } ``` Examples of **correct** code for this rule with the `{"overrides": { "namedExports": "ignore" }}` option: ```js /* func-style: ["error", "expression", { "overrides": { "namedExports": "ignore" } }] */ export var foo = function () { // ... }; export var bar = () => {}; export function baz() { // ... } ``` ## Configuration ### The 1st option type: `"expression" | "declaration"` ### The 2nd option This option is an object with the following properties: #### allowArrowFunctions type: `boolean` default: `false` When true, arrow functions are allowed regardless of the style setting. #### allowTypeAnnotation type: `boolean` default: `false` When true, functions with type annotations are allowed regardless of the style setting. #### overrides type: `object` Override the style specifically for named exports. Can be "expression", "declaration", or "ignore" (default). ##### overrides.namedExports type: `"ignore" | "expression" | "declaration"` default: `null` ## How to use ## Version This rule was added in v0.15.11. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/getter-return.md --- ### What it does Requires all getters to have a `return` statement. ### Why is this bad? Getters should always return a value. If they don't, it's probably a mistake. This rule does not run on TypeScript files, since type checking will catch getters that do not return a value. ### Examples Examples of **incorrect** code for this rule: ```javascript class Person { get name() { // no return } } const obj = { get foo() { // object getter are also checked }, }; ``` Examples of **correct** code for this rule: ```javascript class Person { get name() { return this._name; } } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowImplicit type: `boolean` default: `false` When set to `true`, allows getters to implicitly return `undefined` with a `return` statement containing no expression. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/grouped-accessor-pairs.md --- ### What it does Require grouped accessor pairs in object literals and classes. ### Why is this bad? While it is allowed to define the pair for a getter or a setter anywhere in an object or class definition, it’s considered a best practice to group accessor functions for the same property. ### Examples Examples of **incorrect** code for this rule: ```js const foo = { get a() { return this.val; }, b: 1, set a(value) { this.val = value; }, }; ``` Examples of **correct** code for this rule: ```js const foo = { get a() { return this.val; }, set a(value) { this.val = value; }, b: 1, }; ``` Examples of **incorrect** code for this rule with the `getBeforeSet` option: ```js const foo = { set a(value) { this.val = value; }, get a() { return this.val; }, }; ``` Examples of **correct** code for this rule with the `getBeforeSet` option: ```js const foo = { get a() { return this.val; }, set a(value) { this.val = value; }, }; ``` Examples of **incorrect** code for this rule with the `setBeforeGet` option: ```js const foo = { get a() { return this.val; }, set a(value) { this.val = value; }, }; ``` Examples of **correct** code for this rule with the `setBeforeGet` option: ```js const foo = { set a(value) { this.val = value; }, get a() { return this.val; }, }; ``` ## Configuration ### The 1st option type: `"anyOrder" | "getBeforeSet" | "setBeforeGet"` #### `"anyOrder"` Accessors can be in any order. This is the default. #### `"getBeforeSet"` Getters must come before setters. #### `"setBeforeGet"` Setters must come before getters. ### The 2nd option This option is an object with the following properties: #### enforceForTSTypes type: `boolean` default: `false` When `enforceForTSTypes` is enabled, this rule also applies to TypeScript interfaces and type aliases. Examples of **incorrect** TypeScript code: ```ts interface Foo { get a(): string; someProperty: string; set a(value: string); } type Bar = { get b(): string; someProperty: string; set b(value: string); }; ``` Examples of **correct** TypeScript code: ```ts interface Foo { get a(): string; set a(value: string); someProperty: string; } type Bar = { get b(): string; set b(value: string); someProperty: string; }; ``` ## How to use ## Version This rule was added in v0.15.12. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/guard-for-in.md --- ### What it does Require for-in loops to include an if statement. ### Why is this bad? Looping over objects with a `for in` loop will include properties that are inherited through the prototype chain. Using a `for in` loop without filtering the results in the loop can lead to unexpected items in your for loop which can then lead to unexpected behaviour. ### Examples Examples of **incorrect** code for this rule: ```javascript for (key in foo) { doSomething(key); } ``` Examples of **correct** code for this rule: ```javascript for (key in foo) { if (Object.hasOwn(foo, key)) { doSomething(key); } } ``` ```javascript for (key in foo) { if (Object.prototype.hasOwnProperty.call(foo, key)) { doSomething(key); } } ``` ```javascript for (key in foo) { if ({}.hasOwnProperty.call(foo, key)) { doSomething(key); } } ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/id-denylist.md --- ### What it does Disallow specified identifiers ### Why is this bad? Generic names can lead to hard-to-decipher code. This rule allows you to specify a deny list of disallowed identifier names to avoid this practice. ### Examples Examples of **incorrect** code for this rule: ```js /*eslint id-denylist: ["error", "data", "callback"] */ const data = { ...values }; function callback() { // ... } element.callback = function () { // ... }; const itemSet = { data: [...values], }; class Foo { data = []; } class Bar { #data = []; } class Baz { callback() {} } class Qux { #callback() {} } ``` Examples of **correct** code for this rule: ```js /*eslint id-denylist: ["error", "data", "callback"] */ const encodingOptions = { ...values }; function processFileResult() { // ... } element.successHandler = function () { // ... }; const itemSet = { entities: [...values], }; callback(); // all function calls are ignored foo.callback(); // all function calls are ignored foo.data; // all property names that are not assignments are ignored class Foo { items = []; } class Bar { #items = []; } class Baz { method() {} } class Qux { #method() {} } ``` ## Configuration type: `array` default: `[]` ## How to use ## Version This rule was added in v1.76.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/id-length.md --- ### What it does Enforce a minimum and/or maximum identifier length convention by counting the graphemes for a given identifier. ### Why is this bad? Very short identifier names like e, x, \_t or very long ones like hashGeneratorResultOutputContainerObject can make code harder to read and potentially less maintainable. To prevent this, one may enforce a minimum and/or maximum identifier length. ### Examples Examples of **incorrect** code for this rule: ```js /* id-length: "error" */ // default is minimum 2-chars ({ "min": 2 }) const x = 5; obj.e = document.body; const foo = function (e) {}; try { dangerousStuff(); } catch (e) { // ignore as many do } const myObj = { a: 1 }; (a) => { a * a; }; class y {} class Foo { x() {} } class Bar { #x() {} } class Baz { x = 1; } class Qux { #x = 1; } function bar(...x) {} function baz([x]) {} const [z] = arr; const { prop: [i], } = {}; function qux({ x }) {} const { j } = {}; const { prop: a } = {}; ({ prop: obj.x } = {}); ``` Examples of **correct** code for this rule: ```js /* id-length: "error" */ // default is minimum 2-chars ({ "min": 2 }) const num = 5; function _f() { return 42; } function _func() { return 42; } obj.el = document.body; const foo = function (evt) { /* do stuff */ }; try { dangerousStuff(); } catch (error) { // ignore as many do } const myObj = { apple: 1 }; (num) => { num * num; }; function bar(num = 0) {} class MyClass {} class Foo { method() {} } class Bar { #method() {} } class Baz { field = 1; } class Qux { #field = 1; } function baz(...args) {} function qux([longName]) {} const { prop } = {}; const { prop: [name], } = {}; const [longName] = arr; function foobar({ prop }) {} function foobaz({ a: prop }) {} const { a: property } = {}; ({ prop: obj.longName } = {}); const data = { x: 1 }; // excused because of quotes data["y"] = 3; // excused because of calculated property access ``` ## Configuration This rule accepts a configuration object with the following properties: ### checkGeneric type: `boolean` default: `true` Whether to check TypeScript generic type parameter names. Defaults to `true`. ### exceptionPatterns type: `string[]` An array of regex patterns for identifiers to exclude from the rule. For example, `["^x.*"]` would exclude all identifiers starting with "x". ### exceptions type: `string[]` default: `[]` An array of identifier names that are excluded from the rule. For example, `["x", "y", "z"]` would allow single-letter identifiers "x", "y", and "z". ### max type: `integer` default: `Infinity` The maximum number of graphemes allowed in an identifier. Defaults to no maximum (effectively unlimited). ### min type: `integer` default: `2` The minimum number of graphemes required in an identifier. ### properties type: `"always" | "never"` default: `"always"` Whether to check property names for length. ## How to use ## Version This rule was added in v1.4.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/id-match.md --- ### What it does Enforces a naming convention for identifiers by requiring each checked name to match a configured regular expression. ### Why is this bad? Inconsistent identifier names make code harder to read and maintain. This rule is most commonly used to enforce a project-wide convention such as `camelCase`, `snake_case`, or names without underscores. The configured pattern is compiled with Rust regex syntax. Most common naming patterns work the same way as JavaScript regular expressions, but JavaScript-specific features such as lookaround assertions and backreferences are not supported. Unicode escapes also use Rust syntax, so `\uXXXX` should be written as `\u{XXXX}`. ### Known differences from ESLint * Computed destructuring keys are checked in both binding and assignment patterns, for example `const { [bad_name]: x } = obj` and `({ [bad_name]: x } = obj)`. This still applies when `ignoreDestructuring` is enabled because the computed key is a normal reference expression, not a binding introduced by destructuring. * With `properties` enabled, ordinary top-level keys in dynamic import options are checked, for example `import("x", { bad_option: true })`. Import attributes inside `with { ... }` are still ignored. These cases are intentionally stricter than ESLint because they still contain user-controlled identifier names that participate in normal code. TypeScript syntax is supported on a best-effort basis for identifiers that flow through the same visited AST node kinds and transparent wrappers. This rule intentionally does not try to cover the full TypeScript naming surface. ### Examples Examples of **incorrect** code for this rule: ```js /* id-match: ["error", "^[^_]+$"] */ var first_name = "John"; /* id-match: ["error", "^[^_]+$", { "properties": true }] */ obj.first_name = "John"; ``` Examples of **correct** code for this rule: ```js /* id-match: ["error", "^[^_]+$"] */ var firstName = "John"; /* id-match: ["error", "^[^_]+$", { "ignoreDestructuring": true }] */ const { first_name } = user; ``` ## Configuration ### The 1st option type: `string` ### The 2nd option This option is an object with the following properties: #### classFields type: `boolean` default: `false` Whether class field names are checked, including public fields, accessor properties, and private field names. #### ignoreDestructuring type: `boolean` default: `false` Whether to ignore shorthand and aliased bindings introduced by object destructuring, such as `foo` in `const { foo } = obj` and `alias` in `const { foo: alias } = obj`. This does not suppress computed key references such as `const { [key]: value } = obj`. #### onlyDeclarations type: `boolean` default: `false` Whether to check only variable and function declaration names. References, member names, labels, class names, TypeScript declarations, and function or arrow parameters are skipped. #### properties type: `boolean` default: `false` Whether object literal property names, class method names, and assigned member names such as `obj.prop = value` are checked. ## How to use ## Version This rule was added in v1.66.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/init-declarations.md --- ### What it does Require or disallow initialization in variable declarations. ### Why is this bad? In JavaScript, variables can be assigned during declaration, or at any point afterwards using an assignment statement. For example, in the following code, `foo` is initialized during declaration, while `bar` is initialized later. ```js var foo = 1; var bar; if (foo) { bar = 1; } else { bar = 2; } ``` ### Examples Examples of incorrect code for the default `"always"` option: ```js /* init-declarations: ["error", "always"] */ function foo() { var bar; let baz; } ``` Examples of incorrect code for the `"never"` option: ```js /* init-declarations: ["error", "never"] */ function foo() { var bar = 1; let baz = 2; for (var i = 0; i < 1; i++) {} } ``` Examples of correct code for the default `"always"` option: ```js /* init-declarations: ["error", "always"] */ function foo() { var bar = 1; let baz = 2; const qux = 3; } ``` Examples of correct code for the `"never"` option: ```js /* init-declarations: ["error", "never"] */ function foo() { var bar; let baz; const buzz = 1; } ``` Examples of correct code for the `"never", { "ignoreForLoopInit": true }` options: ```js /* init-declarations: ["error", "never", { "ignoreForLoopInit": true }] */ for (var i = 0; i < 1; i++) {} ``` ## Configuration ### The 1st option type: `"always" | "never"` ### The 2nd option This option is an object with the following properties: #### ignoreForLoopInit type: `boolean` default: `false` When set to `true`, allows uninitialized variables in the init expression of `for`, `for-in`, and `for-of` loops. Only applies when mode is set to `"never"`. ## How to use ## Version This rule was added in v0.15.11. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/logical-assignment-operators.md --- ### What it does This rule requires or disallows logical assignment operator shorthand. ### Why is this bad? ES2021 introduces the assignment operator shorthand for the logical operators `||`, `&&` and `??`. Before, this was only allowed for mathematical operations such as `+` or `*` (see the rule `operator-assignment`). The shorthand can be used if the assignment target and the left expression of a logical expression are the same. For example `a = a || b` can be shortened to `a ||= b`. ### Examples Examples of **incorrect** code for this rule with the default `always` option: ```js a = a || b; a = a && b; a = a ?? b; a || (a = b); a && (a = b); a ?? (a = b); a = a || b || c; a = a && b && c; a = a ?? b ?? c; ``` Examples of **correct** code for this rule with the default `always` option: ```js a = b; a += b; a ||= b; a = b || c; a || (b = c); if (a) a = b; a = a || b || c; ``` Examples of **incorrect** code for this rule with the `never` option: ```js a ||= b; a &&= b; a ??= b; ``` Examples of **correct** code for this rule with the `never` option: ```js a = a || b; a = a && b; a = a ?? b; ``` ## Configuration ### The 1st option type: `"always" | "never"` ### The 2nd option This option is an object with the following properties: #### enforceForIfStatements type: `boolean` default: `false` This option checks for additional patterns with if statements which could be expressed with the logical assignment operator. Only available if string option is set to `always`. Examples of **incorrect** code for this rule with the `["always", { enforceForIfStatements: true }]` option: ```js if (a) a = b; // <=> a &&= b if (!a) a = b; // <=> a ||= b if (a == null) a = b; // <=> a ??= b if (a === null || a === undefined) a = b; // <=> a ??= b ``` Examples of **correct** code for this rule with the `["always", { enforceForIfStatements: true }]` option: ```js if (a) b = c; if (a === 0) a = b; ``` ## How to use ## Version This rule was added in v1.63.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-classes-per-file.md --- ### What it does Enforce a maximum number of classes per file. ### Why is this bad? Files containing multiple classes can often result in a less navigable and poorly structured codebase. Best practice is to keep each file limited to a single responsibility. ### Examples Examples of **incorrect** code for this rule: ```javascript class Foo {} class Bar {} ``` Examples of **correct** code for this rule: ```js function foo() { var bar = 1; let baz = 2; const qux = 3; } ``` ## Configuration ### ignoreExpressions type: `boolean` default: `false` Whether to ignore class expressions when counting classes. ### max type: `integer` default: `1` The maximum number of classes allowed per file. ## How to use ## Version This rule was added in v0.3.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-depth.md --- ### What it does Enforce a maximum depth that blocks can be nested. This rule helps to limit the complexity of nested blocks, improving readability and maintainability by ensuring that code does not become too deeply nested. ### Why is this bad? Many developers consider code difficult to read if blocks are nested beyond a certain depth. Excessive nesting can make it harder to follow the flow of the code, increasing cognitive load and making maintenance more error-prone. By enforcing a maximum block depth, this rule encourages cleaner, more readable code. ### Examples Examples of **incorrect** code for this rule with the default `{ "max": 3 }` option: ```js function foo() { for (;;) { // Nested 1 deep while (true) { // Nested 2 deep if (true) { // Nested 3 deep if (true) { // Nested 4 deep } } } } } ``` Examples of **correct** code for this rule with the default `{ "max": 3 }` option: ```js function foo() { for (;;) { // Nested 1 deep while (true) { // Nested 2 deep if (true) { // Nested 3 deep } } } } ``` Note that class static blocks do not count as nested blocks, and that the depth in them is calculated separately from the enclosing context. Example: ```js function foo() { if (true) { // Nested 1 deep class C { static { if (true) { // Nested 1 deep if (true) { // Nested 2 deep } } } } } } ``` ## Configuration ### max type: `integer` default: `4` The `max` enforces a maximum depth that blocks can be nested ## How to use ## Version This rule was added in v0.15.12. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-lines.md --- ### What it does Enforce a maximum number of lines per file. ### Why is this bad? Some people consider large files a code smell. Large files tend to do a lot of things and can make it hard following what’s going. While there is not an objective maximum number of lines considered acceptable in a file, most people would agree it should not be in the thousands. Recommendations usually range from 100 to 500 lines. ## Configuration ### max type: `integer` default: `300` Maximum number of lines allowed per file. ### skipBlankLines type: `boolean` default: `false` Whether to ignore blank lines when counting. ### skipComments type: `boolean` default: `false` Whether to ignore comments when counting. ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-lines-per-function.md --- ### What it does Enforce a maximum number of lines of code in a function. This rule ensures that functions do not exceed a specified line count, promoting smaller, more focused functions that are easier to maintain and understand. ### Why is this bad? Some people consider large functions a code smell. Large functions tend to do a lot of things and can make it hard to follow what’s going on. Many coding style guides dictate a limit to the number of lines that a function can comprise of. This rule can help enforce that style. ### Examples Examples of **incorrect** code for this rule with a particular max value: ```js /* { "eslint/max-lines-per-function": ["error", 2] } */ function foo() { const x = 0; } /* { "eslint/max-lines-per-function": ["error", 4] } */ function foo() { // a comment followed by a blank line const x = 0; } ``` Examples of **correct** code for this rule with a particular max value: ```js /* { "eslint/max-lines-per-function": ["error", 3] } */ function foo() { const x = 0; } /* { "eslint/max-lines-per-function": ["error", 5] } */ function foo() { // a comment followed by a blank line const x = 0; } ``` ## Configuration ### IIFEs type: `boolean` default: `false` The `IIFEs` option controls whether IIFEs are included in the line count. By default, IIFEs are not considered, but when set to `true`, they will be included in the line count for the function. ### max type: `integer` default: `50` Maximum number of lines allowed in a function. ### skipBlankLines type: `boolean` default: `false` Skip lines made up purely of whitespace. ### skipComments type: `boolean` default: `false` Skip lines containing just comments. ## How to use ## Version This rule was added in v0.15.12. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-nested-callbacks.md --- ### What it does Enforce a maximum depth that callbacks can be nested. This rule helps to limit the complexity of callback nesting, ensuring that callbacks do not become too deeply nested, improving code readability and maintainability. ### Why is this bad? Many JavaScript libraries use the callback pattern to manage asynchronous operations. A program of any complexity will most likely need to manage several asynchronous operations at various levels of concurrency. A common pitfall is nesting callbacks excessively, making code harder to read and understand. ### Examples Examples of **incorrect** code for this rule with the `{ "max": 3 }` option: ```js foo1(function () { foo2(function () { foo3(function () { foo4(function () { // ... }); }); }); }); ``` Examples of **correct** code for this rule with the `{ "max": 3 }` option: ```js foo1(handleFoo1); function handleFoo1() { foo2(handleFoo2); } function handleFoo2() { foo3(handleFoo3); } function handleFoo3() { foo4(handleFoo4); } function handleFoo4() { foo5(); } ``` ## Configuration ### max type: `integer` default: `10` The `max` enforces a maximum depth that callbacks can be nested. ## How to use ## Version This rule was added in v0.15.12. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-params.md --- ### What it does Enforce a maximum number of parameters in function definitions which by default is three. ### Why is this bad? Functions that take numerous parameters can be difficult to read and write because it requires the memorization of what each parameter is, its type, and the order they should appear in. As a result, many coders adhere to a convention that caps the number of parameters a function can take. ### Examples Examples of **incorrect** code for this rule: ```javascript function foo(bar, baz, qux, qxx) { doSomething(); } ``` ```javascript let foo = (bar, baz, qux, qxx) => { doSomething(); }; ``` Examples of **correct** code for this rule: ```javascript function foo(bar, baz, qux) { doSomething(); } ``` ```javascript let foo = (bar, baz, qux) => { doSomething(); }; ``` ## Configuration ### countThis type: `"always" | "never" | "except-void"` This option controls when to count a `this` parameter. * "always": always count `this` * "never": never count `this` * "except-void": count `this` only when it is not type `void` ### countVoidThis type: `boolean` default: `false` Deprecated alias for `countThis`. For example `{ "countVoidThis": true }` would mean that having a function take a `this` parameter of type `void` is counted towards the maximum number of parameters. ### max type: `integer` default: `3` Maximum number of parameters allowed in function definitions. ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/max-statements.md --- ### What it does Enforce a maximum number of statements in a function. This rule ensures that functions do not exceed a specified statements count, promoting smaller, more focused functions that are easier to maintain and understand. ### Why is this bad? Some people consider large functions a code smell. Large functions tend to do a lot of things and can make it hard to follow what's going on. This rule can help avoid large functions. ### Examples Examples of **incorrect** code for this rule with the default `{ "max": 10 }` option: ```js function foo() { const foo1 = 1; const foo2 = 2; const foo3 = 3; const foo4 = 4; const foo5 = 5; const foo6 = 6; const foo7 = 7; const foo8 = 8; const foo9 = 9; const foo10 = 10; const foo11 = 11; // Too many. } const bar = () => { const foo1 = 1; const foo2 = 2; const foo3 = 3; const foo4 = 4; const foo5 = 5; const foo6 = 6; const foo7 = 7; const foo8 = 8; const foo9 = 9; const foo10 = 10; const foo11 = 11; // Too many. }; ``` Examples of **correct** code for this rule with the default `{ "max": 10 }` option: ```js function foo() { const foo1 = 1; const foo2 = 2; const foo3 = 3; const foo4 = 4; const foo5 = 5; const foo6 = 6; const foo7 = 7; const foo8 = 8; const foo9 = 9; return function () { // 10 // The number of statements in the inner function does not count toward the // statement maximum. let bar; let baz; return 42; }; } const bar = () => { const foo1 = 1; const foo2 = 2; const foo3 = 3; const foo4 = 4; const foo5 = 5; const foo6 = 6; const foo7 = 7; const foo8 = 8; const foo9 = 9; return function () { // 10 // The number of statements in the inner function does not count toward the // statement maximum. let bar; let baz; return 42; }; }; ``` Note that this rule does not apply to class static blocks, and that statements in class static blocks do not count as statements in the enclosing function. Examples of **correct** code for this rule with `{ "max": 2 }` option: ```js function foo() { let one; let two = class { static { let three; let four; let five; if (six) { let seven; let eight; let nine; } } }; } ``` Examples of additional **correct** code for this rule with the `{ "max": 10 }, { "ignoreTopLevelFunctions": true }` options: ```js function foo() { const foo1 = 1; const foo2 = 2; const foo3 = 3; const foo4 = 4; const foo5 = 5; const foo6 = 6; const foo7 = 7; const foo8 = 8; const foo9 = 9; const foo10 = 10; const foo11 = 11; } ``` ## Configuration ### ignoreTopLevelFunctions type: `boolean` default: `false` Whether to ignore top-level functions. ### max type: `integer` default: `10` Maximum number of statements allowed per function. ## How to use ## Version This rule was added in v1.35.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/new-cap.md --- ### What it does This rule requires constructor names to begin with a capital letter. ### Why is this bad? The new operator in JavaScript creates a new instance of a particular type of object. That type of object is represented by a constructor function. Since constructor functions are just regular functions, the only defining characteristic is that new is being used as part of the call. Native JavaScript functions begin with an uppercase letter to distinguish those functions that are to be used as constructors from functions that are not. Many style guides recommend following this pattern to more easily determine which functions are to be used as constructors. **Warning**: The option `newIsCapExceptionPattern` and `capIsNewExceptionPattern` are implemented with the [rust regex syntax](https://docs.rs/regex/latest/regex/). Many JavaScript features are not supported (Lookahead, Lookbehinds, ...). ### Examples Examples of **incorrect** code for this rule: ```js function foo(arg) { return Boolean(arg); } ``` Examples of **incorrect** code for this rule with the default `{ "newIsCap": true }` option: ```js /* new-cap: ["error", { "newIsCap": true }] */ var friend = new person(); ``` Examples of **correct** code for this rule with the default `{ "newIsCap": true }` option: ```js /* new-cap: ["error", { "newIsCap": true }] */ var friend = new Person(); ``` Examples of **correct** code for this rule with the `{ "newIsCap": false }` option: ```js /* new-cap: ["error", { "newIsCap": false }] */ var friend = new person(); ``` Examples of **incorrect** code for this rule with the default `{ "capIsNew": true }` option: ```js /* new-cap: ["error", { "capIsNew": true }] */ var colleague = Person(); ``` Examples of **correct** code for this rule with the default `{ "capIsNew": true }` option: ```js /* new-cap: ["error", { "capIsNew": true }] */ var colleague = new Person(); ``` Examples of **correct** code for this rule with the `{ "capIsNew": false }` option: ```js /* new-cap: ["error", { "capIsNew": false }] */ var colleague = Person(); ``` Examples of additional **correct** code for this rule with the `{ "newIsCapExceptions": ["events"] }` option: ```js /* new-cap: ["error", { "newIsCapExceptions": ["events"] }] */ var events = require("events"); var emitter = new events(); ``` Examples of additional **correct** code for this rule with the `{ "newIsCapExceptionPattern": "^person\\.." }` option: ```js /* new-cap: ["error", { "newIsCapExceptionPattern": "^person\\.." }] */ var friend = new person.acquaintance(); var bestFriend = new person.friend(); ``` Examples of additional **correct** code for this rule with the `{ "newIsCapExceptionPattern": "\\.bar$" }` option: ```js /* new-cap: ["error", { "newIsCapExceptionPattern": "\\.bar$" }] */ var friend = new person.bar(); ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptions": ["Person"] }` option: ```js /* new-cap: ["error", { "capIsNewExceptions": ["Person"] }] */ function foo(arg) { return Person(arg); } ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "^person\\.." }` option: ```js /* new-cap: ["error", { "capIsNewExceptionPattern": "^person\\.." }] */ var friend = person.Acquaintance(); var bestFriend = person.Friend(); ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "\\.Bar$" }` option: ```js /* new-cap: ["error", { "capIsNewExceptionPattern": "\\.Bar$" }] */ foo.Bar(); ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "^Foo" }` option: ```js /* new-cap: ["error", { "capIsNewExceptionPattern": "^Foo" }] */ var x = Foo(42); var y = Foobar(42); var z = Foo.Bar(42); ``` ### properties Examples of **incorrect** code for this rule with the default `{ "properties": true }` option: ```js /* new-cap: ["error", { "properties": true }] */ var friend = new person.acquaintance(); ``` Examples of **correct** code for this rule with the default `{ "properties": true }` option: ```js /* new-cap: ["error", { "properties": true }] */ var friend = new person.Acquaintance(); ``` Examples of **correct** code for this rule with the `{ "properties": false }` option: ```js /* new-cap: ["error", { "properties": false }] */ var friend = new person.acquaintance(); ``` Examples of **incorrect** code for this rule with the default `{ "newIsCap": true }` option: ```js /* new-cap: ["error", { "newIsCap": true }] */ var friend = new person(); ``` Examples of **correct** code for this rule with the default `{ "newIsCap": true }` option: ```js /* new-cap: ["error", { "newIsCap": true }] */ var friend = new Person(); ``` Examples of **correct** code for this rule with the `{ "newIsCap": false }` option: ```js /* new-cap: ["error", { "newIsCap": false }] */ var friend = new person(); ``` Examples of **incorrect** code for this rule with the default `{ "capIsNew": true }` option: ```js /* new-cap: ["error", { "capIsNew": true }] */ var colleague = Person(); ``` Examples of **correct** code for this rule with the default `{ "capIsNew": true }` option: ```js /* new-cap: ["error", { "capIsNew": true }] */ var colleague = new Person(); ``` Examples of **correct** code for this rule with the `{ "capIsNew": false }` option: ```js /* new-cap: ["error", { "capIsNew": false }] */ var colleague = Person(); ``` Examples of additional **correct** code for this rule with the `{ "newIsCapExceptions": ["events"] }` option: ```js /* new-cap: ["error", { "newIsCapExceptions": ["events"] }] */ var events = require("events"); var emitter = new events(); ``` Examples of additional **correct** code for this rule with the `{ "newIsCapExceptionPattern": "^person\\.." }` option: ```js /* new-cap: ["error", { "newIsCapExceptionPattern": "^person\\.." }] */ var friend = new person.acquaintance(); var bestFriend = new person.friend(); ``` Examples of additional **correct** code for this rule with the `{ "newIsCapExceptionPattern": "\\.bar$" }` option: ```js /* new-cap: ["error", { "newIsCapExceptionPattern": "\\.bar$" }] */ var friend = new person.bar(); ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptions": ["Person"] }` option: ::: correct ```js /* new-cap: ["error", { "capIsNewExceptions": ["Person"] }] */ function foo(arg) { return Person(arg); } ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "^person\\.." }` option: ```js /* new-cap: ["error", { "capIsNewExceptionPattern": "^person\\.." }] */ var friend = person.Acquaintance(); var bestFriend = person.Friend(); ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "\\.Bar$" }` option: ```js /* new-cap: ["error", { "capIsNewExceptionPattern": "\\.Bar$" }] */ foo.Bar(); ``` Examples of additional **correct** code for this rule with the `{ "capIsNewExceptionPattern": "^Foo" }` option: ```js /* new-cap: ["error", { "capIsNewExceptionPattern": "^Foo" }] */ var x = Foo(42); var y = Foobar(42); var z = Foo.Bar(42); ``` Examples of **incorrect** code for this rule with the default `{ "properties": true }` option: ```js /* new-cap: ["error", { "properties": true }] */ var friend = new person.acquaintance(); ``` Examples of **correct** code for this rule with the default `{ "properties": true }` option: ```js /* new-cap: ["error", { "properties": true }] */ var friend = new person.Acquaintance(); ``` Examples of **correct** code for this rule with the `{ "properties": false }` option: ```js /* new-cap: ["error", { "properties": false }] */ var friend = new person.acquaintance(); ``` ## Configuration This rule accepts a configuration object with the following properties: ### capIsNew type: `boolean` default: `true` `true` to require that all functions with names starting with an uppercase letter to be called with `new`. ### capIsNewExceptionPattern type: `string` A regex pattern to match exceptions for functions with names starting with an uppercase letter. ### capIsNewExceptions type: `string[]` default: `[]` Exceptions to ignore for functions with names starting with an uppercase letter. ### newIsCap type: `boolean` default: `true` `true` to require that all constructor names start with an uppercase letter, e.g. `new Person()`. ### newIsCapExceptionPattern type: `string` A regex pattern to match exceptions for constructor names starting with an uppercase letter. ### newIsCapExceptions type: `string[]` default: `["Array", "Boolean", "Date", "Error", "Function", "Number", "Object", "RegExp", "String", "Symbol", "BigInt"]` Exceptions to ignore for constructor names starting with an uppercase letter. ### properties type: `boolean` default: `true` `true` to require capitalization for object properties (e.g., `new obj.Method()`). ## How to use ## Version This rule was added in v0.15.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-alert.md --- ### What it does Disallow the use of `alert`, `confirm`, and `prompt`. ### Why is this bad? JavaScript’s `alert`, `confirm`, and `prompt` functions are widely considered to be obtrusive as UI elements and should be replaced by a more appropriate custom UI implementation. Furthermore, `alert` is often used while debugging code, which should be removed before deployment to production. ### Examples Examples of **incorrect** code for this rule: ```js alert("here!"); confirm("Are you sure?"); prompt("What's your name?", "John Doe"); ``` Examples of **correct** code for this rule: ```js customAlert("Something happened!"); customConfirm("Are you sure?"); customPrompt("Who are you?"); function foo() { var alert = myCustomLib.customAlert; alert(); } ``` ## How to use ## Version This rule was added in v0.9.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-array-constructor.md --- ### What it does Disallows creating arrays with the `Array` constructor. ### Why is this bad? Use of the `Array` constructor to construct a new array is generally discouraged in favor of array literal notation because of the single-argument pitfall and because the `Array` global may be redefined. The exception is when the `Array` constructor is used to intentionally create sparse arrays of a specified size by giving the constructor a single numeric argument. ### Examples Examples of **incorrect** code for this rule: ```javascript let arr = new Array(); ``` Examples of **correct** code for this rule: ```javascript let arr = []; let arr2 = Array.from(iterable); let arr3 = new Array(9); ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-async-promise-executor.md --- ### What it does Disallow using an async function as a Promise executor. ### Why is this bad? The `new Promise` constructor accepts an executor function as an argument, which has `resolve` and `reject` parameters that can be used to control the state of the created Promise. For example: ```javascript const result = new Promise(function executor(resolve, reject) { readFile("foo.txt", function (err, result) { if (err) { reject(err); } else { resolve(result); } }); }); ``` The executor function can also be an `async function`. However, this is usually a mistake, for a few reasons: * If an async executor function throws an error, the error will be lost and won’t cause the newly-constructed `Promise` to reject.This could make it difficult to debug and handle some errors. * If a `Promise` executor function is using `await`, this is usually a sign that it is not actually necessary to use the new `Promise` constructor, or the scope of the new `Promise` constructor can be reduced. ### Examples Examples of **incorrect** code for this rule: ```javascript const foo = new Promise(async (resolve, reject) => { readFile("foo.txt", function (err, result) { if (err) { reject(err); } else { resolve(result); } }); }); const result = new Promise(async (resolve, reject) => { resolve(await foo); }); ``` Examples of **correct** code for this rule: ```javascript const foo = new Promise((resolve, reject) => { readFile("foo.txt", function (err, result) { if (err) { reject(err); } else { resolve(result); } }); }); const result = Promise.resolve(foo); ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-await-in-loop.md --- ### What it does This rule disallows the use of `await` within loop bodies. (for, for-in, for-of, while, do-while). ### Why is this bad? It potentially indicates that the async operations are not being effectively parallelized. Instead, they are being run in series, which can lead to poorer performance. ### Examples Examples of **incorrect** code for this rule: ```javascript async function bad() { for (const user of users) { const userRecord = await getUserRecord(user); } } ``` Examples of **correct** code for this rule: ```javascript async function good() { await Promise.all(users.map((user) => getUserRecord(user))); } ``` ## How to use ## Version This rule was added in v0.3.2. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-bitwise.md --- ### What it does Disallow bitwise operators. ### Why is this bad? The use of bitwise operators in JavaScript is very rare and often `&` or `|` is simply a mistyped `&&` or `||`, which will lead to unexpected behavior. ### Examples Examples of **incorrect** code for this rule: ```javascript var x = y | z; ``` ```javascript var x = y ^ z; ``` ```javascript var x = y >> z; ``` Examples of **correct** code for this rule: ```javascript var x = y || z; ``` ```javascript var x = y && z; ``` ```javascript var x = y > z; ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` default: `[]` The `allow` option permits the given list of bitwise operators to be used as exceptions to this rule. For example `{ "allow": ["~"] }` would allow the use of the bitwise operator `~` without restriction. Such as in the following: ```javascript ~[1, 2, 3].indexOf(1) === -1; ``` ### int32Hint type: `boolean` default: `false` When set to `true` the `int32Hint` option allows the use of bitwise OR in |0 pattern for type casting. For example with `{ "int32Hint": true }` the following is permitted: ```javascript const b = a | 0; ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-caller.md --- ### What it does Disallow the use of `arguments.caller` or `arguments.callee`. ### Why is this bad? The use of `arguments.caller` and `arguments.callee` make several code optimizations impossible. They have been deprecated in JavaScript, and their use is forbidden while in strict mode. ```js function foo() { var callee = arguments.callee; } ``` This rule is aimed at discouraging the use of deprecated and sub-optimal code by disallowing the use of `arguments.caller` and `arguments.callee`. As such, it will warn when `arguments.caller` and `arguments.callee` are used. See [the MDN docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee) for more information. ### Examples Examples of **incorrect** code for this rule: ```js function foo(n) { if (n <= 0) { return; } arguments.callee(n - 1); } [1, 2, 3, 4, 5].map(function (n) { return !(n > 1) ? 1 : arguments.callee(n - 1) * n; }); ``` Examples of **correct** code for this rule: ```js function foo(n) { if (n <= 0) { return; } foo(n - 1); } [1, 2, 3, 4, 5].map(function factorial(n) { return !(n > 1) ? 1 : factorial(n - 1) * n; }); ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-case-declarations.md --- ### What it does Disallow lexical declarations in case clauses. ### Why is this bad? The reason is that the lexical declaration is visible in the entire switch block but it only gets initialized when it is assigned, which will only happen if the case where it is defined is reached. ### Examples Examples of **incorrect** code for this rule: ```javascript switch (foo) { case 1: let x = 1; break; case 2: const y = 2; break; case 3: function f() {} break; default: class C {} } ``` Examples of **correct** code for this rule: ```javascript switch (foo) { case 1: { let x = 1; break; } case 2: { const y = 2; break; } case 3: { function f() {} break; } default: { class C {} } } ``` ## How to use ## Version This rule was added in v0.0.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-class-assign.md --- ### What it does Disallow reassigning class variables. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? `ClassDeclaration` creates a variable that can be re-assigned, but the re-assignment is a mistake in most cases. ### Examples Examples of **incorrect** code for this rule: ```javascript class A {} A = 0; ``` ```javascript A = 0; class A {} ``` ```javascript class A { b() { A = 0; } } ``` ```javascript let A = class A { b() { A = 0; // `let A` is shadowed by the class name. } }; ``` Examples of **correct** code for this rule: ```javascript let A = class A {}; A = 0; // A is a variable. ``` ```javascript let A = class { b() { A = 0; // A is a variable. } }; ``` ```javascript class A { b(A) { A = 0; // A is a parameter. } } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-compare-neg-zero.md --- ### What it does Disallow comparing against `-0` ### Why is this bad? The rule should warn against code that tries to compare against `-0`, since that will not work as intended. That is, code like `x === -0` will pass for both `+0` and `-0`. The author probably intended `Object.is(x, -0)`. ### Examples Examples of **incorrect** code for this rule: ```javascript if (x === -0) { // doSomething()... } ``` ```javascript if (-0 > x) { // doSomething()... } ``` Examples of **correct** code for this rule: ```javascript if (x === 0) { // doSomething()... } ``` ```javascript if (Object.is(x, -0)) { // doSomething()... } ``` ```javascript if (0 > x) { // doSomething()... } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-cond-assign.md --- ### What it does Disallow assignment operators in conditional expressions. ### Why is this bad? In conditional statements, it is very easy to mistype a comparison operator (such as `==`) as an assignment operator (such as `=`). There are valid reasons to use assignment operators in conditional statements. However, it can be difficult to tell whether a specific assignment was intentional. ### Examples Examples of **incorrect** code for this rule: ```js // Check the user's job title if ((user.jobTitle = "manager")) { // user.jobTitle is now incorrect } ``` Examples of **correct** code for this rule: ```js // Check the user's job title if (user.jobTitle === "manager") { // correctly compared `jobTitle` } ``` ## Configuration This rule accepts one of the following string values: ### `"except-parens"` Allow assignments in conditional expressions only if they are enclosed in parentheses. ### `"always"` Disallow all assignments in conditional expressions. ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-console.md --- ### What it does Disallow the use of console. ### Why is this bad? In JavaScript that is designed to be executed in the browser, it’s considered a best practice to avoid using methods on console. Such messages are considered to be for debugging purposes and therefore not suitable to ship to the client. In general, calls using console should be stripped before being pushed to production. ### Examples Examples of **incorrect** code for this rule: ```javascript console.log("Log a debug level message."); console.warn("Log a warn level message."); console.error("Log an error level message."); console.log = foo(); ``` Examples of **correct** code for this rule: ```javascript // custom console Console.log("Hello world!"); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` default: `[]` The `allow` option permits the given list of console methods to be used as exceptions to this rule. Say the option was configured as `{ "allow": ["info"] }` then the rule would behave as follows: Example of **incorrect** code for this option: ```javascript console.log("foo"); ``` Example of **correct** code for this option: ```javascript console.info("foo"); ``` ## How to use ## Version This rule was added in v0.0.13. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-const-assign.md --- ### What it does Disallow reassigning `const` variables. ### Why is this bad? We cannot modify variables that are declared using the `const` keyword, as it will raise a runtime error. Note that this rule is not necessary for TypeScript code, as TypeScript will already catch this as an error. ### Examples Examples of **incorrect** code for this rule: ```js const a = 0; a = 1; const b = 0; b += 1; ``` Examples of **correct** code for this rule: ```js const a = 0; console.log(a); var b = 0; b += 1; ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-constant-binary-expression.md --- ### What it does Disallow expressions where the operation doesn't affect the value. ### Why is this bad? Comparisons which will always evaluate to true or false and logical expressions (`||`, `&&`, `??`) which either always short-circuit or never short-circuit are both likely indications of programmer error. By default, this rule also reports relational comparisons (`<`, `<=`, `>`, `>=`) where both sides are literal values. These errors are especially common in complex expressions where operator precedence is easy to misjudge. Additionally, this rule detects comparisons to newly constructed objects/arrays/functions/etc. In JavaScript, where objects are compared by reference, a newly constructed object can never `===` any other value. This can be surprising for programmers coming from languages where objects are compared by value. ### Examples Examples of **incorrect** code for this rule: ```javascript // One might think this would evaluate as `a + (b ?? c)`: const x = a + b ?? c; // But it actually evaluates as `(a + b) ?? c`. Since `a + b` can never be null, // the `?? c` has no effect. // Programmers coming from a language where objects are compared by value might expect this to work: const isEmpty = x === []; // However, this will always result in `isEmpty` being `false`. ``` Examples of **correct** code for this rule: ```javascript const x = a + (b ?? c); const isEmpty = x.length === 0; ``` ## Configuration This rule accepts a configuration object with the following properties: ### checkRelationalComparisons type: `boolean` default: `true` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-constant-condition.md --- ### What it does Disallow constant expressions in conditions. ### Why is this bad? A constant expression (for example, a literal) as a test condition might be a typo or development trigger for a specific behavior. This rule disallows constant expressions in the test condition of: * `if`, `for`, `while`, or `do...while` statement * `?`: ternary expression ### Examples Examples of **incorrect** code for this rule: ```js if (false) { doSomethingUnfinished(); } if (new Boolean(x)) { doSomethingAlways(); } if ((x ||= true)) { doSomethingAlways(); } do { doSomethingForever(); } while ((x = -1)); ``` Examples of **correct** code for this rule: ```js if (x === 0) { doSomething(); } while (typeof x === "undefined") { doSomething(); } ``` ## Configuration This rule accepts a configuration object with the following properties: ### checkLoops type: `boolean | "all" | "allExceptWhileTrue" | "none"` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-constructor-return.md --- ### What it does Disallow returning a value from a constructor. ### Why is this bad? In JavaScript, returning a value in the constructor of a class may be a mistake. Forbidding this pattern prevents mistakes resulting from unfamiliarity with the language or a copy-paste error. ### Examples Examples of **incorrect** code for this rule: ```js class C { constructor() { return 42; } } ``` Examples of **correct** code for this rule: ```js class C { constructor() { this.value = 42; } } ``` ## How to use ## Version This rule was added in v0.4.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-continue.md --- ### What it does Disallow `continue` statements. ### Why is this bad? The continue statement terminates execution of the statements in the current iteration of the current or labeled loop, and continues execution of the loop with the next iteration. When used incorrectly it makes code less testable, less readable and less maintainable. Structured control flow statements such as if should be used instead. ### Examples Examples of **incorrect** code for this rule: ```javascript var sum = 0, i; for (i = 0; i < 10; i++) { if (i >= 5) { continue; } sum += i; } ``` Examples of **correct** code for this rule: ```javascript var sum = 0, i; for (i = 0; i < 10; i++) { if (i < 5) { sum += i; } } ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-control-regex.md --- ### What it does Disallows control characters and some escape sequences that match control characters in regular expressions. ### Why is this bad? Control characters are special, invisible characters in the ASCII range 0-31. These characters are rarely used in JavaScript strings so a regular expression containing elements that explicitly match these characters is most likely a mistake. ### Examples Examples of **incorrect** code for this rule: ```javascript var pattern1 = /\x00/; var pattern2 = /\x0C/; var pattern3 = /\x1F/; var pattern4 = /\u000C/; var pattern5 = /\u{C}/u; var pattern6 = new RegExp("\x0C"); // raw U+000C character in the pattern var pattern7 = new RegExp("\\x0C"); // \x0C pattern ``` Examples of **correct** code for this rule: ```javascript var pattern1 = /\x20/; var pattern2 = /\u0020/; var pattern3 = /\u{20}/u; var pattern4 = /\t/; var pattern5 = /\n/; var pattern6 = new RegExp("\x20"); var pattern7 = new RegExp("\\t"); var pattern8 = new RegExp("\\n"); var pattern9 = /\0/; ``` ## How to use ## Version This rule was added in v0.0.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-debugger.md --- ### What it does Checks for usage of the `debugger` statement. ### Why is this bad? `debugger` statements do not affect functionality when a debugger isn't attached. They're most commonly an accidental debugging leftover. ### Examples Examples of **incorrect** code for this rule: ```javascript async function main() { const data = await getData(); const result = complexCalculation(data); debugger; } ``` Examples of **correct** code for this rule: ```javascript async function main() { const data = await getData(); const result = complexCalculation(data); } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-delete-var.md --- ### What it does The purpose of the `delete` operator is to remove a property from an object. ### Why is this bad? Using the `delete` operator on a variable might lead to unexpected behavior. ### Examples Examples of **incorrect** code for this rule: ```javascript var x; delete x; ``` Examples of **correct** code for this rule: ```javascript var x; var y; delete y.prop; ``` ## How to use ## Version This rule was added in v0.0.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-div-regex.md --- ### What it does Disallow equal signs explicitly at the beginning of regular expressions. ### Why is this bad? Characters /= at the beginning of a regular expression literal can be confused with a division assignment operator. ### Examples Examples of **incorrect** code for this rule: ```javascript function bar() { return /=foo/; } ``` Examples of **correct** code for this rule: ```javascript function bar() { return /[=]foo/; } ``` ## How to use ## Version This rule was added in v0.4.2. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-dupe-class-members.md --- ### What it does Disallow duplicate class members. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? If there are declarations of the same name in class members, the last declaration overwrites other declarations silently. It can cause unexpected behaviors. ### Examples Examples of **incorrect** code for this rule: ```javascript class A { foo() { console.log("foo"); } foo = 123; } let a = new A(); a.foo(); // Uncaught TypeError: a.foo is not a function ``` Examples of **correct** code for this rule: ```javascript class A { foo() { console.log("foo"); } } let a = new A(); a.foo(); ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-dupe-else-if.md --- ### What it does Disallow duplicate conditions in if-else-if chains. ### Why is this bad? if-else-if chains are commonly used when there is a need to execute only one branch (or at most one branch) out of several possible branches, based on certain conditions. Two identical test conditions in the same chain are almost always a mistake in the code. Unless there are side effects in the expressions, a duplicate will evaluate to the same true or false value as the identical expression earlier in the chain, meaning that its branch can never execute. ### Examples Examples of **incorrect** code for this rule: ```javascript if (a) { foo(); } else if (b) { bar(); } else if (b) { baz(); } ``` ```javascript if (a || b) { foo(); } else if (a) { bar(); } ``` ```javascript if (n === 1) { foo(); } else if (n === 2) { bar(); } else if (n === 3) { baz(); } else if (n === 2) { quux(); } else if (n === 5) { quuux(); } ``` Examples of **correct** code for this rule: ```javascript if (a) { foo(); } else if (b) { bar(); } else if (c) { baz(); } ``` ```javascript if (a || b) { foo(); } else if (c) { bar(); } ``` ```javascript if (n === 1) { foo(); } else if (n === 2) { bar(); } else if (n === 3) { baz(); } else if (n === 4) { quux(); } else if (n === 5) { quuux(); } ``` ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-dupe-keys.md --- ### What it does Disallow duplicate keys in object literals. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? Multiple properties with the same key in object literals can cause unexpected behavior in your application. ### Examples Examples of **incorrect** code for this rule: ```js var foo = { bar: "baz", bar: "qux", }; var foo = { bar: "baz", bar: "qux", }; var foo = { 0x1: "baz", 1: "qux", }; ``` Examples of **correct** code for this rule: ```js var foo = { bar: "baz", qux: "qux", }; ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-duplicate-case.md --- ### What it does Disallow duplicate case labels. ### Why is this bad? If a switch statement has duplicate test expressions in case clauses, it is likely that a programmer copied a case clause but forgot to change the test expression. ### Examples Examples of **incorrect** code for this rule: ```js var a = 1, one = 1; switch (a) { case 1: break; case 2: break; case 1: // duplicate test expression break; default: break; } switch (a) { case one: break; case 2: break; case one: // duplicate test expression break; default: break; } ``` Examples of **correct** code for this rule: ```js var a = 1, one = 1; switch (a) { case 1: break; case 2: break; default: break; } switch (a) { case "1": break; case "2": break; default: break; } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-duplicate-imports.md --- ### What it does Disallow duplicate module imports. ### Why is this bad? Using a single import statement per module will make the code clearer because you can see everything being imported from that module on one line. ### Examples Examples of **incorrect** code for this rule: In the following example the module import on line 1 is repeated on line 3. These can be combined to make the list of imports more succinct. ```js import { merge } from "module"; import something from "another-module"; import { find } from "module"; ``` Examples of **correct** code for this rule: ```js import { merge, find } from "module"; import something from "another-module"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowSeparateTypeImports type: `boolean` default: `false` When `true`, imports with only type specifiers (inline types or type imports) are considered separate from imports with value specifiers, so they can be imported from the same module on separate import statements. Examples of **correct** code when `allowSeparateTypeImports` is set to `true`: ```js import { foo } from "module"; import type { Bar } from "module"; ``` ```js import { type Foo } from "module"; import type { Bar } from "module"; ``` ### includeExports type: `boolean` default: `false` When `true` this rule will also look at exports to see if there is both a re-export of a module as in `export ... from 'module'` and also a standard import statement for the same module. This would count as a rule violation because there are in a sense two statements importing from the same module. Examples of **incorrect** code when `includeExports` is set to `true`: ```js import { merge } from "module"; export { find } from "module"; // re-export which is an import and an export. ``` Examples of **correct** code when `includeExports` is set to `true`: If re-exporting from an imported module, you should add the imports to the `import` statement, and export that directly, not use `export ... from`. ```js import { merge } from "lodash-es"; export { merge as lodashMerge }; ``` ```js import { merge, find } from "module"; // cannot be merged with the above import export * as something from "module"; // cannot be written differently export * from "module"; ``` ## How to use ## Version This rule was added in v0.13.2. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-else-return.md --- ### What it does Disallow `else` blocks after `return` statements in `if` statements. ### Why is this bad? If an `if` block contains a `return` statement, the `else` block becomes unnecessary. Its contents can be placed outside of the block. ```javascript function foo() { if (x) { return y; } else { return z; } } ``` This rule is aimed at highlighting an unnecessary block of code following an `if` containing a return statement. As such, it will warn when it encounters an `else` following a chain of `if`s, all of them containing a `return` statement. ### Examples #### `allowElseIf: true` Examples of **incorrect** code for this rule: ```javascript function foo1() { if (x) { return y; } else { return z; } } function foo2() { if (x) { return y; } else if (z) { return w; } else { return t; } } function foo3() { if (x) { return y; } else { var t = "foo"; } return t; } function foo4() { if (error) { return "It failed"; } else { if (loading) { return "It's still loading"; } } } // Two warnings for nested occurrences function foo5() { if (x) { if (y) { return y; } else { return x; } } else { return z; } } ``` Examples of **correct** code for this rule: ```javascript function foo1() { if (x) { return y; } return z; } function foo2() { if (x) { return y; } else if (z) { var t = "foo"; } else { return w; } } function foo3() { if (x) { if (z) { return y; } } else { return z; } } function foo4() { if (error) { return "It failed"; } else if (loading) { return "It's still loading"; } } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowElseIf type: `boolean` default: `true` Whether to allow `else if` blocks after a return statement. Examples of **incorrect** code for this rule with `allowElseIf: false`: ```javascript function foo() { if (error) { return "It failed"; } else if (loading) { return "It's still loading"; } } ``` Examples of **correct** code for this rule with `allowElseIf: false`: ```javascript function foo() { if (error) { return "It failed"; } if (loading) { return "It's still loading"; } } ``` ## How to use ## Version This rule was added in v0.9.10. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-empty.md --- ### What it does Disallows empty block statements. ### Why is this bad? Empty block statements, while not technically errors, usually occur due to refactoring that wasn’t completed. They can cause confusion when reading code. ### Examples Examples of **incorrect** code for this rule: ```javascript if (condition) { } ``` Examples of **correct** code for this rule: ```javascript if (condition) { throw new Error("condition should be false"); } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowEmptyCatch type: `boolean` default: `false` If set to `true`, allows an empty `catch` block without triggering the linter. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-empty-character-class.md --- ### What it does Disallow empty character classes in regular expressions. ### Why is this bad? Because empty character classes in regular expressions do not match anything, they might be typing mistakes. ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = /^abc[]/; ``` Examples of **correct** code for this rule: ```javascript var foo = /^abc/; var foo2 = /^abc[123]/; ``` ## How to use ## Version This rule was added in v0.0.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-empty-function.md --- ### What it does Disallows the usage of empty functions. ### Why is this bad? Empty functions can reduce readability because readers need to guess whether it's intentional or not. So writing a clear comment for empty functions is a good practice. ### Examples Examples of **incorrect** code for this rule: ```typescript function foo() {} const bar = () => {}; class Foo { constructor(); someMethod() {} set bar(value) {} } ``` Examples of **correct** code for this rule: ```typescript function foo() { // do nothing } function foo() { return; } const add = (a, b) => a + b; class Foo { // constructor body is empty, but it declares a private property named // `_name` constructor(private _name: string) {} public get name() { return this._name; } } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `array` Types of functions that are allowed to be empty. By default, no function kinds are allowed to be empty, but this option can be used to permit specific kinds of functions. Example: ```json { "no-empty-function": [ "error", { "allow": ["constructors"] } ] } ``` #### allow\[n] type: `"functions" | "arrowFunctions" | "generatorFunctions" | "methods" | "generatorMethods" | "getters" | "setters" | "constructors" | "asyncFunctions" | "asyncMethods" | "privateConstructors" | "protectedConstructors" | "decoratedFunctions" | "overrideMethods"` Kinds of functions that can be allowed to be empty. ##### `"functions"` Allow empty regular functions. ```js function foo() {} ``` ##### `"arrowFunctions"` Allow empty arrow functions. ```js const foo = () => {}; ``` ##### `"generatorFunctions"` Allow empty generator functions. ```js function* foo() {} ``` ##### `"methods"` Allow empty methods. ```js class Foo { bar() {} } ``` ##### `"generatorMethods"` Allow empty generator methods. ```js class Foo { *bar() {} } ``` ##### `"getters"` Allow empty getters. ```js class Foo { get bar() {} } ``` ##### `"setters"` Allow empty setters. ```js class Foo { set bar(value) {} } ``` ##### `"constructors"` Allow empty constructors. ```js class Foo { constructor() {} } ``` ##### `"asyncFunctions"` Allow empty async functions. ```js async function foo() {} ``` ##### `"asyncMethods"` Allow empty async methods. ```js class Foo { async bar() {} } ``` ##### `"privateConstructors"` Allow empty private constructors. ```ts class Foo { private constructor() {} } ``` ##### `"protectedConstructors"` Allow empty protected constructors. ```ts class Foo { protected constructor() {} } ``` ##### `"decoratedFunctions"` Allow empty decorated functions. ```js class Foo { @decorator() bar() {} } ``` ##### `"overrideMethods"` Allow empty override methods. ```ts class Foo extends Base { override bar() {} } ``` ## How to use ## Version This rule was added in v0.3.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-empty-pattern.md --- ### What it does Disallow empty destructuring patterns. ### Why is this bad? When using destructuring, it’s possible to create a pattern that has no effect. This happens when empty curly braces are used to the right of an embedded object destructuring pattern, such as: ```JavaScript // doesn't create any variables var {a: {}} = foo; ``` In this code, no new variables are created because a is just a location helper while the `{}` is expected to contain the variables to create, such as: ```JavaScript // creates variable b var {a: { b }} = foo; ``` In many cases, the empty object pattern is a mistake where the author intended to use a default value instead, such as: ```JavaScript // creates variable a var {a = {}} = foo; ``` The difference between these two patterns is subtle, especially because the problematic empty pattern looks just like an object literal. ### Examples of **incorrect** code for this rule: ```JavaScript var {} = foo; var [] = foo; var {a: {}} = foo; var {a: []} = foo; function foo({}) {} function foo([]) {} function foo({a: {}}) {} function foo({a: []}) {} ``` ### Examples of **correct** code for this rule: ```JavaScript var {a = {}} = foo; var {a = []} = foo; function foo({a = {}}) {} function foo({a = []}) {} ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowObjectPatternsAsParameters type: `boolean` default: `false` When set to `true`, this rule allows empty object patterns used directly as function parameters, including parameters defaulted to an empty object literal. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-empty-static-block.md --- ### What it does Disallow empty static blocks. ### Why is this bad? Empty block statements, while not technically errors, usually occur due to refactoring that wasn’t completed. They can cause confusion when reading code. ### Examples Examples of **incorrect** code for this rule: ```js class Foo { static {} } ``` Examples of **correct** code for this rule: ```js class Foo { static { // blocks with comments are allowed } } class Bar { static { doSomething(); } } ``` ## How to use ## Version This rule was added in v0.0.19. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-eq-null.md --- ### What it does Disallow `null` comparisons without type-checking operators. ### Why is this bad? Comparing to `null` without a type-checking operator (`==` or `!=`), can have unintended results as the comparison will evaluate to `true` when comparing to not just a `null`, but also an `undefined` value. ### Examples Examples of **incorrect** code for this rule: ```js if (foo == null) { bar(); } if (baz != null) { bar(); } ``` Examples of **correct** code for this rule: ```js if (foo === null) { bar(); } if (baz !== null) { bar(); } if (bang === undefined) { bar(); } ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-eval.md --- ### What it does Disallows referencing the `eval` function. This rule is aimed at preventing potentially dangerous, unnecessary, and slow code by disallowing the use of the `eval()` function. ### Why is this bad? JavaScript’s `eval()` function is potentially dangerous and is often misused. Using `eval()` on untrusted code can open a program up to several different injection attacks. The use of `eval()` in most contexts can be substituted for a better, safer alternative approach to solving the problem, such as using `JSON.parse()` or `Function` constructors in safer ways. ### Examples Examples of **incorrect** code for this rule: ```js const obj = { x: "foo" }, key = "x", value = eval("obj." + key); (0, eval)("const a = 0"); const foo = eval; foo("const a = 0"); this.eval("const a = 0"); ``` Examples of **correct** code for this rule: ```js const obj = { x: "foo" }, key = "x", value = obj[key]; class A { foo() { this.eval("const a = 0"); } eval() {} static { this.eval("const a = 0"); } static eval() {} } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowIndirect type: `boolean` default: `true` This `allowIndirect` option allows indirect `eval()` calls. Indirect calls to `eval`(e.g., `window['eval']`) are less dangerous than direct calls because they cannot dynamically change the scope. Indirect `eval()` calls also typically have less impact on performance compared to direct calls, as they do not invoke JavaScript's scope chain. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-ex-assign.md --- ### What it does Disallow reassigning exceptions in catch clauses. ### Why is this bad? If a catch clause in a try statement accidentally (or purposely) assigns another value to the exception parameter, it is impossible to refer to the error from that point on. Since there is no arguments object to offer alternative access to this data, assignment of the parameter is absolutely destructive. ### Examples Examples of **incorrect** code for this rule: ```javascript try { // code } catch (e) { e = 10; } ``` Examples of **correct** code for this rule: ```javascript try { // code } catch (e) { let val = 10; } ``` ## How to use ## Version This rule was added in v0.0.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-extend-native.md --- ### What it does Prevents extending native global objects such as `Object`, `String`, or `Array` with new properties. ### Why is this bad? Extending native objects can cause unexpected behavior and conflicts with other code. For example: ```js // Adding a new property, which might seem okay Object.prototype.extra = 55; // Defining a user object const users = { 1: "user1", 2: "user2", }; for (const id in users) { // This will print "extra" as well as "1" and "2": console.log(id); } ``` ### Examples Examples of **incorrect** code for this rule: ```js Object.prototype.p = 0; Object.defineProperty(Array.prototype, "p", { value: 0 }); ``` Examples of **correct** code for this rule: ```js x.prototype.p = 0; Object.defineProperty(x.prototype, "p", { value: 0 }); ``` ## Configuration This rule accepts a configuration object with the following properties: ### exceptions type: `string[]` default: `[]` A list of objects which are allowed to be exceptions to the rule. ## How to use ## Version This rule was added in v0.9.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-extra-bind.md --- ### What it does Disallow unnecessary calls to `.bind()`. ### Why is this bad? This rule is aimed at avoiding the unnecessary use of `bind()` and as such will warn whenever an immediately-invoked function expression (IIFE) is using `bind()` and doesn’t have an appropriate `this` value. This rule won’t flag usage of `bind()` that includes function argument binding. ### Examples Examples of **incorrect** code for this rule: ```js const x = function () { foo(); }.bind(bar); const z = (() => { this.foo(); }).bind(this); ``` Examples of **correct** code for this rule: ```js const x = function () { this.foo(); }.bind(bar); const y = function (a) { return a + 1; }.bind(foo, bar); ``` ## How to use ## Version This rule was added in v1.1.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-extra-boolean-cast.md --- ### What it does This rule disallows unnecessary boolean casts. ### Why is this bad? In contexts such as an if statement's test where the result of the expression will already be coerced to a Boolean, casting to a Boolean via double negation (`!!`) or a `Boolean` call is unnecessary. ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = !!!bar; var foo = Boolean(!!bar); if (!!foo) { } if (Boolean(foo)) { } // with "enforceForInnerExpressions" option enabled if (!!foo || bar) { } ``` Examples of **correct** code for this rule: ```javascript var foo = !bar; var foo = Boolean(bar); if (foo) { } if (foo) { } // with "enforceForInnerExpressions" option enabled if (foo || bar) { } ``` ## Configuration This rule accepts a configuration object with the following properties: ### enforceForInnerExpressions type: `boolean` default: `false` when set to `true`, in addition to checking default contexts, checks whether extra boolean casts are present in expressions whose result is used in a boolean context. See examples below. Default is `false`, meaning that this rule by default does not warn about extra booleans cast inside inner expressions. ## How to use ## Version This rule was added in v0.0.8. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-extra-label.md --- ### What it does Disallow unnecessary labels. ### Why is this bad? If a loop contains no nested loops or switches, labeling the loop is unnecessary. ```js A: while (a) { break A; } ``` You can achieve the same result by removing the label and using `break` or `continue` without a label. Probably those labels would confuse developers because they expect labels to jump to further. ### Examples Examples of **incorrect** code for this rule: ```js A: while (a) { break A; } B: for (let i = 0; i < 10; ++i) { break B; } C: switch (a) { case 0: break C; } ``` Examples of **correct** code for this rule: ```js while (a) { break; } for (let i = 0; i < 10; ++i) { break; } switch (a) { case 0: break; } A: { break A; } B: while (a) { while (b) { break B; } } C: switch (a) { case 0: while (b) { break C; } break; } ``` ## How to use ## Version This rule was added in v0.15.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-fallthrough.md --- ### What it does Disallow fallthrough of `case` statements This rule is aimed at eliminating unintentional fallthrough of one case to the other. As such, it flags any fallthrough scenarios that are not marked by a comment. ### Why is this bad? The switch statement in JavaScript is one of the more error-prone constructs of the language thanks in part to the ability to “fall through” from one case to the next. For example: ```js switch (foo) { case 1: doSomething(); case 2: doSomethingElse(); } ``` In this example, if `foo` is `1`, then execution will flow through both cases, as the first falls through to the second. You can prevent this by using `break`, as in this example: ```js switch (foo) { case 1: doSomething(); break; case 2: doSomethingElse(); } ``` That works fine when you don’t want a fallthrough, but what if the fallthrough is intentional, there is no way to indicate that in the language. It’s considered a best practice to always indicate when a fallthrough is intentional using a comment which matches the \`/falls?\s?through/i\`\` regular expression but isn’t a directive: ```js switch (foo) { case 1: doSomething(); // falls through case 2: doSomethingElse(); } switch (foo) { case 1: doSomething(); // fall through case 2: doSomethingElse(); } switch (foo) { case 1: doSomething(); // fallsthrough case 2: doSomethingElse(); } switch (foo) { case 1: { doSomething(); // falls through } case 2: { doSomethingElse(); } } ``` In this example, there is no confusion as to the expected behavior. It is clear that the first case is meant to fall through to the second case. ### Examples Examples of **incorrect** code for this rule: ```js switch (foo) { case 1: doSomething(); case 2: doSomething(); } ``` Examples of **correct** code for this rule: ```js switch (foo) { case 1: doSomething(); break; case 2: doSomething(); } function bar(foo) { switch (foo) { case 1: doSomething(); return; case 2: doSomething(); } } switch (foo) { case 1: doSomething(); throw new Error("Boo!"); case 2: doSomething(); } switch (foo) { case 1: case 2: doSomething(); } switch (foo) { case 1: case 2: doSomething(); } switch (foo) { case 1: doSomething(); // falls through case 2: doSomething(); } switch (foo) { case 1: { doSomething(); // falls through } case 2: { doSomethingElse(); } } ``` Note that the last case statement in these examples does not cause a warning because there is nothing to fall through into. ## Configuration This rule accepts a configuration object with the following properties: ### allowEmptyCase type: `boolean` default: `false` Whether to allow empty case clauses to fall through. ### commentPattern type: `string` Custom regex pattern to match fallthrough comments. ### reportUnusedFallthroughComment type: `boolean` default: `false` Whether to report unused fallthrough comments. ## How to use ## Version This rule was added in v0.0.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-func-assign.md --- ### What it does Disallow reassigning `function` declarations. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? Overwriting/reassigning a function written as a FunctionDeclaration is often indicative of a mistake or issue. ### Examples Examples of **incorrect** code for this rule: ```javascript function foo() {} foo = bar; ``` ```javascript function foo() { foo = bar; } ``` ```javascript let a = function hello() { hello = 123; }; ``` Examples of **correct** code for this rule: ```javascript let foo = function () {}; foo = bar; ``` ```javascript function baz(baz) { // `baz` is shadowed. baz = bar; } ``` ``` function qux() { const qux = bar; // `qux` is shadowed. } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-global-assign.md --- ### What it does Disallow modifications to read-only global variables. ### Why is this bad? In almost all cases, you don't want to assign a value to these global variables as doing so could result in losing access to important functionality. ### Examples Examples of **incorrect** code for this rule: ```javascript Object = null; ``` ## Configuration This rule accepts a configuration object with the following properties: ### exceptions type: `string[]` default: `[]` List of global variable names to exclude from this rule. Globals listed here can be assigned to without triggering warnings. ## How to use ## Version This rule was added in v0.0.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-implicit-coercion.md --- ### What it does Disallow shorthand type conversions using operators like `!!`, unary `+`, and `"" +`. ### Why is this bad? Implicit type coercions using operators can be less clear than using explicit type conversion functions like `Boolean()`, `Number()`, and `String()`. Using explicit conversions makes the intent clearer and the code more readable. ### Examples Examples of **incorrect** code for this rule: ```javascript var b = !!foo; var n = +foo; var s = "" + foo; ``` Examples of **correct** code for this rule: ```javascript var b = Boolean(foo); var n = Number(foo); var s = String(foo); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` List of operators to allow. Valid values: `"!!"`, `"~"`, `"+"`, `"-"`, `"- -"`, `"*"` ### boolean type: `boolean` default: `true` When `true`, warns on implicit boolean coercion (e.g., `!!foo`). ### disallowTemplateShorthand type: `boolean` default: `false` When `true`, disallows using template literals for string coercion (e.g., `` `${foo}` ``). ### number type: `boolean` default: `true` When `true`, warns on implicit number coercion (e.g., `+foo`). ### string type: `boolean` default: `true` When `true`, warns on implicit string coercion (e.g., `"" + foo`). ## How to use ## Version This rule was added in v1.33.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-implicit-globals.md --- ### What it does Disallows declarations in the global scope, global variable leaks, and writes or redeclarations of read-only globals. ### Why is this bad? Browser scripts share a global scope. Top-level `var` and `function` declarations, and assignments to undeclared variables in sloppy mode, create globals that can collide with other scripts. ### Examples Examples of **incorrect** code for this rule: ```js var foo = 1; function bar() {} baz = 1; ``` Examples of **correct** code for this rule: ```js window.foo = 1; (function () { var bar = 1; })(); ``` ## Configuration ### lexicalBindings type: `boolean` default: `false` ## How to use ## Version This rule was added in v1.65.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-implied-eval.md --- ### What it does Disallows passing strings to `setTimeout()`, `setInterval()`, and `execScript()`. ### Why is this bad? Passing a string to these APIs evaluates the string as JavaScript source text at runtime. This has many of the same security, readability, and performance problems as `eval()`. Pass a function instead. ### Examples Examples of **incorrect** code for this rule: ```js setTimeout("alert('Hi!')", 100); setInterval("doWork()", 1000); window.setTimeout("doWork()", 100); ``` Examples of **correct** code for this rule: ```js setTimeout(() => alert("Hi!"), 100); setInterval(doWork, 1000); window.setTimeout(doWork, 100); ``` ## How to use ## Version This rule was added in v1.66.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-import-assign.md --- ### What it does Disallow assigning to imported bindings. ### Why is this bad? The updates of imported bindings by ES Modules cause runtime errors. The TypeScript compiler generally enforces this check already. Although it should be noted that there are some cases TypeScript does not catch, such as assignments via `Object.assign`. So this rule is still useful for TypeScript code in those cases. ### Examples Examples of **incorrect** code for this rule: ```javascript import mod, { named } from "./mod.mjs"; import * as mod_ns from "./mod.mjs"; mod = 1; // ERROR: 'mod' is readonly. named = 2; // ERROR: 'named' is readonly. mod_ns.named = 3; // ERROR: The members of 'mod_ns' are readonly. mod_ns = {}; // ERROR: 'mod_ns' is readonly. // Can't extend 'mod_ns' Object.assign(mod_ns, { foo: "foo" }); // ERROR: The members of 'mod_ns' are readonly. ``` ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-inline-comments.md --- ### What it does Disallows comments on the same line as code. ### Why is this bad? Comments placed at the end of a line of code can make code harder to read. They can easily be missed when scanning vertically, and they make lines longer. Moving comments to their own lines makes them more prominent and reduces line length. ### Examples Examples of **incorrect** code for this rule: ```js var a = 1; // inline comment var b = 2; /* another inline comment */ ``` Examples of **correct** code for this rule: ```js // comment on its own line var a = 1; /* block comment on its own line */ var b = 2; ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignorePattern type: `string` A regex pattern to ignore certain inline comments. Comments matching this pattern will not be reported. Example configuration: ```json { "no-inline-comments": [ "error", { "ignorePattern": "webpackChunkName" } ] } ``` ## How to use ## Version This rule was added in v1.34.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-inner-declarations.md --- ### What it does Disallow variable or function declarations in nested blocks. ### Why is this bad? A variable declaration is permitted anywhere a statement can go, even nested deeply inside other blocks. This is often undesirable due to variable hoisting, and moving declarations to the root of the program or function body can increase clarity. Note that block bindings (let, const) are not hoisted and therefore they are not affected by this rule. ### Examples Examples of **incorrect** code for this rule: ```javascript if (test) { function doSomethingElse() {} } ``` Examples of **correct** code for this rule: ```javascript function doSomethingElse() {} if (test) { // your code here } ``` ## Configuration ### The 1st option type: `"functions" | "both"` Determines what type of declarations to check. #### `"functions"` Disallows function declarations in nested blocks. #### `"both"` Disallows function and var declarations in nested blocks. ### The 2nd option This option is an object with the following properties: #### blockScopedFunctions type: `"allow" | "disallow"` Controls whether function declarations in nested blocks are allowed in strict mode (ES6+ behavior). ##### `"allow"` Allow function declarations in nested blocks in strict mode (ES6+ behavior). ##### `"disallow"` Disallow function declarations in nested blocks regardless of strict mode. #### namespaces type: `"allow" | "disallow"` Controls whether declarations directly inside TypeScript namespace or module bodies are allowed. ##### `"allow"` Allow declarations directly inside TypeScript namespace or module bodies. ##### `"disallow"` Disallow declarations directly inside TypeScript namespace or module bodies. ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-invalid-regexp.md --- ### What it does Disallow invalid regular expression strings in RegExp constructors. ### Why is this bad? An invalid pattern in a regular expression literal is a SyntaxError when the code is parsed, but an invalid string in RegExp constructors throws a SyntaxError only when the code is executed. ### Examples Examples of **incorrect** code for this rule: ```js RegExp("["); RegExp(".", "z"); new RegExp("\\"); ``` Examples of **correct** code for this rule: ```js RegExp("."); new RegExp(); this.RegExp("["); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowConstructorFlags type: `string[]` default: `[]` Case-sensitive array of flags that will be allowed. ## How to use ## Version This rule was added in v0.9.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-irregular-whitespace.md --- ### What it does Disallows the use of irregular whitespace characters in the code. ### Why is this bad? Irregular whitespace characters are invisible to most editors and can cause unexpected behavior, making code harder to debug and maintain. They can also cause issues with code formatting and parsing. ### Examples Examples of **incorrect** code for this rule: ```javascript // Contains irregular whitespace characters (invisible) function example() { var foo = "bar"; // irregular whitespace before 'bar' } ``` Examples of **correct** code for this rule: ```javascript function example() { var foo = "bar"; // regular spaces only } ``` ## Configuration This rule accepts a configuration object with the following properties: ### skipComments type: `boolean` default: `true` Whether to skip irregular whitespace in comments. ### skipJSXText type: `boolean` default: `true` Whether to skip irregular whitespace in JSX text. ### skipRegExps type: `boolean` default: `true` Whether to skip irregular whitespace in regular expression literals. ### skipStrings type: `boolean` default: `true` Whether to skip irregular whitespace in string literals. ### skipTemplates type: `boolean` default: `true` Whether to skip irregular whitespace in template literals. ## How to use ## Version This rule was added in v0.1.1. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-iterator.md --- ### What it does Disallow the use of the `__iterator__` property. ### Why is this bad? The `__iterator__` property was a SpiderMonkey extension to JavaScript that could be used to create custom iterators that are compatible with JavaScript’s for in and for each constructs. However, this property is now obsolete, so it should not be used. Here’s an example of how this used to work: ```js Foo.prototype.__iterator__ = function () { return new FooIterator(this); }; ``` ### Examples Examples of **incorrect** code for this rule: ```javascript Foo.prototype.__iterator__ = function () { return new FooIterator(this); }; foo.__iterator__ = function () {}; foo["__iterator__"] = function () {}; ``` Examples of **correct** code for this rule: ```js const __iterator__ = 42; // not using the __iterator__ property Foo.prototype[Symbol.iterator] = function () { return new FooIterator(this); }; ``` ## How to use ## Version This rule was added in v0.2.15. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-label-var.md --- ### What it does Disallow labels that share a name with a variable. ### Why is this bad? This rule aims to create clearer code by disallowing the bad practice of creating a label that shares a name with a variable that is in scope. ### Examples Examples of **incorrect** code for this rule: ```js var x = foo; function bar() { x: for (;;) { break x; } } ``` Examples of **correct** code for this rule: ```js // The variable that has the same name as the label is not in scope. function foo() { var q = t; } function bar() { q: for (;;) { break q; } } ``` ## How to use ## Version This rule was added in v0.6.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-labels.md --- ### What it does Disallow labeled statements. ### Why is this bad? Labeled statements in JavaScript are used in conjunction with `break` and `continue` to control flow around multiple loops. For example: ```js outer: while (true) { while (true) { break outer; } } ``` The `break outer` statement ensures that this code will not result in an infinite loop because control is returned to the next statement after the `outer` label was applied. If this statement was changed to be just `break`, control would flow back to the outer `while` statement and an infinite loop would result. While convenient in some cases, labels tend to be used only rarely and are frowned upon by some as a remedial form of flow control that is more error prone and harder to understand. ### Examples Examples of **incorrect** code for this rule: ```js label: while (true) { // ... } label: while (true) { break label; } label: while (true) { continue label; } label: switch (a) { case 0: break label; } label: { break label; } label: if (a) { break label; } ``` Examples of **correct** code for this rule: ```js var f = { label: "foo", }; while (true) { break; } while (true) { continue; } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowLoop type: `boolean` default: `false` If set to `true`, this rule ignores labels which are sticking to loop statements. Examples of **correct** code with this option set to `true`: ```js label: while (true) { break label; } ``` ### allowSwitch type: `boolean` default: `false` If set to `true`, this rule ignores labels which are sticking to switch statements. Examples of **correct** code with this option set to `true`: ```js label: switch (a) { case 0: break label; } ``` ## How to use ## Version This rule was added in v0.15.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-lone-blocks.md --- ### What it does Disallows unnecessary standalone block statements. ### Why is this bad? Standalone blocks can be confusing as they do not provide any meaningful purpose when used unnecessarily. They may introduce extra nesting, reducing code readability, and can mislead readers about scope or intent. ### Examples Examples of **incorrect** code for this rule: ```js { var x = 1; } ``` Examples of **correct** code for this rule: ```js if (condition) { var x = 1; } { let x = 1; // Used to create a valid block scope. } ``` ## How to use ## Version This rule was added in v0.15.6. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-lonely-if.md --- ### What it does Disallow `if` statements as the only statement in `else` blocks. ### Why is this bad? When an `if` statement is the only statement in an `else` block, it is often clearer to use an `else if` instead. ### Examples Examples of **incorrect** code for this rule: ```js if (condition) { // ... } else { if (anotherCondition) { // ... } } ``` ```js if (condition) { // ... } else { if (anotherCondition) { // ... } else { // ... } } ``` Examples of **correct** code for this rule: ```js if (condition) { // ... } else if (anotherCondition) { // ... } ``` ```js if (condition) { // ... } else if (anotherCondition) { // ... } else { // ... } ``` ```js if (condition) { // ... } else { if (anotherCondition) { // ... } doSomething(); } ``` ## How to use ## Version This rule was added in v0.16.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-loop-func.md --- ### What it does Disallows function declarations and expressions inside loop statements when they reference variables declared in the outer scope that may change across iterations. ### Why is this bad? Writing functions within loops tends to result in errors due to the way closures work in JavaScript. Functions capture variables by reference, not by value. When using `var`, which is function-scoped, all iterations share the same variable binding, leading to unexpected behavior. ### Examples Examples of **incorrect** code for this rule: ```js for (var i = 0; i < 10; i++) { funcs[i] = function () { return i; }; } ``` Examples of **correct** code for this rule: ```js for (let i = 0; i < 10; i++) { funcs[i] = function () { return i; }; } ``` ## How to use ## Version This rule was added in v1.33.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-loss-of-precision.md --- ### What it does Disallow precision loss in numeric literals. ### Why is this bad? It can lead to unexpected results in certain situations. For example, when performing mathematical operations. In JavaScript, Numbers are stored as double-precision floating-point numbers according to the IEEE 754 standard. Because of this, numbers can only retain accuracy up to a certain amount of digits. If the programmer enters additional digits, those digits will be lost in the conversion to the Number type and will result in unexpected/incorrect behavior. ### Examples Examples of **incorrect** code for this rule: ```javascript var x = 2e999; ``` ```javascript var x = 9007199254740993; ``` ```javascript var x = 5123000000000000000000000000001; ``` ```javascript var x = 1230000000000000000000000.0; ``` ```javascript var x = 0x200000_0000000_1; ``` Examples of **correct** code for this rule: ```javascript var x = 12345; ``` ```javascript var x = 123.456; ``` ```javascript var x = 123.0; ``` ```javascript var x = 123e34; ``` ```javascript var x = 0x1fff_ffff_fff_fff; ``` ## How to use ## Version This rule was added in v0.0.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-magic-numbers.md --- ### What it does This rule aims to make code more readable and refactoring easier by ensuring that special numbers are declared as constants to make their meaning explicit. The current implementation does not support BigInt numbers inside array indexes. ### Why is this bad? ‘Magic numbers’ are numbers that occur multiple times in code without an explicit meaning. They should preferably be replaced by named constants. ### Examples Examples of **incorrect** code for this rule: ```javascript var dutyFreePrice = 100; var finalPrice = dutyFreePrice + dutyFreePrice * 0.25; ``` Examples of **correct** code for this rule with option "ignore": ```javascript /*typescript no-magic-numbers: ["error", { "ignore": [1] }]*/ var data = ["foo", "bar", "baz"]; var dataLast = data.length && data[data.length - 1]; ``` Examples of **correct** code for this rule with option "ignoreArrayIndexes": ```javascript /*typescript no-magic-numbers: ["error", { "ignoreArrayIndexes": true }]*/ var item = data[2]; data[100] = a; f(data[0]); a = data[-0]; // same as data[0], -0 will be coerced to "0" a = data[0xab]; a = data[5.6e1]; a = data[4294967294]; // max array index ``` Examples of **correct** code for this rule with option "ignoreDefaultValues": ```javascript /*typescript no-magic-numbers: ["error", { "ignoreDefaultValues": true }]*/ const { tax = 0.25 } = accountancy; function mapParallel(concurrency = 3) { /***/ } ``` Examples of **correct** code for this rule with option "ignoreClassFieldInitialValues": ```javascript /*typescript no-magic-numbers: ["error", { "ignoreClassFieldInitialValues": true }]*/ class C { foo = 2; bar = -3; #baz = 4; static qux = 5; } ``` Examples of **incorrect** code for this rule with option "enforceConst": ```javascript /*typescript no-magic-numbers: ["error", { "enforceConst": true }]*/ var TAX = 0.25; ``` Examples of **incorrect** code for this rule with option "detectObjects": ```javascript /*typescript no-magic-numbers: ["error", { "detectObjects": true }]*/ var magic = { tax: 0.25, }; ``` Examples of **correct** code for this rule with option "detectObjects": ```javascript /*typescript no-magic-numbers: ["error", { "detectObjects": true }]*/ var TAX = 0.25; var magic = { tax: TAX, }; ``` Examples of **correct** code for this rule with option "ignoreEnums": ```typescript /*typescript no-magic-numbers: ["error", { "ignoreEnums": true }]*/ enum foo { SECOND = 1000, } ``` Examples of **correct** code for this rule with option "ignoreNumericLiteralTypes": ```typescript /*typescript no-magic-numbers: ["error", { "ignoreNumericLiteralTypes": true }]*/ type SmallPrimes = 2 | 3 | 5 | 7 | 11; ``` Examples of **correct** code for this rule with option "ignoreReadonlyClassProperties": ```typescript /*typescript no-magic-numbers: ["error", { "ignoreReadonlyClassProperties": true }]*/ class Foo { readonly A = 1; readonly B = 2; public static readonly C = 1; static readonly D = 1; } ``` Examples of **correct** code for this rule with option "ignoreTypeIndexes": ```typescript /*typescript no-magic-numbers: ["error", { "ignoreTypeIndexes": true }]*/ type Foo = Bar[0]; type Baz = Parameters[2]; ``` ## Configuration This rule accepts a configuration object with the following properties: ### detectObjects type: `boolean` default: `false` When true, numeric literals used in object properties are considered magic numbers. ### enforceConst type: `boolean` default: `false` When true, enforces that number constants must be declared using `const` instead of `let` or `var`. ### ignore type: `array` default: `[]` An array of numbers to ignore if used as magic numbers. Can include floats or BigInt strings. #### ignore\[n] type: `number | string` ### ignoreArrayIndexes type: `boolean` default: `false` When true, numeric literals used as array indexes are ignored. ### ignoreClassFieldInitialValues type: `boolean` default: `false` When true, numeric literals used as initial values in class fields are ignored. ### ignoreDefaultValues type: `boolean` default: `false` When true, numeric literals used as default values in function parameters and destructuring are ignored. ### ignoreEnums type: `boolean` default: `false` When true, numeric literals in TypeScript enums are ignored. ### ignoreNumericLiteralTypes type: `boolean` default: `false` When true, numeric literals used as TypeScript numeric literal types are ignored. ### ignoreReadonlyClassProperties type: `boolean` default: `false` When true, numeric literals in readonly class properties are ignored. ### ignoreTypeIndexes type: `boolean` default: `false` When true, numeric literals used to index TypeScript types are ignored. ## How to use ## Version This rule was added in v0.9.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-misleading-character-class.md --- ### What it does This rule reports regular expressions which include multiple code point characters in character class syntax. This includes: * Characters with combining marks (e.g., `Á` where `A` is followed by a combining acute accent) * Characters with emoji modifiers (e.g., `👶🏻`) * Pairs of regional indicator symbols (e.g., `🇯🇵`) * Characters joined by zero-width joiner (ZWJ) (e.g., `👨‍👩‍👦`) * Surrogate pairs without the Unicode flag (e.g., `/^[👍]$/`) ### Why is this bad? Unicode includes characters which are made by multiple code points. RegExp character class syntax (`/[abc]/`) cannot handle characters which are made by multiple code points as a character; those characters will be dissolved to each code point. For example, `❇️` is made by `❇` (`U+2747`) and VARIATION SELECTOR-16 (`U+FE0F`). If this character is in a RegExp character class, it will match either `❇` (`U+2747`) or VARIATION SELECTOR-16 (`U+FE0F`) rather than `❇️`. This can lead to regular expressions that do not match what the author intended, especially for emoji, regional indicators, and characters with combining marks. #### Examples Examples of **incorrect** code for this rule: ```javascript /^[Á]$/u; /^[❇️]$/u; /^[👶🏻]$/u; /^[🇯🇵]$/u; /^[👨‍👩‍👦]$/u; /^[👍]$/; new RegExp("[🎵]"); ``` Examples of **correct** code for this rule: ```javascript /^[abc]$/; /^[👍]$/u; /[\u00B7\u0300-\u036F]/u; new RegExp("^[\u{1F1EF}\u{1F1F5}]", "u"); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowEscape type: `boolean` default: `false` When set to `true`, the rule allows any grouping of code points inside a character class as long as they are written using escape sequences. Examples of **incorrect** code for this rule with `{ "allowEscape": true }`: ```javascript /[\uD83D]/; // backslash can be omitted new RegExp("[\ud83d" + "\udc4d]"); ``` Examples of **correct** code for this rule with `{ "allowEscape": true }`: ```javascript /[\ud83d\udc4d]/; /[\u00B7\u0300-\u036F]/u; /[👨\u200d👩]/u; new RegExp("[\x41\u0301]"); new RegExp(`[\u{1F1EF}\u{1F1F5}]`, "u"); new RegExp("[\\u{1F1EF}\\u{1F1F5}]", "u"); ``` ## How to use ## Version This rule was added in v1.17.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-multi-assign.md --- ### What it does Disallow use of chained assignment expressions. ### Why is this bad? Chaining the assignment of variables can lead to unexpected results and be difficult to read. ```js (function () { const foo = (bar = 0); // Did you mean `foo = bar == 0`? bar = 1; // This will not fail since `bar` is not constant. })(); console.log(bar); // This will output 1 since `bar` is not scoped. ``` ### Examples Examples of **incorrect** code for this rule: ```js var a = (b = c = 5); const foo = (bar = "baz"); let d = (e = f); class Foo { a = (b = 10); } a = b = "quux"; ``` Examples of **correct** code for this rule: ```js var a = 5; var b = 5; var c = 5; const foo = "baz"; const bar = "baz"; let d = c; let e = c; class Foo { a = 10; b = 10; } a = "quux"; b = "quux"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignoreNonDeclaration type: `boolean` default: `false` When set to `true`, the rule allows chains that don't include initializing a variable in a declaration or initializing a class field. Examples of **correct** code for this option set to `true`: ```js let a; let b; a = b = "baz"; const x = {}; const y = {}; x.one = y.one = 1; ``` Examples of **incorrect** code for this option set to `true`: ```js let a = (b = "baz"); const foo = (bar = 1); class Foo { a = (b = 10); } ``` ## How to use ## Version This rule was added in v0.15.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-multi-str.md --- ### What it does Disallow multiline strings. ### Why is this bad? Some consider this to be a bad practice as it was an undocumented feature of JavaScript that was only formalized later. ### Examples Examples of **incorrect** code for this rule: ```javascript var x = "Line 1 \ Line 2"; ``` ## How to use ## Version This rule was added in v0.5.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-negated-condition.md --- ### What it does Disallow negated conditions. ### Why is this bad? Negated conditions are more difficult to understand. Code can be made more readable by inverting the condition. ### Examples Examples of **incorrect** code for this rule: ```javascript if (!a) { doSomethingC(); } else { doSomethingB(); } !a ? doSomethingC() : doSomethingB(); ``` Examples of **correct** code for this rule: ```javascript if (a) { doSomethingB(); } else { doSomethingC(); } a ? doSomethingB() : doSomethingC(); ``` ## How to use ## Version This rule was added in v0.0.18. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-nested-ternary.md --- ### What it does Disallow nested ternary expressions. ### Why is this bad? Nested ternary expressions make code harder to read and understand. Nesting of these expressions can lead to complex logic that is difficult to understand. ### Examples Examples of **incorrect** code for this rule: ```js const result = condition1 ? (condition2 ? "a" : "b") : "c"; ``` Examples of **correct** code for this rule: ```js let result; if (condition1) { result = condition2 ? "a" : "b"; } else { result = "c"; } ``` ## How to use ## Version This rule was added in v0.15.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-new.md --- ### What it does Disallow new operators outside of assignments or comparisons. ### Why is this bad? Calling new without assigning or comparing it the reference is thrown away and in many cases the constructor can be replaced with a function. ### Examples Examples of **incorrect** code for this rule: ```javascript new Person(); () => { new Date(); }; ``` Examples of **correct** code for this rule: ```javascript var a = new Date()(() => new Date()); ``` ## How to use ## Version This rule was added in v0.4.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-new-func.md --- ### What it does Disallow `new` operators with the `Function` object. ### Why is this bad? Using `new Function` or `Function` can lead to code that is difficult to understand and maintain. It can introduce security risks similar to those associated with `eval` because it generates a new function from a string of code, which can be a vector for injection attacks. Additionally, it impacts performance negatively as these functions are not optimized by the JavaScript engine. ### Examples Examples of **incorrect** code for this rule: ```js var x = new Function("a", "b", "return a + b"); var x = Function("a", "b", "return a + b"); var x = Function.call(null, "a", "b", "return a + b"); var x = Function.apply(null, ["a", "b", "return a + b"]); var x = Function.bind(null, "a", "b", "return a + b")(); var f = Function.bind(null, "a", "b", "return a + b"); ``` Examples of **correct** code for this rule: ```js let x = function (a, b) { return a + b; }; ``` ## How to use ## Version This rule was added in v0.9.2. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-new-native-nonconstructor.md --- ### What it does Disallow `new` operators with global non-constructor functions (`Symbol`, `BigInt`). This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? Both `new Symbol` and `new BigInt` throw a type error because they are functions and not classes. It is easy to make this mistake by assuming the uppercase letters indicate classes. ### Examples Examples of **incorrect** code for this rule: ```js // throws a TypeError let foo = new Symbol("foo"); // throws a TypeError let result = new BigInt(9007199254740991); ``` Examples of **correct** code for this rule: ```js let foo = Symbol("foo"); let result = BigInt(9007199254740991); ``` ## How to use ## Version This rule was added in v0.3.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-new-wrappers.md --- ### What it does Disallow `new` operators with the `String`, `Number`, and `Boolean` objects. ### Why is this bad? The first problem is that primitive wrapper objects are, in fact, objects. That means `typeof` will return `"object"` instead of `"string"`, `"number"`, or `"boolean"`. The second problem comes with boolean objects. Every object is truthy, that means an instance of `Boolean` always resolves to `true` even when its actual value is `false`. https://eslint.org/docs/latest/rules/no-new-wrappers ### Examples Examples of **incorrect** code for this rule: ```js var stringObject = new String("Hello world"); var numberObject = new Number(33); var booleanObject = new Boolean(false); var symbolObject = new Symbol("foo"); // symbol is not a constructor ``` Examples of **correct** code for this rule: ```js var stringObject = "Hello world"; var stringObject2 = String(value); var numberObject = Number(value); var booleanObject = Boolean(value); var symbolObject = Symbol("foo"); ``` ## How to use ## Version This rule was added in v0.2.10. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-nonoctal-decimal-escape.md --- ### What it does Disallow `\8` and `\9` escape sequences in string literals. ### Why is this bad? ECMAScript specification treats `\8` and `\9` in string literals as a legacy feature ### Examples Examples of **incorrect** code for this rule: ```javascript let x = "\8"; let y = "\9"; ``` Examples of **correct** code for this rule: ```javascript let x = "8"; let y = "\\9"; ``` ## How to use ## Version This rule was added in v0.2.10. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-obj-calls.md --- ### What it does Disallow calling some global objects as functions. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? Some global objects are not intended to be called as functions. Calling them as functions will usually result in a TypeError being thrown. ### Examples Examples of **incorrect** code for this rule: ```javascript let math = Math(); let newMath = new Math(); let json = JSON(); let newJson = new JSON(); let atomics = Atomics(); let newAtomics = new Atomics(); let intl = Intl(); let newIntl = new Intl(); let reflect = Reflect(); let newReflect = new Reflect(); ``` Examples of **correct** code for this rule: ```javascript let area = (r) => 2 * Math.PI * r * r; let object = JSON.parse("{}"); let first = Atomics.load(sharedArray, 0); let segmenterFrom = Intl.Segmenter("fr", { granularity: "word" }); ``` ## How to use ## Version This rule was added in v0.0.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-object-constructor.md --- ### What it does Disallow calls to the Object constructor without an argument. ### Why is this bad? Use of the Object constructor to construct a new empty object is generally discouraged in favor of object literal notation because of conciseness and because the Object global may be redefined. The exception is when the Object constructor is used to intentionally wrap a specified value which is passed as an argument. ### Examples Examples of **incorrect** code for this rule: ```js Object(); new Object(); ``` Examples of **correct** code for this rule: ```js Object("foo"); const obj = { a: 1, b: 2 }; const isObject = (value) => value === Object(value); const createObject = (Object) => new Object(); ``` ## How to use ## Version This rule was added in v0.13.2. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-param-reassign.md --- ### What it does Disallow reassigning function parameters or, optionally, their properties. ### Why is this bad? Reassigning parameters can lead to unexpected behavior, especially when relying on the original arguments passed into the function. Mutating parameter properties can be similarly surprising and harder to reason about. ### Examples ```javascript function foo(bar) { bar = 1; } function baz(qux) { qux.prop = 2; // when `props` option is enabled } ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignorePropertyModificationsFor type: `string[]` default: `[]` An array of parameter names whose property modifications should be ignored. ### ignorePropertyModificationsForRegex type: `string[]` An array of regex patterns (as strings) for parameter names whose property modifications should be ignored. Note that this uses [Rust regex syntax](https://docs.rs/regex/latest/regex/) and so may not have all features available to JavaScript regexes. ### props type: `boolean` default: `false` When true, also check for modifications to properties of parameters. ## How to use ## Version This rule was added in v1.20.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-plusplus.md --- ### What it does Disallow the unary operators `++` and `--`. ### Why is this bad? Because the unary `++` and `--` operators are subject to automatic semicolon insertion, differences in whitespace can change the semantics of source code. For example, these two code blocks are not equivalent: ```js var i = 10; var j = 20; i++; j; // => i = 11, j = 20 ``` ```js var i = 10; var j = 20; i; ++j; // => i = 10, j = 21 ``` ### Examples Examples of **incorrect** code for this rule: ```js var x = 0; x++; var y = 0; y--; for (let i = 0; i < l; i++) { doSomething(i); } ``` Examples of **correct** code for this rule: ```js var x = 0; x += 1; var y = 0; y -= 1; for (let i = 0; i < l; i += 1) { doSomething(i); } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowForLoopAfterthoughts type: `boolean` default: `false` Whether to allow `++` and `--` in for loop afterthoughts. ## How to use ## Version This rule was added in v0.9.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-promise-executor-return.md --- ### What it does Disallow returning values from Promise executor functions. ### Why is this bad? The `new Promise` constructor accepts an executor function as an argument, which has `resolve` and `reject` parameters that can be used to control the state of the created Promise. The return value of the executor is ignored. Returning a value from an executor function is a possible error because the returned value cannot be used and it doesn't affect the promise in any way. ### Examples Examples of **incorrect** code for this rule: ```javascript new Promise((resolve, reject) => { if (someCondition) { return defaultResult; } getSomething((err, result) => { if (err) { reject(err); } else { resolve(result); } }); }); new Promise((resolve, reject) => getSomething((err, data) => { if (err) { reject(err); } else { resolve(data); } }), ); new Promise(() => { return 1; }); ``` Examples of **correct** code for this rule: ```javascript new Promise((resolve, reject) => { if (someCondition) { resolve(defaultResult); return; } getSomething((err, result) => { if (err) { reject(err); } else { resolve(result); } }); }); new Promise((resolve, reject) => { getSomething((err, data) => { if (err) { reject(err); } else { resolve(data); } }); }); new Promise((r) => { r(1); }); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowVoid type: `boolean` default: `false` If `true`, allows returning `void` expressions (e.g., `return void resolve()`). ## How to use ## Version This rule was added in v1.33.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-proto.md --- ### What it does Disallow the use of the `__proto__` property. ### Why is this bad? The `__proto__` property has been deprecated as of ECMAScript 3.1 and shouldn’t be used in new code. Use `Object.getPrototypeOf` and `Object.setPrototypeOf` instead. For more information, see [the MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto). ### Examples Examples of **incorrect** code for this rule: ```javascript var a = obj.__proto__; var a = obj["__proto__"]; obj.__proto__ = b; obj["__proto__"] = b; ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-prototype-builtins.md --- ### What it does Disallow calling some `Object.prototype` methods directly on objects. ### Why is this bad? In ECMAScript 5.1, `Object.create` was added, which enables the creation of objects with a specified \[\[Prototype]]. `Object.create(null)` is a common pattern used to create objects that will be used as a Map. This can lead to errors when it is assumed that objects will have properties from `Object.prototype`. This rule prevents calling some `Object.prototype` methods directly from an object. Additionally, objects can have properties that shadow the builtins on `Object.prototype`, potentially causing unintended behavior or denial-of-service security vulnerabilities. For example, it would be unsafe for a webserver to parse JSON input from a client and call `hasOwnProperty` directly on the resulting object, because a malicious client could send a JSON value like {"hasOwnProperty": 1} and cause the server to crash. To avoid subtle bugs like this, it’s better to always call these methods from `Object.prototype`. For example, `foo.hasOwnProperty("bar")` should be replaced with `Object.prototype.hasOwnProperty.call(foo, "bar")`. ### Examples Examples of **incorrect** code for this rule: ```javascript var hasBarProperty = foo.hasOwnProperty("bar"); var isPrototypeOfBar = foo.isPrototypeOf(bar); var barIsEnumerable = foo.propertyIsEnumerable("bar"); ``` ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-redeclare.md --- ### What it does This rule disallows redeclaring variables within the same scope, ensuring that each variable is declared only once. It helps avoid confusion and unintended behavior in code. ### Why is this bad? Redeclaring variables in the same scope can lead to unexpected behavior, overwriting existing values, and making the code harder to understand and maintain. ### Examples Examples of **incorrect** code for this rule: ```javascript var a = 3; var a = 10; ``` Examples of **correct** code for this rule: ```javascript var a = 3; a = 10; ``` ## Configuration This rule accepts a configuration object with the following properties: ### builtinGlobals type: `boolean` default: `true` When set `true`, it flags redeclaring built-in globals (e.g., `let Object = 1;`). ## How to use ## Version This rule was added in v0.0.13. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-regex-spaces.md --- ### What it does Disallow 2+ consecutive spaces in regular expressions. ### Why is this bad? In a regular expression, it is hard to tell how many spaces are intended to be matched. It is better to use only one space and then specify how many spaces are expected using a quantifier. ```javascript var re = /foo {3}bar/; ``` ### Examples Examples of **incorrect** code for this rule: ```javascript var re = /foo bar/; ``` ## How to use ## Version This rule was added in v0.0.18. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-restricted-exports.md --- ### What it does This rule disallows specified names from being used as exported names. By default, this rule doesn’t disallow any names. Only the names you specify in the configuration will be disallowed. ### Why is this bad? In a project, certain names may be disallowed from being used as exported names for various reasons. ## Configuration This rule accepts a configuration object with the following properties: ### restrictDefaultExports type: `object` An object with boolean properties to restrict certain default export declarations. This option works only if the `restrictedNamedExports` option does not contain the `"default"` value. #### restrictDefaultExports.defaultFrom type: `boolean` default: `false` Whether to restrict `export { default } from` declarations. Example of **incorrect** code for `"restrictDefaultExports": { "defaultFrom": true }`: ```js export { default } from "foo"; ``` #### restrictDefaultExports.direct type: `boolean` default: `false` Whether to restrict `export default` declarations. Example of **incorrect** code for `"restrictDefaultExports": { "direct": true }`: ```js const foo = 123; export default foo; ``` #### restrictDefaultExports.named type: `boolean` default: `false` Whether to restrict `export { foo as default }` declarations. Example of **incorrect** code for `"restrictDefaultExports": { "named": true }`: ```js const foo = 123; export { foo as default }; ``` #### restrictDefaultExports.namedFrom type: `boolean` default: `false` Whether to restrict `export { foo as default } from` declarations. Example of **incorrect** code for `"restrictDefaultExports": { "namedFrom": true }`: ```js export { foo as default } from "foo"; ``` #### restrictDefaultExports.namespaceFrom type: `boolean` default: `false` Whether to restrict `export * as default from` declarations. Example of **incorrect** code for `"restrictDefaultExports": { "namespaceFrom": true }`: ```js export * as default from "foo"; ``` ### restrictedNamedExports type: `string[]` default: `[]` An array of strings, where each string is a name to be restricted. Example of **incorrect** code for `"restrictedNamedExports": ["foo"]`: ```ts export const foo = 1; ``` Example of **correct** code for `"restrictedNamedExports": ["foo"]`: ```ts export const bar = 1; ``` By design, this option doesn't disallow export default declarations. If you configure `default` as a restricted name, that restriction will apply only to named export declarations. Example of **incorrect** code for `"restrictedNamedExports": ["default"]`: ```ts function foo() {} export { foo as default }; export { default } from "some_module"; ``` ### restrictedNamedExportsPattern type: `string` A string representing a regular expression pattern. Named exports matching this pattern will be restricted. This option does not apply to default named exports. Example of **incorrect** code for \`"restrictedNamedExportsPattern": "bar$": ```ts export const foobar = 1; ``` Example of **correct** code for \`"restrictedNamedExportsPattern": "bar$": ```ts export const foo = 1; ``` ## How to use ## Version This rule was added in v1.59.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-restricted-globals.md --- ### What it does Specify global variable names that should not be used in your application. ### Why is this bad? Disallowing usage of specific global variables can be useful if you want to allow a set of global variables by enabling an environment, but still want to disallow some of those. For instance, early Internet Explorer versions exposed the current DOM event as a global variable `event`, but using this variable has been considered as a bad practice for a long time. Restricting this will make sure this variable isn't used in browser code. ### Examples If we have options: ```json "no-restricted-globals": ["error", "event"] ``` The following patterns are considered problems: ```javascript function onClick() { console.log(event); // Unexpected global variable 'event'. Use local parameter instead. } ``` ## How to use ## Version This rule was added in v0.4.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-restricted-imports.md --- ### What it does This rule allows you to specify imports that you don’t want to use in your application. It applies to static imports and to dynamic `import()` with a string-literal source; computed sources like `import(bar)` are ignored. ### Why is this bad? Some imports might not make sense in a particular environment. For example, Node.js’ fs module would not make sense in an environment that didn’t have a file system. Some modules provide similar or identical functionality, think lodash and underscore. Your project may have standardized on a module. You want to make sure that the other alternatives are not being used as this would unnecessarily bloat the project and provide a higher maintenance cost of two dependencies when one would suffice. ### Examples Examples of **incorrect** code for this rule: ```js /* no-restricted-imports: ["error", "disallowed-import"] */ import foo from "disallowed-import"; export * from "disallowed-import"; ``` Examples of **correct** code for this rule: ```js /* no-restricted-imports: ["error", "fs"] */ import crypto from "crypto"; export * from "bar"; ``` ### Options You may also specify a custom message for a particular module using the `name` and `message` properties inside an object, where the value of the name is the `name` of the module and message property contains the custom message. The custom message will be displayed as a help text for the user. Examples of **incorrect** code for this rule: ```js /* no-restricted-imports: ["error", { "name": "disallowed-import", "message": "Please use 'allowed-import' instead" }] */ import foo from "disallowed-import"; ``` #### paths This is an object option whose value is an array containing the names of the modules you want to restrict. ```json {"rules: {"no-restricted-imports": ["error", { "paths": ["import1", "import2"] }]}} ``` Examples of **incorrect** code for `paths`: ```js /* no-restricted-imports: ["error", { "paths": ["cluster"] }] */ import cluster from "cluster"; ``` Custom messages for a particular module can also be specified in `paths` array using objects with `name` and `message`. ```json "no-restricted-imports": ["error", { "paths": [{ "name": "import-foo", "message": "Please use import-bar instead." }, { "name": "import-baz", "message": "Please use import-quux instead." }] }] ``` ##### importNames This option in `paths` is an array and can be used to specify the names of certain bindings exported from a module. Import names specified inside `paths` array affect the module specified in the `name` property of corresponding object, so it is required to specify the `name` property first when you are using `importNames` or `message` option. Specifying `"default"` string inside the `importNames` array will restrict the default export from being imported. Examples of **incorrect** code for this rule: ```js /* no-restricted-imports: ["error", { paths: [{ "name": "foo", "importNames": ["default"] }, { "name": "bar", "importNames": ["Baz"] }]}] */ import DisallowedObject from "foo"; import { Baz } from "far"; ``` ##### allowImportNames This option is an array. Inverse of `importNames`, `allowImportNames` allows the imports that are specified inside this array. So it restricts all imports from a module, except specified allowed ones. Note: `allowImportNames` cannot be used in combination with `importNames`. Examples of **incorrect** code for this rule: ```js /* no-restricted-imports: ["error", { paths: [{ "name": "foo", "allowImportNames": ["AllowedObject"], "message": "Please use only 'AllowedObject' from 'foo'." }]}] */ import { DisallowedObject } from "foo"; ``` #### allowTypeImports Whether to allow type-only imports for a path. Default: `false`. Examples of **incorrect** code for this rule: ```typescript /* no-restricted-imports: ["error", { paths: [{ "name": "foo", "allowTypeImports": true }]}] */ import foo from "import-foo"; export { Foo } from "import-foo"; ``` Examples of **correct** code for this rule: ```typescript /* no-restricted-imports: ["error", { paths: [{ "name": "foo", "allowTypeImports": true }]}] */ import type foo from "import-foo"; export type { Foo } from "import-foo"; ``` #### patterns This is also an object option whose value is an array. This option allows you to specify multiple modules to restrict using `gitignore`-style patterns or regular expressions. Where `paths` option takes exact import paths, `patterns` option can be used to specify the import paths with more flexibility, allowing for the restriction of multiple modules within the same directory. For example: ```json "no-restricted-imports": ["error", { "paths": [{ "name": "import-foo", }] }] ``` This configuration restricts import of the `import-foo` module but wouldn’t restrict the import of `import-foo/bar` or `import-foo/baz`. You can use `patterns` to restrict both: ```json "no-restricted-imports": ["error", { "paths": [{ "name": "import-foo", }], "patterns": [{ "group": ["import-foo/ba*"], }] }] ``` This configuration restricts imports not just from `import-foo` using path, but also `import-foo/bar` and `import-foo/baz` using `patterns`. You can also use regular expressions to restrict modules (see the `regex` option). Examples of **incorrect** code for `patterns` option: ```js /* no-restricted-imports: ["error", { "patterns": ["lodash/*"] }] */ import pick from "lodash/pick"; ``` Examples of **correct** code for `patterns` option: ```js /* no-restricted-imports: ["error", { "patterns": ["crypto/*"] }] */ import crypto from "crypto"; ``` ##### group The `patterns` array can also include objects. The `group` property is used to specify the `gitignore`-style patterns for restricting modules and the `message` property is used to specify a custom message. Either of the `group` or `regex` properties is required when using the `patterns` option. Examples of **incorrect** code for `group` option: ```js /* no-restricted-imports: ["error", { patterns: [{ group: ["lodash/*"], message: "Please use the default import from 'lodash' instead." }]}] */ import pick from "lodash/pick"; ``` ##### regex The `regex` property is used to specify the regex patterns for restricting modules. Note: `regex` cannot be used in combination with `group`. **Warning**: This rule uses the [Rust-Regex](https://docs.rs/regex/latest/regex/), which supports not all features of JS-Regex, like Lookahead and Lookbehinds. Examples of **incorrect** code for `regex` option: ```js /* no-restricted-imports: ["error", { patterns: [{ regex: "@app/(api|enums).*", }]}] */ import Foo from "@app/api"; import Bar from "@app/api/bar"; import Baz from "@app/api/baz"; import Bux from "@app/api/enums/foo"; ``` ##### caseSensitive This is a boolean option and sets the patterns specified in the `group` property to be case-sensitive when `true`. Default is `false`. **Warning**: It will not apply case-sensitive checks to `regex`. `regex` uses Rust-RegEx which has its own implementation of case-sensitive. ##### importNames You can also specify `importNames` within objects inside the `patterns` array. In this case, the specified names apply only to the associated `group` or `regex` property. Examples of **incorrect** code for `importNames` in `patterns`: ```js /* no-restricted-imports: ["error", { patterns: [{ group: ["utils/*"], importNames: ['isEmpty'], message: "Use 'isEmpty' from lodash instead." }]}] */ import { isEmpty } from "utils/collection-utils"; ``` ##### allowImportNames You can also specify `allowImportNames` within objects inside the `patterns` array. In this case, the specified names apply only to the associated `group` or `regex` property. Note: `allowImportNames` cannot be used in combination with `importNames`, `importNamePattern` or `allowImportNamePattern`. ##### importNamePattern This option allows you to use regex patterns to restrict import names. Examples of **incorrect** code for `importNamePattern` option: ```js /* no-restricted-imports: ["error", { patterns: [{ group: ["foo/*"], importNamePattern: '^(is|has)', message: "Use 'is*' and 'has*' functions from baz/bar instead" }]}] */ import { isSomething, hasSomething } from "foo/bar"; ``` ##### allowImportNamePattern This is a string option. Inverse of `importNamePattern`, this option allows imports that matches the specified regex pattern. So it restricts all imports from a module, except specified allowed patterns. Note: `allowImportNamePattern` cannot be used in combination with `importNames`, `importNamePattern` or `allowImportNames`. ```json "no-restricted-imports": ["error", { "patterns": [{ "group": ["import-foo/*"], "allowImportNamePattern": "^foo", }] }] ``` Examples of **incorrect** code for `allowImportNamePattern` option: ```js /* no-restricted-imports: ["error", { patterns: [{ group: ["utils/*"], allowImportNamePattern: '^has' }]}] */ import { isEmpty } from "utils/collection-utils"; ``` Examples of **correct** code for `allowImportNamePattern` option: ```js /* no-restricted-imports: ["error", { patterns: [{ group: ["utils/*"], allowImportNamePattern: '^is' }]}] */ import { isEmpty } from "utils/collection-utils"; ``` ## How to use ## Version This rule was added in v0.15.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-restricted-properties.md --- ### What it does This rule allows you to disallow access to certain properties on certain objects. ### Why is this bad? Certain properties on objects may be disallowed in a codebase. This is useful for deprecating an API or restricting usage of a module’s methods. For example, you may want to disallow using describe.only when using Mocha or telling people to use Object.assign instead of \_.extend. If you want to disallow APIs marked with `@deprecated`, consider using the type-aware `typescript/no-deprecated` rule instead. ### Examples **With options:** ```json "no-restricted-properties": ["error", { "object": "JSON", "property": "parse" }] ``` Examples of **incorrect** code for this rule: ```js /* no-restricted-properties: ["error", { "object": "JSON", "property": "parse" }] */ JSON.parse('{ "json": "here" }'); // 'JSON.parse' is restricted from being used. ``` Examples of **correct** code for this rule: ```js /* no-restricted-properties: ["error", { "object": "JSON", "property": "parse" }] */ JSON.stringify({ json: "here" }); ``` **With options:** ```json "no-restricted-properties": ["error", { "property": "extend", "allowObjects": ["safeUtils"] }] ``` Examples of **incorrect** code for this rule: ```js /* no-restricted-properties: ["error", { "property": "extend", "allowObjects": ["safeUtils"] }] */ unsafeUtils.extend(value); // 'extend' is restricted from being used. Property 'extend' is only allowed on these objects: safeUtils. ``` Examples of **correct** code for this rule: ```js /* no-restricted-properties: ["error", { "property": "extend", "allowObjects": ["safeUtils"] }] */ safeUtils.extend(value); ``` **With options:** ```json "no-restricted-properties": ["error", { "object": "legacyApi", "allowProperties": ["stableMethod"] }] ``` Examples of **incorrect** code for this rule: ```js /* no-restricted-properties: ["error", { "object": "legacyApi", "allowProperties": ["stableMethod"] }] */ legacyApi.unstableMethod(); // 'legacyApi' is restricted from being used. Only these properties are allowed: stableMethod. ``` Examples of **correct** code for this rule: ```js /* no-restricted-properties: ["error", { "object": "legacyApi", "allowProperties": ["stableMethod"] }] */ legacyApi.stableMethod(); ``` ## How to use ## Version This rule was added in v1.63.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-return-assign.md --- ### What it does Disallows assignment operators in return statements. ### Why is this bad? Assignment is allowed by js in return expressions, but usually, an expression with only one equal sign is intended to be a comparison. However, because of the missing equal sign, this turns to assignment, which is valid js code Because of this ambiguity, it’s considered a best practice to not use assignment in return statements. ### Examples Examples of **incorrect** code for this rule: ```js () => (a = b); function x() { return (a = b); } ``` Examples of **correct** code for this rule: ```js () => (a = b); function x() { var result = (a = b); return result; } ``` ## Configuration This rule accepts one of the following string values: ### `"always"` Disallow all assignments in return statements. ### `"except-parens"` Allow assignments in return statements only if they are enclosed in parentheses. This is the default mode. ## How to use ## Version This rule was added in v0.9.10. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-script-url.md --- ### What it does Disallow `javascript:` URLs. ### Why is this bad? Using `javascript:` URLs is considered by some as a form of `eval`. Code passed in `javascript:` URLs must be parsed and evaluated by the browser in the same way that `eval` is processed. This can lead to security and performance issues. ### Examples Examples of **incorrect** code for this rule: ```javascript location.href = "javascript:void(0)"; location.href = `javascript:void(0)`; ``` ## How to use ## Version This rule was added in v0.2.15. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-self-assign.md --- ### What it does Disallow assignments where both sides are exactly the same. ### Why is this bad? Self assignments have no effect, so probably those are an error due to incomplete refactoring. Those indicate that what you should do is still remaining. ### Examples Examples of **incorrect** code for this rule: ```javascript foo = foo; [a, b] = [a, b]; [a, ...b] = [x, ...b]; ({ a, b } = { a, x }); foo &&= foo; foo ||= foo; foo ??= foo; ``` ```javascript obj.a = obj.a; obj.a.b = obj.a.b; obj["a"] = obj["a"]; obj[a] = obj[a]; ``` Examples of **correct** code for this rule: ```javascript foo = bar; [a, b] = [b, a]; // This pattern is warned by the `no-use-before-define` rule. let foo = foo; // The default values have an effect. [foo = 1] = [foo]; // This ignores if there is a function call. obj.a().b = obj.a().b; a().b = a().b; // `&=` and `|=` have an effect on non-integers. foo &= foo; foo |= foo; ``` ## Configuration This rule accepts a configuration object with the following properties: ### props type: `boolean` default: `true` The `props` option when set to `false`, disables the checking of properties. With `props` set to `false` the following are examples of correct code: ```javascript obj.a = obj.a; obj.a.b = obj.a.b; obj["a"] = obj["a"]; obj[a] = obj[a]; ``` ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-self-compare.md --- ### What it does Disallow comparisons where both sides are exactly the same. ### Why is this bad? Comparing a variable against itself is usually an error, either a typo or refactoring error. It is confusing to the reader and may potentially introduce a runtime error. ### Examples Examples of **incorrect** code for this rule: ```javascript var x = 10; if (x === x) { x = 20; } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-sequences.md --- ### What it does Disallows the use of the comma operator. ### Why is this bad? The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand. However, this frequently obscures side effects, and its use is often an accident. ### Examples Examples of **incorrect** code for this rule: ```javascript ((foo = doSomething()), val); (0, eval("doSomething();")); // Arrow function body needs double parentheses const fn = () => (doSomething(), val); // with allowInParentheses: false foo = (doSomething(), val); ``` Examples of **correct** code for this rule: ```javascript foo = (doSomething(), val); (0, eval)("doSomething();"); // Single extra parentheses is enough for conditions do {} while ((doSomething(), !!test)); for (i = 0, j = 10; i < j; i++, j--) {} // Arrow function body needs double parentheses const fn = () => (doSomething(), val); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowInParentheses type: `boolean` default: `true` If this option is set to `false`, this rule disallows the comma operator even when the expression sequence is explicitly wrapped in parentheses. ## How to use ## Version This rule was added in v1.33.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-setter-return.md --- ### What it does Setters cannot return values. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? While returning a value from a setter does not produce an error, the returned value is being ignored. Therefore, returning a value from a setter is either unnecessary or a possible error, since the returned value cannot be used. ### Examples Examples of **incorrect** code for this rule: ```javascript class URL { set origin() { return true; } } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-shadow.md --- ### What it does Disallows variable declarations from shadowing variables declared in the outer scope. ### Why is this bad? Shadowing is the process by which a local variable shares the same name as a variable in its containing scope. This can cause confusion, as it may be unclear which variable is being referenced, and can lead to bugs that are difficult to diagnose. ### Examples Examples of **incorrect** code for this rule: ```js var x = 1; function foo() { var x = 2; // x shadows the outer x } ``` Examples of **correct** code for this rule: ```js var x = 1; function foo() { var y = 2; // different name, no shadowing } ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` default: `[]` List of variable names that are allowed to shadow. ### builtinGlobals type: `boolean` default: `false` Whether to report shadowing of built-in global variables. ### hoist type: `"all" | "functions" | "functions-and-types" | "never" | "types"` default: `"functions-and-types"` Controls how hoisting is handled when checking for shadowing. #### `"all"` Report shadowing even before the outer variable is declared (due to hoisting). #### `"functions"` Only report shadowing for function declarations that are hoisted. #### `"functions-and-types"` Report shadowing for both function and type declarations that are hoisted. #### `"never"` Never report shadowing before the outer variable is declared. #### `"types"` Only report shadowing for type declarations that are hoisted. ### ignoreFunctionTypeParameterNameValueShadow type: `boolean` default: `true` If `true`, ignore when a function type parameter shadows a value. Example: `const T = 1; function foo() {}` ### ignoreOnInitialization type: `boolean` default: `false` Whether to ignore the variable initializers when the shadowed variable is presumably still uninitialized. ### ignoreTypeValueShadow type: `boolean` default: `true` If `true`, ignore when a type and a value have the same name. This is common in TypeScript: `type Foo = ...; const Foo = ...;` ## How to use ## Version This rule was added in v1.48.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-shadow-restricted-names.md --- ### What it does Disallows the redefining of global variables such as `undefined`, `NaN`, `Infinity`, `eval`, `globalThis` and `arguments`. ### Why is this bad? Value properties of the Global Object `NaN`, `Infinity`, `undefined`, `globalThis` as well as the strict mode restricted identifiers `eval` and `arguments` are considered to be restricted names in JavaScript. Defining them to mean something else can have unintended consequences and confuse others reading the code. For example, there’s nothing preventing you from writing: ```javascript var undefined = "foo"; ``` Then any code used within the same scope would not get the global `undefined`, but rather the local version with a very different meaning. ### Examples Examples of **incorrect** code for this rule: ```javascript function NaN() {} !function (Infinity) {}; var undefined = 5; try { } catch (eval) {} const globalThis = "foo"; ``` ```javascript import NaN from "foo"; import { undefined } from "bar"; class Infinity {} ``` Examples of **correct** code for this rule: ```javascript var Object; function f(a, b) {} // Exception: `undefined` may be shadowed if the variable is never assigned a value. var undefined; ``` ```javascript import { undefined as undef } from "bar"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### reportGlobalThis type: `boolean` default: `true` If true, also report shadowing of `globalThis`. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-sparse-arrays.md --- ### What it does Disallow sparse arrays. ### Why is this bad? Take the following example: ```javascript const items = [, ,]; ``` While the items array in this example has a length of 2, there are actually no values in items\[0] or items\[1]. The fact that the array literal is valid with only commas inside, coupled with the length being set and actual item values not being set, make sparse arrays confusing for many developers. The confusion around sparse arrays is enough that it’s recommended to avoid using them unless you are certain that they are useful in your code. ### Examples Examples of **incorrect** code for this rule: ```javascript var items = [, ,]; ``` ```javascript var colors = ["red", , "blue"]; ``` Examples of **correct** code for this rule: ```javascript var items = []; ``` // trailing comma (after the last element) is not a problem ```javascript var colors = ["red", "blue"]; ``` ## How to use ## Version This rule was added in v0.0.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-template-curly-in-string.md --- ### What it does Disallow template literal placeholder syntax in regular strings. This rule ensures that expressions like `${variable}` are only used within template literals, avoiding incorrect usage in regular strings. ### Why is this bad? ECMAScript 6 allows programmers to create strings containing variables or expressions using template literals. This is done by embedding expressions like `${variable}` between backticks. If regular quotes (`'` or `"`) are used with template literal syntax, it results in the literal string `"${variable}"` instead of evaluating the expression. This rule helps to avoid this mistake, ensuring that expressions are correctly evaluated inside template literals. ### Examples Examples of **incorrect** code for this rule: ```javascript "Hello ${name}!"; "Hello ${name}!"; "Time: ${12 * 60 * 60 * 1000}"; ``` Examples of **correct** code for this rule: ```javascript `Hello ${name}!`; `Time: ${12 * 60 * 60 * 1000}`; templateFunction`Hello ${name}`; ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-ternary.md --- ### What it does Disallow ternary operators. ### Why is this bad? The ternary operator is used to conditionally assign a value to a variable. Some believe that the use of ternary operators leads to unclear code. ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = isBar ? baz : qux; ``` ```javascript function quux() { return foo ? bar() : baz(); } ``` Examples of **correct** code for this rule: ```javascript let foo; if (isBar) { foo = baz; } else { foo = qux; } ``` ```javascript function quux() { if (foo) { return bar(); } else { return baz(); } } ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-this-before-super.md --- ### What it does Requires calling `super()` before using `this` or `super`. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? In the constructor of derived classes, if `this`/`super` are used before `super()` calls, it raises a `ReferenceError`. ### Examples Examples of **incorrect** code for this rule: ```javascript class A1 extends B { constructor() { // super() needs to be called first this.a = 0; super(); } } ``` ## How to use ## Version This rule was added in v0.2.6. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-throw-literal.md --- ### What it does Disallows throwing literals or non-Error objects as exceptions. ::: warning This rule has been deprecated, please instead use [typescript/only-throw-error](https://oxc.rs/docs/guide/usage/linter/rules/typescript/only-throw-error.html). The typescript rule is more reliable than the Javascript version, as it has less false positive, and can catch more cases. ::: ### Why is this bad? It is considered good practice to only throw the Error object itself or an object using the Error object as base objects for user-defined exceptions. The fundamental benefit of Error objects is that they automatically keep track of where they were built and originated. ### Examples Examples of **incorrect** code for this rule: ```js throw "error"; throw 0; throw undefined; throw null; var err = new Error(); throw "an " + err; // err is recast to a string literal var err = new Error(); throw `${err}`; ``` Examples of **correct** code for this rule: ```js throw new Error(); throw new Error("error"); var e = new Error("error"); throw e; try { throw new Error("error"); } catch (e) { throw e; } ``` ## How to use ## Version This rule was added in v0.9.10. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unassigned-vars.md --- ### What it does Disallow let or var variables that are read but never assigned. ### Why is this bad? This rule flags let or var declarations that are never assigned a value but are still read or used in the code. Since these variables will always be `undefined`, their usage is likely a programming mistake. ### Examples Examples of **incorrect** code for this rule: ```js let status; if (status === "ready") { console.log("Ready!"); } ``` Examples of **correct** code for this rule: ```js let message = "hello"; console.log(message); let user; user = getUser(); console.log(user.name); ``` ## How to use ## Version This rule was added in v1.10.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-undef.md --- ### What it does Disallow the use of undeclared variables. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? It is most likely a potential ReferenceError caused by a misspelling of a variable or parameter name. ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = someFunction(); var bar = a + 1; ``` ## Configuration This rule accepts a configuration object with the following properties: ### typeof type: `boolean` default: `false` When set to `true`, warns on undefined variables used in a `typeof` expression. ## How to use ## Version This rule was added in v0.0.8. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-undefined.md --- ### What it does Disallow the use of `undefined` as an identifier. ### Why is this bad? Using `undefined` directly can lead to bugs, since it can be shadowed or overwritten in JavaScript. It's safer and more intentional to use `null` or rely on implicit `undefined` (e.g., missing return) to avoid accidental issues. ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = undefined; var undefined = "foo"; if (foo === undefined) { // ... } function baz(undefined) { // ... } bar(undefined, "lorem"); ``` Examples of **correct** code for this rule: ```javascript var foo = void 0; var Undefined = "foo"; if (typeof foo === "undefined") { // ... } global.undefined = "foo"; bar(void 0, "lorem"); ``` ## How to use ## Version This rule was added in v0.5.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-underscore-dangle.md --- ### What it does Disallows dangling underscores in identifiers. ### Why is this bad? There is a long history of using `_` as a prefix or suffix for private members in JavaScript. It is however recommended to use the formal private class feature introduced in ES2022. See for more information. ### Examples Examples of **incorrect** code for this rule: ```js let foo_; const __proto__ = {}; foo._bar(); ``` Examples of **correct** code for this rule: ```js const _ = require("underscore"); const obj = _.contains(items, item); obj.__proto__ = {}; const file = __filename; function foo(_bar) {} const bar = { onClick(_bar) {} }; const baz = (_bar) => {}; ``` ## Configuration ### allow type: `string[]` default: `[]` An array of variable names that are allowed to have dangling underscores. ### allowAfterSuper type: `boolean` default: `false` Whether to allow dangling underscores in members of the `super` object. ### allowAfterThis type: `boolean` default: `false` Whether to allow dangling underscores in members of the `this` object. ### allowAfterThisConstructor type: `boolean` default: `false` Whether to allow dangling underscores in members of the `this.constructor` object. ### allowFunctionParams type: `boolean` default: `true` Whether to allow dangling underscores in function parameter names. ### allowInArrayDestructuring type: `boolean` default: `true` Whether to allow dangling underscores in variable names assigned by array destructuring. ### allowInObjectDestructuring type: `boolean` default: `true` Whether to allow dangling underscores in variable names assigned by object destructuring. ### allowInUsingDeclarations type: `boolean` default: `false` Whether to allow dangling underscores in `using` and `await using` declarations. ### enforceInClassFields type: `boolean` default: `false` Whether to enforce dangling underscores in class field names. ### enforceInMethodNames type: `boolean` default: `false` Whether to enforce dangling underscores in method names. ## How to use ## Version This rule was added in v1.62.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unexpected-multiline.md --- ### What it does In most cases, semicolons are not required in JavaScript in order for code to be parsed and executed as expected. Typically this occurs because semicolons are automatically inserted based on a fixed set of rules. This rule exists to detect those cases where a semicolon is NOT inserted automatically, and may be parsed differently than expected. ### Why is this bad? Code that has unexpected newlines may be parsed and executed differently than what the developer intended. This can lead to bugs that are difficult to track down. ### Examples Examples of **incorrect** code for this rule: ```js var a = b(x || y).doSomething(); var a = b[(a, b, c)].forEach(doSomething); let x = (function () {})`hello`; foo / bar / g.test(baz); ``` Examples of **correct** code for this rule: ```js var a = b; (x || y).doSomething(); var a = b; [a, b, c].forEach(doSomething); let x = function () {}; `hello`; foo; /bar/g.test(baz); ``` ## How to use ## Version This rule was added in v0.9.7. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unmodified-loop-condition.md --- ### What it does Disallow references in loop conditions that are never modified within the loop. ### Why is this bad? A loop condition that depends on values that never change within the loop body can cause infinite loops or logic bugs. ### Examples Examples of **incorrect** code for this rule: ```js let done = false; while (!done) { work(); } ``` Examples of **correct** code for this rule: ```js let done = false; while (!done) { done = checkDone(); } ``` ## How to use ## Version This rule was added in v1.48.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unneeded-ternary.md --- ### What it does Disallow ternary operators when simpler alternatives exist. ### Why is this bad? It’s a common mistake in JavaScript to use a conditional expression to select between two Boolean values instead of using ! to convert the test to a Boolean. Another common mistake is using a single variable as both the conditional test and the consequent. In such cases, the logical OR can be used to provide the same functionality. ### Examples Examples of **incorrect** code for this rule: ```js const isYes = answer === 1 ? true : false; const isNo = answer === 1 ? false : true; foo(bar ? bar : 1); ``` Examples of **correct** code for this rule: ```js const isYes = answer === 1; const isNo = answer !== 1; foo(bar || 1); ``` ## Configuration This rule accepts a configuration object with the following properties: ### defaultAssignment type: `boolean` default: `true` Whether to allow the default assignment pattern `x ? x : y`. When set to `false`, the rule also flags cases like `x ? x : y` and suggests using the logical OR form `x || y` instead. When `true` (default), such default assignments are allowed and not reported. ## How to use ## Version This rule was added in v0.15.12. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unreachable.md --- ### What it does Disallow unreachable code after `return`, `throw`, `continue`, and `break` statements. This rule can be disabled for TypeScript code if `allowUnreachableCode: false` is configured in the `tsconfig.json`, as the TypeScript compiler enforces this check. ### Why is this bad? Unreachable code after a `return`, `throw`, `continue`, or `break` statement can never be run. ### Examples Examples of **incorrect** code for this rule: ```ts function foo() { return 2; console.log("this will never be executed"); } ``` Examples of **correct** code for this rule: ```ts function foo() { console.log("this will be executed"); return 2; } ``` ## How to use ## Version This rule was added in v0.4.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unreachable-loop.md --- ### What it does Disallow loops whose body allows only one iteration. ### Why is this bad? A loop that always exits before a second iteration is usually accidental and can be replaced with simpler control flow. ### Examples Examples of **incorrect** code for this rule: ```js for (const item of items) { console.log(item); break; } ``` Examples of **correct** code for this rule: ```js for (const item of items) { console.log(item); } ``` ## Configuration ### ignore type: `array` #### ignore\[n] type: `"WhileStatement" | "DoWhileStatement" | "ForStatement" | "ForInStatement" | "ForOfStatement"` ## How to use ## Version This rule was added in vnext. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unsafe-finally.md --- ### What it does Disallow control flow statements in `finally` blocks. ### Why is this bad? JavaScript suspends the control flow statements of `try` and `catch` blocks until the execution of a `finally` block finishes. So, when `return`, `throw`, `break`, or `continue` is used in `finally`, control flow statements inside `try` and `catch` are overwritten. This is possibly unexpected behavior for the developer. ### Examples Examples of **incorrect** code for this rule: ```javascript // We expect this function to return 1; (() => { try { return 1; // 1 is returned but suspended until finally block ends } catch (err) { return 2; } finally { return 3; // 3 is returned before 1, which we did not expect } })(); // > 3 ``` ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unsafe-negation.md --- ### What it does Disallows negating the left operand of relational operators to prevent logical errors caused by misunderstanding operator precedence or accidental use of negation. This rule can be disabled for TypeScript code, as the TypeScript compiler enforces this check. ### Why is this bad? Negating the left operand of relational operators can result in unexpected behavior due to operator precedence, leading to logical errors. For instance, `!a in b` may be interpreted as `(!a) in b` instead of `!(a in b)`, which is not the intended logic. ### Examples Examples of **incorrect** code for this rule: ```javascript if (!key in object) {} if (!obj instanceof Ctor) {} ``` Examples of **correct** code for this rule: ```javascript if (!(key in object)) {} if (!(obj instanceof Ctor)) {} ``` ## Configuration This rule accepts a configuration object with the following properties: ### enforceForOrderingRelations type: `boolean` default: `false` The `enforceForOrderingRelations` option determines whether negation is allowed on the left-hand side of ordering relational operators (<, >, <=, >=). The purpose is to avoid expressions such as `!a < b` (which is equivalent to `(a ? 0 : 1) < b`) when what is really intended is `!(a < b)`. ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unsafe-optional-chaining.md --- ### What it does Disallow use of optional chaining in contexts where the `undefined` value is not allowed. ### Why is this bad? The optional chaining (`?.`) expression can short-circuit with a return value of `undefined`. Therefore, treating an evaluated optional chaining expression as a function, object, number, etc., can cause TypeError or unexpected results. For example: ### Examples Examples of **incorrect** code for this rule: ```javascript var obj = undefined; 1 in obj?.foo; // TypeError with (obj?.foo); // TypeError for (bar of obj?.foo); // TypeError bar instanceof obj?.foo; // TypeError const { bar } = obj?.foo; // TypeError ``` ## Configuration This rule accepts a configuration object with the following properties: ### disallowArithmeticOperators type: `boolean` default: `false` Disallow arithmetic operations on optional chaining expressions. If this is true, this rule warns arithmetic operations on optional chaining expressions, which possibly result in NaN. ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unused-expressions.md --- ### What it does This rule disallows unused expressions. ### Why is this bad? Unused expressions are usually a mistake. They can be a symptom of a bug or a misunderstanding of the code. ### Examples Examples of **incorrect** code for this rule: ```ts Set; 1 as number; window!; ``` Examples of **correct** code for this rule: ```ts const foo = new Set(); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowShortCircuit type: `boolean` default: `false` When set to `true`, allows short circuit evaluations in expressions. ### allowTaggedTemplates type: `boolean` default: `false` When set to `true`, allows tagged template literals in expressions. ### allowTernary type: `boolean` default: `false` When set to `true`, allows ternary operators in expressions. ### enforceForJSX type: `boolean` default: `false` When set to `true`, enforces the rule for unused JSX expressions also. ### ignoreDirectives type: `boolean` default: `false` When set to `true`, allows directive prologues. ## How to use ## Version This rule was added in v0.14.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unused-labels.md --- ### What it does Disallow unused labels. ### Why is this bad? Labels that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. ### Examples Examples of **incorrect** code for this rule: ```javascript OUTER_LOOP: for (const student of students) { if (checkScores(student.scores)) { continue; } doSomething(student); } ``` Examples of **correct** code for this rule: ```javascript for (const student of students) { if (checkScores(student.scores)) { continue; } doSomething(student); } ``` ## How to use ## Version This rule was added in v0.0.3. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unused-private-class-members.md --- ### What it does Disallow unused private class members. ### Why is this bad? Private class members that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such class members take up space in the code and can lead to confusion by readers. ### Examples Examples of **incorrect** code for this rule: ```javascript class A { #unusedMember = 5; } class B { #usedOnlyInWrite = 5; method() { this.#usedOnlyInWrite = 42; } } class C { #usedOnlyToUpdateItself = 5; method() { this.#usedOnlyToUpdateItself++; } } class D { #unusedMethod() {} } class E { get #unusedAccessor() {} set #unusedAccessor(value) {} } ``` Examples of **correct** code for this rule: ```javascript class A { #usedMember = 42; method() { return this.#usedMember; } } class B { #usedMethod() { return 42; } anotherMethod() { return this.#usedMethod(); } } class C { get #usedAccessor() {} set #usedAccessor(value) {} method() { this.#usedAccessor = 42; } } ``` ## How to use ## Version This rule was added in v0.1.1. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-unused-vars.md --- ### What it does Disallows variable declarations, imports, or type declarations that are not used in code. ### Why is this bad? Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers. ```ts // `b` is unused; this indicates a bug. function add(a: number, b: number) { return a; } console.log(add(1, 2)); ``` A variable `foo` is considered to be used if any of the following are true: * It is called (`foo()`) or constructed (`new foo()`) * It is read (`var bar = foo`) * It is passed into a function or constructor as an argument (`doSomething(foo)`) * It is read inside of a function that is passed to another function (`doSomething(function() { foo(); })`) * It is exported (`export const foo = 42`) * It is used as an operand to TypeScript's `typeof` operator (`const bar: typeof foo = 4`) A variable is *not* considered to be used if it is only ever declared (`var foo = 5`) or assigned to (`foo = 7`). #### Types This rule has full support for TypeScript types, interfaces, enums, and namespaces. A type or interface `Foo` is considered to be used if it is used in any of the following ways: * It is used in the definition of another type or interface. * It is used as a type annotation or as part of a function signature. * It is used in a cast or `satisfies` expression. A type or interface is *not* considered to be used if it is only ever used in its own definition, e.g. `type Foo = Array`. Enums and namespaces are treated the same as variables, classes, functions, etc. #### Ignored Files This rule ignores `.d.ts`, `.astro`, `.svelte` and `.vue` files entirely. Variables, classes, interfaces, and types declared in `.d.ts` files are generally used by other files, which are not checked by Oxlint. Since Oxlint does not support parsing template syntax, this rule cannot tell if a variable is used or unused in a Vue / Svelte / Astro file. #### Exported The original ESLint rule recognizes `/* exported variableName */` comments as a way to indicate that a variable is used in another script and should not be considered unused. Since ES modules are now a TC39 standard, Oxlint does not support this feature. ### Examples Examples of **incorrect** code for this rule: ```javascript /* no-unused-vars: "error" */ /* if you have `some_unused_var` defined as a global in .oxlintrc.json */ // It checks variables you have defined as global some_unused_var = 42; var x; // Write-only variables are not considered as used. var y = 10; y = 5; // A read for a modification of itself is not considered as used. var z = 0; z = z + 1; // By default, unused arguments cause warnings. (function (foo) { return 5; })(); // Unused recursive functions also cause warnings. function fact(n) { if (n < 2) return 1; return n * fact(n - 1); } // When a function definition destructures an array, unused entries from // the array also cause warnings. function getY([x, y]) { return y; } ``` ```ts type A = Array; enum Color { Red, Green, Blue, } ``` Examples of **correct** code for this rule: ```js /* no-unused-vars: "error" */ var x = 10; alert(x); // foo is considered used here myFunc( function foo() { // ... }.bind(this), ); (function (foo) { return foo; })(); var myFunc; myFunc = setTimeout(function () { // myFunc is considered used myFunc(); }, 50); // Only the second argument from the destructured array is used. function getY([, y]) { return y; } ``` ```ts export const x = 1; const y = 1; export { y }; type A = Record; type B = T extends Record ? K : never; const x = "foo" as B; console.log(x); ``` Examples of **incorrect** code for `/* exported variableName */` operation: ```js /* exported global_var */ // Not respected, use ES modules instead. var global_var = 42; ``` ## Configuration ### args type: `"after-used" | "all" | "none"` Controls how unused arguments are checked. #### `"after-used"` Unused positional arguments that occur before the last used argument will not be checked, but all named arguments and all positional arguments after the last used argument will be checked. #### `"all"` All named arguments must be used #### `"none"` Do not check arguments ### argsIgnorePattern type: `string` Specifies exceptions to this rule for unused arguments. Arguments whose names match this pattern will be ignored. By default, this pattern is `^_` unless options are configured with an object. In this case it will default to \[`None`]. Note that this behavior deviates from both ESLint and TypeScript-ESLint, which never provide a default pattern. #### Example Examples of **correct** code for this option when the pattern is `^_`: ```javascript function foo(_a, b) { console.log(b); } foo(1, 2); ``` ### caughtErrors type: `"all" | "none"` Used for `catch` block validation. #### `"all"` All named arguments must be used. #### `"none"` Do not check error objects. ### caughtErrorsIgnorePattern type: `string` Specifies exceptions to this rule for errors caught within a `catch` block. Variables declared within a `catch` block whose names match this pattern will be ignored. #### Example Examples of **correct** code when the pattern is `^ignore`: ```javascript try { // ... } catch (ignoreErr) { console.error("Error caught in catch block"); } ``` ### destructuredArrayIgnorePattern type: `string` This option specifies exceptions within destructuring patterns that will not be checked for usage. Variables declared within array destructuring whose names match this pattern will be ignored. By default this pattern is unset. #### Example Examples of **correct** code for this option, when the pattern is `^_`: ```javascript const [a, _b, c] = ["a", "b", "c"]; console.log(a + c); const { x: [_a, foo], } = bar; console.log(foo); let _m, n; foo.forEach((item) => { [_m, n] = item; console.log(n); }); ``` ### fix type: `object` Controls which `no-unused-vars` auto-fixes are emitted. When omitted, both `imports` and `variables` default to `"suggestion"`, preserving the current behavior. NOTE: This option is experimental and may change based on feedback. Fine-grained auto-fix controls for `no-unused-vars`. #### fix.imports type: `"off" | "suggestion" | "fix" | "safe-fix"` Controls auto-fixes for unused imports. ##### `"off"` Disable auto-fixes for this symbol kind. ##### `"suggestion"` Emit suggestion-style fixes (current behavior). ##### `"fix"` Emit fix-style fixes. ##### `"safe-fix"` Like `Fix`, but does not mark them as dangerous. Only applicable for imports, unavailable for variables. #### fix.variables type: `"off" | "suggestion" | "fix" | "safe-fix"` Controls auto-fixes for unused variables (including catch bindings). ##### `"off"` Disable auto-fixes for this symbol kind. ##### `"suggestion"` Emit suggestion-style fixes (current behavior). ##### `"fix"` Emit fix-style fixes. ##### `"safe-fix"` Like `Fix`, but does not mark them as dangerous. Only applicable for imports, unavailable for variables. ### ignoreClassWithStaticInitBlock type: `boolean` default: `false` The `ignoreClassWithStaticInitBlock` option is a boolean. Static initialization blocks allow you to initialize static variables and execute code during the evaluation of a class definition, meaning the static block code is executed without creating a new instance of the class. When set to `true`, this option ignores classes containing static initialization blocks. #### Example Examples of **incorrect** code for the `{ "ignoreClassWithStaticInitBlock": true }` option ```javascript /* no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/ class Foo { static myProperty = "some string"; static mymethod() { return "some string"; } } class Bar { static { let baz; // unused variable } } ``` Examples of **correct** code for the `{ "ignoreClassWithStaticInitBlock": true }` option ```javascript /* no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/ class Foo { static { let bar = "some string"; console.log(bar); } } ``` ### ignoreRestSiblings type: `boolean` default: `false` Using a Rest property it is possible to "omit" properties from an object, but by default the sibling properties are marked as "unused". With this option enabled the rest property's siblings are ignored. #### Example Examples of **correct** code when this option is set to `true`: ```js // 'foo' and 'bar' were ignored because they have a rest property sibling. var { foo, ...coords } = data; var bar; ({ bar, ...coords } = data); ``` ### ignoreUsingDeclarations type: `boolean` default: `false` When set to `true`, the rule will ignore variables declared with `using` or `await using` declarations, even if they are unused. This is useful when working with resources that need to be disposed via the explicit resource management proposal, where the primary purpose is the disposal side effect rather than using the resource. #### Example Examples of **correct** code for the `{ "ignoreUsingDeclarations": true }` option: ```javascript /* no-unused-vars: ["error", { "ignoreUsingDeclarations": true }]*/ using resource = getResource(); await using anotherResource = getAnotherResource(); ``` ### reportUsedIgnorePattern type: `boolean` default: `false` The `reportUsedIgnorePattern` option is a boolean. Using this option will report variables that match any of the valid ignore pattern options (`varsIgnorePattern`, `argsIgnorePattern`, `caughtErrorsIgnorePattern`, or `destructuredArrayIgnorePattern`) if they have been used. #### Example Examples of **incorrect** code for the `{ "reportUsedIgnorePattern": true }` option: ```javascript /* no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/ var firstVarIgnored = 1; var secondVar = 2; console.log(firstVarIgnored, secondVar); ``` Examples of **correct** code for the `{ "reportUsedIgnorePattern": true }` option: ```javascript /* no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/ var firstVar = 1; var secondVar = 2; console.log(firstVar, secondVar); ``` ### reportVarsOnlyUsedAsTypes type: `boolean` default: `false` The `reportVarsOnlyUsedAsTypes` option is a boolean. If `true`, the rule will also report variables that are only used as types. #### Examples Examples of **incorrect** code for the `{ "reportVarsOnlyUsedAsTypes": true }` option: ```javascript /* no-unused-vars: ["error", { "reportVarsOnlyUsedAsTypes": true }] */ const myNumber: number = 4; export type MyNumber = typeof myNumber ``` Examples of **correct** code for the `{ "reportVarsOnlyUsedAsTypes": true }` option: ```javascript export type MyNumber = number; ``` Note: even with `{ "reportVarsOnlyUsedAsTypes": false }`, cases where the value is only used a type within itself will still be reported: ```javascript function foo(): typeof foo {} ``` ### vars type: `"all" | "local"` Controls how usage of a variable in the global scope is checked. #### `"all"` All variables are checked for usage, including those in the global scope. #### `"local"` Checks only that locally-declared variables are used but will allow global variables to be unused. ### varsIgnorePattern type: `string` Specifies exceptions to this rule for unused variables. Variables whose names match this pattern will be ignored. By default, this pattern is `^_` unless options are configured with an object. In this case it will default to \[`None`]. Note that this behavior deviates from both ESLint and TypeScript-ESLint, which never provide a default pattern. #### Example Examples of **correct** code for this option when the pattern is `^_`: ```javascript var _a = 10; var b = 10; console.log(b); ``` ## How to use ## Version This rule was added in v0.7.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-use-before-define.md --- ### What it does Disallows using variables before they are defined. ### Why is this bad? Referencing identifiers before their declarations can hide bugs and make code order-dependent and difficult to reason about. ### Examples Examples of **incorrect** code for this rule: ```ts new A(); var A = class {}; ``` Examples of **correct** code for this rule: ```ts var A = class {}; new A(); ``` ## Configuration ### allowNamedExports type: `boolean` default: `false` Allow named exports that appear before declaration. ### classes type: `boolean` default: `true` Check class declarations. ### enums type: `boolean` default: `true` Check enum declarations. ### functions type: `boolean` default: `true` Check function declarations. ### ignoreTypeReferences type: `boolean` default: `true` Ignore usages that are type-only references. ### typedefs type: `boolean` default: `true` Check type aliases, interfaces, and type parameters. ### variables type: `boolean` default: `true` Check variable declarations. ## How to use ## Version This rule was added in v1.49.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-assignment.md --- ### What it does Flags assignments where the newly assigned value is never read afterward (a "dead store"). This helps catch wasted work or accidental mistakes. ### Why is this bad? Dead stores add noise and can hide real bugs (e.g., you meant to use that value or wrote to the wrong variable). Removing them improves clarity and performance. ### Examples Examples of **incorrect** code for this rule: ```js function fn1() { let v = "used"; doSomething(v); v = "unused"; // assigned but never read } function fn2() { let v = "used"; if (condition) { v = "unused"; // early return; this write is never observed return; } doSomething(v); } function fn3() { let v = "used"; if (condition) { doSomething(v); } else { v = "unused"; // value not used later in this branch } } ``` Examples of **correct** code for this rule: ```js function fn1() { let v = "used"; doSomething(v); v = "used-2"; doSomething(v); // the reassigned value is read } function fn2() { let v = "used"; if (condition) { v = "used-2"; doSomething(v); // reassignment is observed before returning return; } doSomething(v); } function fn3() { let v = "used"; for (let i = 0; i < 10; i++) { doSomething(v); v = "used in next iteration"; // used on the next loop pass } } ``` ## How to use ## Version This rule was added in v1.59.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-backreference.md --- ### What it does Disallows backreferences in regular expressions that will always be ignored because the capture group they refer to has not matched and cannot match at the time the backreference is evaluated. ### Why is this bad? Useless backreferences can lead to confusing or misleading regular expressions. They may give the impression that a group’s value is being reused, but due to the structure of the pattern (e.g., order of evaluation, disjunctions, or negative lookarounds), the group has not matched anything — so the reference always resolves to an empty string. This is almost always a mistake and makes patterns harder to understand and maintain. ### Examples Examples of **incorrect** code for this rule: ```js /\1(a)/; // backreference appears before group /(a|\1b)/; // group and reference are in different alternatives /(?<=\1(a))b/; // backreference used before group in lookbehind /\1(?!(a))/; // group is inside negative lookahead /(a\1)/; // backreference is inside its own group ``` Examples of **correct** code for this rule: ```js /(a)\1/; // valid — backreference follows completed group /(?a)\k/; // named group used properly /(?:a|(b))\1/; // backreference only used when group matches ``` ## How to use ## Version This rule was added in v0.16.10. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-call.md --- ### What it does Disallow unnecessary calls to `.call()` and `.apply()` ### Why is this bad? `Function.prototype.call()` and `Function.prototype.apply()` are slower than the normal function invocation. This rule compares code statically to check whether or not thisArg is changed. So if the code about thisArg is a dynamic expression, this rule cannot judge correctly. ### Examples Examples of **incorrect** code for this rule: ```js // These are the same as `foo(1, 2, 3);` foo.call(undefined, 1, 2, 3); foo.apply(undefined, [1, 2, 3]); foo.call(null, 1, 2, 3); foo.apply(null, [1, 2, 3]); // These are the same as `obj.foo(1, 2, 3);` obj.foo.call(obj, 1, 2, 3); obj.foo.apply(obj, [1, 2, 3]); ``` Examples of **correct** code for this rule: ```js // The `this` binding is different. foo.call(obj, 1, 2, 3); foo.apply(obj, [1, 2, 3]); obj.foo.call(null, 1, 2, 3); obj.foo.apply(null, [1, 2, 3]); obj.foo.call(otherObj, 1, 2, 3); obj.foo.apply(otherObj, [1, 2, 3]); // The argument list is variadic. // Those are warned by the `prefer-spread` rule. foo.apply(undefined, args); foo.apply(null, args); obj.foo.apply(obj, args); ``` ## How to use ## Version This rule was added in v0.15.9. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-catch.md --- ### What it does Disallow unnecessary catch clauses. ### Why is this bad? A catch clause that only rethrows the original error is redundant, and has no effect on the runtime behavior of the program. These redundant clauses can be a source of confusion and code bloat, so it’s better to disallow these unnecessary catch clauses. ### Examples Examples of **incorrect** code for this rule: ```javascript try { doSomethingThatMightThrow(); } catch (e) { throw e; } ``` Examples of **correct** code for this rule: ```javascript doSomethingThatMightThrow(); ``` ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-computed-key.md --- ### What it does Disallow unnecessary computed property keys in objects and classes. ### Why is this bad? It’s unnecessary to use computed properties with literals such as: ```js const foo = { ["a"]: "b" }; ``` The code can be rewritten as: ```js const foo = { a: "b" }; ``` ### Examples Examples of **incorrect** code for this rule: ```js const a = { ["0"]: 0 }; const b = { ["0+1,234"]: 0 }; const c = { [0]: 0 }; const e = { ["x"]() {} }; class Foo { ["foo"] = "bar"; [0]() {} static ["foo"] = "bar"; get ["b"]() {} set ["c"](value) {} } ``` Examples of **correct** code for this rule: ```js const a = { a: 0 }; const b = { 0: 0 }; const c = { x() {} }; const e = { "0+1,234": 0 }; class Foo { foo = "bar"; 0() {} a() {} static foo = "bar"; } ``` Examples of additional **correct** code for this rule: ```js const c = { __proto__: foo, // defines object's prototype ["__proto__"]: bar, // defines a property named "__proto__" }; class Foo { ["constructor"]; // instance field named "constructor" constructor() {} // the constructor of this class static ["constructor"]; // static field named "constructor" static ["prototype"]; // runtime error, it would be a parsing error without `[]` } ``` ## Configuration This rule accepts a configuration object with the following properties: ### enforceForClassMembers type: `boolean` default: `true` The `enforceForClassMembers` option controls whether the rule applies to class members (methods and properties). Examples of **correct** code for this rule with the `{ "enforceForClassMembers": false }` option: ```js class SomeClass { ["foo"] = "bar"; [42] = "baz"; get ["b"]() {} set ["c"](value) {} static ["foo"] = "bar"; } ``` ## How to use ## Version This rule was added in v1.16.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-concat.md --- ### What it does Disallow unnecessary concatenation of literals or template literals. ### Why is this bad? It’s unnecessary to concatenate two strings together when they could be combined into a single literal. ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = "a" + "b"; ``` ```javascript var foo = "a" + "b" + "c"; ``` Examples of **correct** code for this rule: ```javascript var foo = "a" + bar; // When the string concatenation is multiline var foo = "a" + "b" + "c"; ``` ## How to use ## Version This rule was added in v0.4.2. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-constructor.md --- ### What it does Disallow constructors that can be safely removed without changing how the class works. ### Why is this bad? ES2015 provides a default class constructor if one is not specified. As such, it is unnecessary to provide an empty constructor or one that simply delegates into its parent class. ::: warning Caveat: This lint rule will report on constructors whose sole purpose is to change the visibility of a parent constructor, or to expose parameter properties with modifiers. This is because the rule does not have type information to determine if the parent constructor is `public`, `protected`, or `private`. ::: ### Examples Examples of **incorrect** code for this rule: ```javascript class A { constructor() {} } class B extends A { constructor(...args) { super(...args); } } ``` Examples of **correct** code for this rule: ```javascript class A {} class B { constructor() { doSomething(); } } class C extends A { constructor() { super("foo"); } } class D extends A { constructor() { super(); doSomething(); } } ``` ## How to use ## Version This rule was added in v0.4.4. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-escape.md --- ### What it does Disallow unnecessary escape characters. ### Why is this bad? Escaping characters unnecessarily has no effect on the behavior of strings or regexes, and can make code harder to read and understand by adding unnecessary complexity. This applies to string literals, template literals, and regular expressions. ### Examples Examples of **incorrect** code for this rule: ```javascript "\'"; '\"'; "\#"; "\e"; `\"`; `\"${foo}\"`; `\#{foo}`; /\!/; /\@/; /[\[]/; /[a-z\-]/; ``` Examples of **correct** code for this rule: ```javascript "\""; '\''; "\x12"; "\u00a9"; "\371"; "xs\u2111"; `\``; `\${${foo}}`; `$\{${foo}}`; /\\/g; /\t/g; /\w\$\*\^\./; /[[]/; /[\]]/; /[a-z-]/; ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowRegexCharacters type: `string[]` default: `[]` An array of characters that are allowed to be escaped unnecessarily in regexes. For example, setting this to `["#"]` allows `\#` in regexes. Each string in this array must be a single character. ## How to use ## Version This rule was added in v0.0.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-rename.md --- ### What it does Disallow renaming import, export, and destructured assignments to the same name. ### Why is this bad? It is unnecessary to rename a variable to the same name. ### Examples Examples of **incorrect** code for this rule: ```javascript import { foo as foo } from "foo"; const { bar: bar } = obj; export { baz as baz }; ``` Examples of **correct** code for this rule: ```javascript import { foo } from "foo"; const { bar: renamed } = obj; export { baz }; ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignoreDestructuring type: `boolean` default: `false` When set to `true`, allows using the same name in destructurings. ### ignoreExport type: `boolean` default: `false` When set to `true`, allows renaming exports to the same name. ### ignoreImport type: `boolean` default: `false` When set to `true`, allows renaming imports to the same name. ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-useless-return.md --- ### What it does Disallows redundant return statements. ### Why is this bad? A `return;` statement with nothing after it is redundant, and has no effect on the runtime behavior of a function. This can be confusing, so it's better to disallow these redundant statements. ### Examples Examples of **incorrect** code for this rule: ```js function foo() { return; } function bar() { doSomething(); return; } function baz() { if (condition) { doSomething(); return; } } ``` Examples of **correct** code for this rule: ```js function foo() { return 5; } function bar() { if (condition) { return; } doSomething(); } function baz() { return doSomething(); } ``` ## How to use ## Version This rule was added in v1.32.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-var.md --- ### What it does ECMAScript 2015 allows programmers to create variables with block scope instead of function scope using the `let` and `const` keywords. Block scope is common in many other programming languages and helps programmers avoid mistakes. ### Why is this bad? Using `var` in an ES2015 environment triggers this error ### Examples Examples of **incorrect** code for this rule: ```javascript var x = "y"; var CONFIG = {}; ``` Examples of **correct** code for this rule: ```javascript let x = "y"; const CONFIG = {}; ``` ## How to use ## Version This rule was added in v0.1.1. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-void.md --- ### What it does Disallows the use of the `void` operator. ### Why is this bad? The `void` operator is often used to get `undefined`, but this is unnecessary because `undefined` can be used directly instead. ### Examples Examples of **incorrect** code for this rule: ```ts void 0; var foo = void 0; ``` Examples of **correct** code for this rule: ```ts "var foo = bar()"; "foo.void()"; "foo.void = bar"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowAsStatement type: `boolean` default: `false` If set to `true`, using `void` as a standalone statement is allowed. ## How to use ## Version This rule was added in v0.2.5. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-warning-comments.md --- ### What it does Disallows warning comments such as TODO, FIXME, XXX in code. ### Why is this bad? Developers often add comments like TODO or FIXME to mark incomplete work or areas that need attention. While useful during development, these comments can indicate unfinished code that shouldn't be shipped to production. This rule helps catch such comments before they make it into production code. ### Examples Examples of **incorrect** code for this rule: ```javascript // TODO: implement this feature function doSomething() {} // FIXME: this is broken const x = 1; /* XXX: hack */ let y = 2; ``` Examples of **correct** code for this rule: ```javascript // This is a regular comment function doSomething() {} // Note: This explains something const x = 1; ``` ## Configuration This rule accepts a configuration object with the following properties: ### decoration type: `string[]` default: `[]` An array of characters to ignore at the start of comments when `location` is `"start"`. Useful for ignoring common comment decorations like `*` in JSDoc-style comments. ### location type: `"start" | "anywhere"` default: `"start"` Where to check for the terms. #### `"start"` Terms must appear at the start of the comment, after any decoration. #### `"anywhere"` Terms can appear anywhere in the comment. ### terms type: `string[]` default: `["todo", "fixme", "xxx"]` An array of terms to match. The matching is case-insensitive. ## How to use ## Version This rule was added in v1.24.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-with.md --- ### What it does Disallow [`with`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/with) statements. ### Why is this bad? The with statement is potentially problematic because it adds members of an object to the current scope, making it impossible to tell what a variable inside the block actually refers to. It is generally considered a bad practice and is forbidden in strict mode. This rule is not necessary in TypeScript code if `alwaysStrict` is enabled. ### Examples Examples of **incorrect** code for this rule: ```javascript with (point) { r = Math.sqrt(x * x + y * y); // is r a member of point? } ``` ## How to use ## Version This rule was added in v0.2.14. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/object-shorthand.md --- ### What it does Require or disallow method and property shorthand syntax for object literals ### Why is this bad? Stylistic preference ### Example Here are a few common examples using the ES5 syntax: ```javascript var properties = { x: x, y: y, z: z }; var methods = { a: function () {}, b: function () {} }; ``` Now here are ES6 equivalents: ```javascript var properties = { x, y, z }; var methods = { a() {}, b() {} }; ``` ## Configuration ### The 1st option type: `"always" | "methods" | "properties" | "consistent" | "consistent-as-needed" | "never"` ### The 2nd option This option is an object with the following properties: #### avoidExplicitReturnArrows type: `boolean` default: `false` #### avoidQuotes type: `boolean` default: `false` #### ignoreConstructors type: `boolean` default: `false` #### methodsIgnorePattern type: `string` ## How to use ## Version This rule was added in v1.59.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/one-var.md --- ### What it does Enforces variables to be declared either together or separately. ### Why is this bad? Consistent declaration grouping makes variable lifetimes and initialization patterns easier to scan. This rule can require one declaration per scope, one declarator per statement, or grouping only consecutive declarations. ### Examples Examples of **incorrect** code for this rule: ```js var foo = 1; var bar = 2; ``` Examples of **correct** code for this rule: ```js var foo = 1, bar = 2; ``` ## Configuration Enforces consistent grouping of variable declarations. type: `object` ## How to use ## Version This rule was added in vnext. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/operator-assignment.md --- ### What it does This rule requires or disallows assignment operator shorthand where possible. It encourages the use of shorthand assignment operators like `+=`, `-=`, `*=`, `/=`, etc. to make the code more concise and readable. ### Why is this bad? JavaScript provides shorthand operators that combine variable assignment and simple mathematical operations. Failing to use these shorthand operators can lead to unnecessarily verbose code and can be seen as a missed opportunity for clarity and simplicity. ### Examples Examples of **incorrect** code for this rule with the default `always` option: ```js x = x + y; x = y * x; x[0] = x[0] / y; x.y = x.y << z; ``` Examples of **correct** code for this rule with the default `always` option: ```js x = y; x += y; x = y * z; x = x * y * z; x[0] /= y; x[foo()] = x[foo()] % 2; x = y + x; // `+` is not always commutative (e.g. x = "abc") ``` Examples of **incorrect** code for this rule with the `never` option: ```js x *= y; x ^= (y + z) / foo(); ``` Examples of **correct** code for this rule with the `never` option: ```js x = x + y; x.y = x.y / a.b; ``` ## Configuration This rule accepts one of the following string values: type: `"always" | "never"` ## How to use ## Version This rule was added in v0.15.13. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-arrow-callback.md --- ### What it does Requires using arrow functions for callbacks. ### Why is this bad? Arrow functions are generally better suited for callbacks because they: * inherit `this` from the surrounding scope, avoiding a common source of bugs; * are shorter and easier to read; * cannot be used as constructors, which is desirable for callbacks. ### Examples Examples of **incorrect** code for this rule: ```js foo(function (a) { return a; }); foo( function () { return this.a; }.bind(this), ); ``` Examples of **correct** code for this rule: ```js foo((a) => a); foo(function* () { yield; }); foo(function () { this; }); foo(function bar() { bar(); }); ``` ## Configuration ### allowNamedFunctions type: `boolean` default: `false` If this option is set to `true`, named function expressions are allowed. ### allowUnboundThis type: `boolean` default: `true` If this option is set to `false`, function expressions that reference `this` are reported even when they are not bound to a `this` value. ## How to use ## Version This rule was added in v1.65.0. ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-const.md --- ### What it does Requires `const` declarations for variables that are never reassigned after their initial declaration. #### Ignored Files This rule ignores `.svelte` and `.vue` files entirely. Oxlint only parses the ` ``` Trailing ignore comments are also supported: ```js const a = 42; // oxfmt-ignore ``` For other files and non-JS parts of Vue files (e.g., `