--- url: /sponsor.md --- # 🌟 Become an Oxc Sponsor ## 🤝 How to Sponsor You may sponsor through [GitHub Sponsors](https://github.com/sponsors/Boshen) or [OpenCollective](https://opencollective.com/oxc). ## 💚 Why sponsor? Sponsorship helps us keep improving the JavaScript and Rust ecosystems while preventing burnout from maintaining fast and evolving tools in our personal time. If our work has improved your development experience, your CI pipelines, your build times, or your learning in any way, please consider sponsoring. It helps more than you might think, and it truly 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 "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 For transformations, use the mutable visitor: ```rust use oxc_ast::visit::{VisitMut, walk_mut}; struct MyTransformer; impl<'a> VisitMut<'a> for MyTransformer { fn visit_binary_expression(&mut self, expr: &mut BinaryExpression<'a>) { // Transform the expression if expr.operator == BinaryOperator::Addition { // Modify the AST node } walk_mut::walk_binary_expression_mut(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/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), and [eslint-plugin-react-refresh](https://github.com/ArnaudBarre/eslint-plugin-react-refresh) | | `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). ## 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/transformer/plugins.md --- # Built-in Plugins Oxc transformer includes built-in support for popular transformation plugins to improve developer experience and build performance. ## 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/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) ## 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`, or `oxlint.config.ts` 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`* — Deny 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`, `github`, `gitlab`, `json`, `junit`, `stylish`, `unix` ## 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/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 current directory and walking up the tree: * `.oxfmtrc.json` * `.oxfmtrc.jsonc` * `oxfmt.config.ts` You can also pass a config explicitly with `-c`. 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: ```json [.oxfmtrc.json] { "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. `.oxfmtrc.json(c)` root options 3. `.oxfmtrc.json(c)` `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: ```json [.oxfmtrc.json] { "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` or `oxlint.config.ts` 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 either `.oxlintrc.json` or `oxlint.config.ts` in a directory, but not both. 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`. ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ categories: { correctness: "warn", }, rules: { "eslint/no-unused-vars": "error", }, }); ``` Notes: * The file must be named `oxlint.config.ts` (including when passed via `--config`). * 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. ::: 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], }); ``` ::: ## 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. * 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). * Default: `false` ## bracketSpacing type: `boolean` Print spaces between brackets in object literals. * 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. NOTE: XXX-in-JS support is incomplete. * Default: `"auto"` ## endOfLine type: `"lf" | "crlf" | "cr"` Which end of line characters to apply. NOTE: `"auto"` is not supported. * Default: `"lf"` * Overrides `.editorconfig.end_of_line` ## htmlWhitespaceSensitivity type: `"css" | "strict" | "ignore"` Specify the global whitespace sensitivity for HTML, Vue, Angular, and Handlebars. * Default: `"css"` ## ignorePatterns type: `string[]` Ignore files matching these glob patterns. Patterns are based on the location of the Oxfmt configuration file. * Default: `[]` ## insertFinalNewline type: `boolean` Whether to insert a final newline at the end of the file. * 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. * 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: `string` 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: `string` 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. * 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. * 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. #### overrides\[n].files type: `string[]` Glob patterns to match files for this override. All patterns are relative to the Oxfmt configuration file. #### overrides\[n].options type: `object` ##### overrides\[n].options.arrowParens type: `"always" | "avoid"` Include parentheses around a sole arrow function parameter. * 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). * Default: `false` ##### overrides\[n].options.bracketSpacing type: `boolean` Print spaces between brackets in object literals. * 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. NOTE: XXX-in-JS support is incomplete. * Default: `"auto"` ##### overrides\[n].options.endOfLine type: `"lf" | "crlf" | "cr"` Which end of line characters to apply. NOTE: `"auto"` is not supported. * 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. * Default: `"css"` ##### overrides\[n].options.insertFinalNewline type: `boolean` Whether to insert a final newline at the end of the file. * 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. * 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: `string` 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: `string` 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. * 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. * 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. * 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". * Default: `"preserve"` ##### overrides\[n].options.quoteProps type: `"as-needed" | "consistent" | "preserve"` Change when properties in objects are quoted. * Default: `"as-needed"` ##### overrides\[n].options.semi type: `boolean` Print semicolons at the ends of statements. * Default: `true` ##### overrides\[n].options.singleAttributePerLine type: `boolean` Enforce single attribute per line in HTML, Vue, and JSX. * Default: `false` ##### overrides\[n].options.singleQuote type: `boolean` Use single quotes instead of double quotes. For JSX, you can set the `jsxSingleQuote` option. * 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. * 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: `string[]` Modifiers to match the import characteristics. All specified modifiers must be present (AND logic). Possible values: `"side_effect"`, `"type"`, `"value"`, `"default"`, `"wildcard"`, `"named"` \######## overrides\[n].options.sortImports.customGroups\[n].selector type: `string` Selector to match the import kind. Possible values: `"type"`, `"side_effect_style"`, `"side_effect"`, `"style"`, `"index"`, `"sibling"`, `"parent"`, `"subpath"`, `"internal"`, `"builtin"`, `"external"`, `"import"` ###### 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. * 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. * 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.tabWidth type: `integer` Specify the number of spaces per indentation-level. * Default: `2` * Overrides `.editorconfig.indent_size` (falls back to `.editorconfig.tab_width`) ##### overrides\[n].options.trailingComma type: `"all" | "es5" | "none"` Print trailing commas wherever possible in multi-line comma-separated syntactic structures. A single-line array, for example, never gets trailing commas. * Default: `"all"` ##### overrides\[n].options.useTabs type: `boolean` Indent lines with tabs instead of spaces. * Default: `false` * Overrides `.editorconfig.indent_style` ##### overrides\[n].options.vueIndentScriptAndStyle type: `boolean` Whether or not to indent the 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 ## 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 ## 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. ### Options First option: * Type: `string` * Enum: `"always"`, `"as-needed"`, `"never"` * Default: `"as-needed"` Possible values: * `never` enforces no braces around the function body (constrains arrow functions to the role of returning an expression) * `always` enforces braces around the function body * `as-needed` enforces no braces where they can be omitted (default) Second option: * Type: `object` * Properties: * `requireReturnForObjectLiteral`: `boolean` (default: `false`) - requires braces and an explicit return for object literals. Note: This option only applies when the first option is `"as-needed"`. Example configuration: ```json { "arrow-body-style": ["error", "as-needed", { "requireReturnForObjectLiteral": true }] } ``` ### 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"` ### The 2nd option This option is an object with the following properties: #### requireReturnForObjectLiteral type: `boolean` default: `false` ## How to use ## 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 ## 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: #### block type: `object` Configuration options specific to block comments. ##### block.ignoreConsecutiveComments type: `boolean` If true, consecutive comments will be ignored after the first comment. ##### block.ignoreInlineComments type: `boolean` If true, inline comments (comments in the middle of code) will be ignored. ##### block.ignorePattern type: `string` A regex pattern. Comments that match the pattern will not cause violations. #### 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. #### line type: `object` Configuration options specific to line comments. ##### line.ignoreConsecutiveComments type: `boolean` If true, consecutive comments will be ignored after the first comment. ##### line.ignoreInlineComments type: `boolean` If true, inline comments (comments in the middle of code) will be ignored. ##### line.ignorePattern type: `string` A regex pattern. Comments that match the pattern will not cause violations. ## How to use ## 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. #### `"all"` Ignores all classes that implement interfaces #### `"public-fields"` Only ignores public fields in classes that implement interfaces ### ignoreOverrideMethods type: `boolean` default: `false` Whether to ignore methods that are overridden. ## How to use ## 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 This rule accepts a configuration object with the following properties: ### max type: `integer` default: `20` Maximum amount of cyclomatic complexity ### variant type: `"classic" | "modified"` default: `"classic"` 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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"` ##### `"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 ## 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 ## 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 ## 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` ##### overrides.namedExports type: `"ignore" | "expression" | "declaration"` default: `null` ## How to use ## 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 ## 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 ## 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/id-length.md --- ### What it does This rule enforces 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: `18446744073709551615` 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. #### `"always"` Property names are checked just like other identifiers #### `"never"` Property names are not checked for length. ## How to use ## 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"` #### `"always"` Requires that variables be initialized on declaration. This is the default behavior. #### `"never"` Disallows initialization during declaration. ### 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 ## 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 This rule accepts a configuration object with the following properties: ### 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 ## 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 This rule accepts a configuration object with the following properties: ### max type: `integer` default: `4` The `max` enforces a maximum depth that blocks can be nested ## How to use ## 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 This rule accepts a configuration object with the following properties: ### 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 ## 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 This rule accepts a configuration object with the following properties: ### 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 ## 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 This rule accepts a configuration object with the following properties: ### max type: `integer` default: `10` The `max` enforces a maximum depth that callbacks can be nested. ## How to use ## 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 This rule accepts a configuration object with the following properties: ### 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 ## 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 This rule accepts a configuration object with the following properties: ### 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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. 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; ``` ## How to use ## 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: `"all" | "allExceptWhileTrue" | "none"` default: `"allExceptWhileTrue"` Configuration option to specify whether to check for constant conditions in loops. * `"all"` or `true` disallows constant expressions in loops * `"allExceptWhileTrue"` disallows constant expressions in loops except while loops with expression `true` * `"none"` or `false` allows constant expressions in loops ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-constructor-return.md --- ### What it does Disallow returning value from 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 ## 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 ## 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"); ``` ## How to use ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 = []}) {} ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-empty-static-block.md --- ### What it does Disallows the usages of 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-implicit-coercion.md --- ### What it does Disallows shorthand type conversions using operators like `!!`, `+`, `""+ `, etc. ### 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 ## 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 ## 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 ## 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"` ##### `"allow"` Allow function declarations in nested blocks in strict mode (ES6+ behavior). ##### `"disallow"` Disallow function declarations in nested blocks regardless of strict mode. ## How to use ## 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 ## 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 } ``` ## How to use ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-loss-of-precision.md --- ### What it does Disallow precision loss of number literal. ### 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 ## 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] ### 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 ## 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 ## 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 ## 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 ## 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-nested-ternary.md --- ### What it does Disallows nested ternary expressions to improve code readability and maintainability. ### Why is this bad? Nested ternary expressions make code harder to read and understand. They can lead to complex, difficult-to-debug logic. ### 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 ## 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-new-func.md --- ### What it does The rule 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 ## 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 ## 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-nonoctal-decimal-escape.md --- ### What it does This rule disallows \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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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: ### hasDefaultRestrictedNamedExport type: `boolean` ### 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 ## References --- --- url: /docs/guide/usage/linter/rules/eslint/no-restricted-globals.md --- ### What it does This rule allows you to specify global variable names that you don't want to use 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. } ``` ## Configuration This rule accepts a configuration object with the following properties: ### restrictedGlobals type: `Record` default: `{}` Objects in the format `{ "name": "event", "message": "Use local parameter instead." }`, which define what globals are restricted from use. ## How to use ## 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 only, not dynamic ones. ### 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 ## 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 ## 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 ## 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 ## 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 ## 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. ### Options * `allowInParentheses` (default: `true`): If set to `false`, disallows the comma operator even when wrapped in parentheses. ### 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. Default is `true`. ## How to use ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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. ## How to use ## 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 ## 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 ## 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 This rule accepts a configuration object with the following properties: ### args type: `"after-used" | "all" | "none"` default: `"after-used"` 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 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 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 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` default: `{"imports":"suggestion", "variables":"suggestion"}` Fine-grained auto-fix controls for `no-unused-vars`. #### fix.imports type: `"off" | "suggestion" | "fix" | "safe-fix"` ##### `"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"` ##### `"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"` default: `"all"` 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 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 ## 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 This rule accepts a configuration object with the following properties: ### 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 ## 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 /* eslint no-useless-assignment: "error" */ 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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 ## 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; ``` ### Options This rule has an options object with the following defaults: ```json { "terms": ["todo", "fixme", "xxx"], "location": "start", "decoration": [] } ``` #### `terms` An array of terms to match. The matching is case-insensitive. #### `location` Where to check for the terms: * `"start"` (default): Terms must appear at the start of the comment (after any decoration) * `"anywhere"`: Terms can appear anywhere in the comment #### `decoration` 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. ## How to use ## 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 ## 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 ## 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: ### `"always"` Requires assignment operator shorthand where possible. ### `"never"` Disallows assignment operator shorthand. ## How to use ## 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. ### Why is this bad? If a variable is never reassigned, using the `const` declaration is better. `const` declaration tells readers, "this variable is never reassigned," reducing cognitive load and improving maintainability. ### Examples Examples of **incorrect** code for this rule: ```js let a = 3; console.log(a); let b; b = 0; console.log(b); for (let i in [1, 2, 3]) { console.log(i); } ``` Examples of **correct** code for this rule: ```js const a = 0; let a; a = 0; a = 1; let a; if (true) { a = 0; } for (const i in [1, 2, 3]) { console.log(i); } ``` ## Configuration ### destructuring type: `"any" | "all"` #### `"any"` Warn if any of the variables in a destructuring assignment should be `const`. #### `"all"` Only warn if all variables in a destructuring assignment should be `const`. Otherwise, ignore them. ### ignoreReadBeforeAssign type: `boolean` default: `false` If `true`, the rule will not report variables that are read before their initial assignment. This is mainly useful for preventing conflicts with the `typescript/no-use-before-define` rule. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-destructuring.md --- ### What it does Require destructuring from arrays and/or objects. ### Why is this bad? With JavaScript ES2015, a new syntax was added for creating variables from an array index or object property, called destructuring. This rule enforces usage of destructuring instead of accessing a property through a member expression. ### Examples Examples of **incorrect** code for this rule: ```js // With `array` enabled const foo = array[0]; bar.baz = array[0]; // With `object` enabled const qux = object.qux; const quux = object["quux"]; ``` Examples of **correct** code for this rule: ```js // With `array` enabled const [foo] = array; const arr = array[someIndex]; [bar.baz] = array; // With `object` enabled const { baz } = object; const obj = object.bar; ``` ## Configuration This rule accepts a configuration object with the following properties: ### AssignmentExpression type: `object` default: `{"array":true, "object":true}` Configuration for destructuring in assignment expressions, configured for arrays and objects independently. #### AssignmentExpression.array type: `boolean` default: `true` #### AssignmentExpression.object type: `boolean` default: `true` ### VariableDeclarator type: `object` default: `{"array":true, "object":true}` Configuration for destructuring in variable declarations, configured for arrays and objects independently. #### VariableDeclarator.array type: `boolean` default: `true` #### VariableDeclarator.object type: `boolean` default: `true` ### enforceForRenamedProperties type: `boolean` default: `false` Determines whether the object destructuring rule applies to renamed variables. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-exponentiation-operator.md --- ### What it does Disallow the use of `Math.pow` in favor of the `**` operator. ### Why is this bad? Introduced in ES2016, the infix exponentiation operator `**` is an alternative for the standard `Math.pow` function. Infix notation is considered to be more readable and thus more preferable than the function notation. ### Examples Examples of **incorrect** code for this rule: ```javascript Math.pow(a, b); ``` Examples of **correct** code for this rule: ```javascript a ** b; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-numeric-literals.md --- ### What it does Disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals. ### Why is this bad? The `parseInt()` and `Number.parseInt()` functions can be used to turn binary, octal, and hexadecimal strings into integers. As binary, octal, and hexadecimal literals are supported in ES2015, this rule encourages use of those numeric literals instead of `parseInt()` or `Number.parseInt()`. ### Examples Examples of **incorrect** code for this rule: ```javascript parseInt("111110111", 2) === 503; parseInt(`111110111`, 2) === 503; parseInt("767", 8) === 503; parseInt("1F7", 16) === 503; Number.parseInt("111110111", 2) === 503; Number.parseInt("767", 8) === 503; Number.parseInt("1F7", 16) === 503; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-object-has-own.md --- ### What it does Disallow use of `Object.prototype.hasOwnProperty.call()` and prefer use of `Object.hasOwn()` ### Why is this bad? It is very common to write code like: ```javascript if (Object.prototype.hasOwnProperty.call(object, "foo")) { console.log("has property foo"); } ``` This is a common practice because methods on `Object.prototype` can sometimes be unavailable or redefined (see the no-prototype-builtins rule). Introduced in ES2022, `Object.hasOwn()` is a shorter alternative to `Object.prototype.hasOwnProperty.call()`: ```javascript if (Object.hasOwn(object, "foo")) { console.log("has property foo"); } ``` ### Examples Examples of **incorrect** code for this rule: ```js Object.prototype.hasOwnProperty.call(obj, "a"); Object.hasOwnProperty.call(obj, "a"); ({}).hasOwnProperty.call(obj, "a"); const hasProperty = Object.prototype.hasOwnProperty.call(object, property); ``` Examples of **correct** code for this rule: ```js Object.hasOwn(obj, "a"); const hasProperty = Object.hasOwn(object, property); ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-object-spread.md --- ### What it does Disallow using `Object.assign` with an object literal as the first argument and prefer the use of object spread instead. ### Why is this bad? When `Object.assign` is called using an object literal as the first argument, this rule requires using the object spread syntax instead. This rule also warns on cases where an `Object.assign` call is made using a single argument that is an object literal, in this case, the `Object.assign` call is not needed. ### Examples Examples of **incorrect** code for this rule: ```js Object.assign({}, foo); Object.assign({}, { foo: "bar" }); Object.assign({ foo: "bar" }, baz); Object.assign({}, baz, { foo: "bar" }); Object.assign({}, { ...baz }); // Object.assign with a single argument that is an object literal Object.assign({}); Object.assign({ foo: bar }); ``` Examples of **correct** code for this rule: ```js ({ ...foo }); ({ ...baz, foo: "bar" }); // Any Object.assign call without an object literal as the first argument Object.assign(foo, { bar: baz }); Object.assign(foo, bar); Object.assign(foo, { bar, baz }); Object.assign(foo, { ...baz }); ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-promise-reject-errors.md --- ### What it does Require using Error objects as Promise rejection reasons. ### Why is this bad? It is considered good practice to only pass instances of the built-in `Error` object to the `reject()` function for user-defined errors in Promises. `Error` objects automatically store a stack trace, which can be used to debug an error by determining where it came from. If a Promise is rejected with a non-`Error` value, it can be difficult to determine where the rejection occurred. ### Examples Examples of **incorrect** code for this rule: ```js Promise.reject("something bad happened"); Promise.reject(5); Promise.reject(); new Promise(function (resolve, reject) { reject("something bad happened"); }); new Promise(function (resolve, reject) { reject(); }); ``` Examples of **correct** code for this rule: ```js Promise.reject(new Error("something bad happened")); Promise.reject(new TypeError("something bad happened")); new Promise(function (resolve, reject) { reject(new Error("something bad happened")); }); var foo = getUnknownValue(); Promise.reject(foo); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowEmptyReject type: `boolean` default: `false` Whether to allow calls to `Promise.reject()` with no arguments. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-rest-params.md --- ### What it does Disallows the use of the `arguments` object and instead enforces the use of rest parameters. ### Why is this bad? The `arguments` object does not have methods from `Array.prototype`, making it inconvenient for array-like operations. Using rest parameters provides a more intuitive and efficient way to handle variadic arguments. ### Examples Examples of **incorrect** code for this rule: ```javascript function foo() { console.log(arguments); } function foo(action) { var args = Array.prototype.slice.call(arguments, 1); action.apply(null, args); } function foo(action) { var args = [].slice.call(arguments, 1); action.apply(null, args); } ``` Examples of **correct** code for this rule: ```javascript function foo(...args) { console.log(args); } function foo(action, ...args) { action.apply(null, args); // Or use `action(...args)` (related to `prefer-spread` rule). } // Note: Implicit `arguments` can be shadowed. function foo(arguments) { console.log(arguments); // This refers to the first argument. } function foo() { var arguments = 0; console.log(arguments); // This is a local variable. } ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-spread.md --- ### What it does Require spread operators instead of `.apply()` ### Why is this bad? Before ES2015, one must use `Function.prototype.apply()` to call variadic functions. ```javascript var args = [1, 2, 3, 4]; Math.max.apply(Math, args); ``` In ES2015, one can use spread syntax to call variadic functions. ```javascript var args = [1, 2, 3, 4]; Math.max(...args); ``` ### Examples Examples of **incorrect** code for this rule: ```javascript foo.apply(undefined, args); foo.apply(null, args); obj.foo.apply(obj, args); ``` Examples of **correct** code for this rule: ```javascript // Using spread syntax foo(...args); obj.foo(...args); // The `this` binding is different. foo.apply(obj, args); obj.foo.apply(null, args); obj.foo.apply(otherObj, args); // The argument list is not variadic. // Those are warned by the `no-useless-call` rule. foo.apply(undefined, [1, 2, 3]); foo.apply(null, [1, 2, 3]); obj.foo.apply(obj, [1, 2, 3]); ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/prefer-template.md --- ### What it does Require template literals instead of string concatenation. ### Why is this bad? In ES2015 (ES6), we can use template literals instead of string concatenation. ### Examples Examples of **incorrect** code for this rule: ```js const str = "Hello, " + name + "!"; const str1 = "Time: " + 12 * 60 * 60 * 1000; ``` Examples of **correct** code for this rule: ```js const str = "Hello World!"; const str2 = `Time: ${12 * 60 * 60 * 1000}`; const str4 = "Hello, " + "World!"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/preserve-caught-error.md --- ### What it does Enforces that when re-throwing an error in a catch block, the original error is preserved using the 'cause' property. ### Why is this bad? Re-throwing an error without preserving the original error loses important debugging information and makes it harder to trace the root cause of issues. ### Examples Examples of **incorrect** code for this rule: ```js try { doSomething(); } catch (err) { throw new Error("Something failed"); } ``` Examples of **correct** code for this rule: ```js try { doSomething(); } catch (err) { throw new Error("Something failed", { cause: err }); } ``` ## Configuration This rule accepts a configuration object with the following properties: ### requireCatchParameter type: `boolean` default: `false` When set to `true`, requires that catch clauses always have a parameter. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/radix.md --- ### What it does Enforce the consistent use of the radix argument when using `parseInt()`, which specifies what base to use for parsing the number. ### Why is this bad? Using the `parseInt()` function without specifying the radix can lead to unexpected results. See the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#radix) for more information on how `parseInt()` handles certain edge-cases. ### Configuration Note that passing an option to this rule has no effect on its behavior. In v1.49.0, the config option for this rule was removed and made a no-op. This matches the behavior change made in ESLint v10, and the rule now always enforces that a radix parameter is provided to `parseInt()`. If you receive new violations due to this change, you may either opt to disable this rule, or add the radix parameter to all usages of `parseInt()` in your codebase. ### Examples Examples of **incorrect** code for this rule: ```javascript let num = parseInt("071"); // 57 ``` Examples of **correct** code for this rule: ```javascript let num = parseInt("071", 10); // 71 ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/require-await.md --- ### What it does Disallow async functions which have no `await` expression. ::: warning NOTE This rule is inferior to the accuracy of the type-aware `typescript/require-await` rule. If using type-aware rules, always prefer that rule over this one. ::: ### Why is this bad? Asynchronous functions in JavaScript behave differently than other functions in two important ways: 1. The return value is always a `Promise`. 2. You can use the `await` operator inside of them. The primary reason to use asynchronous functions is typically to use the await operator, such as this: ```js async function fetchData(processDataItem) { const response = await fetch(DATA_URL); const data = await response.json(); return data.map(processDataItem); } ``` Asynchronous functions that don’t use `await` might not need to be asynchronous functions and could be the unintentional result of refactoring. Note: this rule ignores async generator functions. This is because generators yield rather than return a value and async generators might yield all the values of another async generator without ever actually needing to use `await`. ### Examples Examples of **incorrect** code for this rule: ```js async function foo() { doSomething(); } ``` Examples of **correct** code for this rule: ```js async function foo() { await doSomething(); } ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/require-yield.md --- ### What it does This rule generates warnings for generator functions that do not have the yield keyword. ### Why is this bad? Probably a mistake. ### Examples Examples of **incorrect** code for this rule: ```javascript function* foo() { return 10; } ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/sort-imports.md --- ### What it does This rule checks all import declarations and verifies that all imports are first sorted by the used member syntax and then alphabetically by the first member or alias name. When declaring multiple imports, a sorted list of import declarations make it easier for developers to read the code and find necessary imports later. ### Why is this bad? Consistent import sorting can be useful for readability and maintainability of code. ### Examples Examples of **incorrect** code for this rule: ```javascript import { b, a, c } from "foo.js"; import d from "foo.js"; import e from "bar.js"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowSeparatedGroups type: `boolean` default: `false` When `true`, the rule allows import groups separated by blank lines to be treated independently. ### ignoreCase type: `boolean` default: `false` When `true`, the rule ignores case-sensitivity when sorting import names. ### ignoreDeclarationSort type: `boolean` default: `false` When `true`, the rule ignores the sorting of import declarations (the order of `import` statements). ### ignoreMemberSort type: `boolean` default: `false` When `true`, the rule ignores the sorting of import members within a single import declaration. ### memberSyntaxSortOrder type: `array` default: `["none", "all", "multiple", "single"]` Specifies the sort order of different import syntaxes. Must include all 4 kinds! #### memberSyntaxSortOrder\[n] type: `"none" | "all" | "multiple" | "single"` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/sort-keys.md --- ### What it does When declaring multiple properties, sorting property names alphabetically makes it easier to find and/or diff necessary properties at a later time. ### Why is this bad? Unsorted property keys can make the code harder to read and maintain. ### Examples Examples of **incorrect** code for this rule: ```js let myObj = { c: 1, a: 2, }; ``` Examples of **correct** code for this rule: ```js let myObj = { a: 2, c: 1, }; ``` ## Configuration ### The 1st option type: `"desc" | "asc"` Sorting order for keys. Accepts "asc" for ascending or "desc" for descending. ### The 2nd option This option is an object with the following properties: #### allowLineSeparatedGroups type: `boolean` default: `false` When true, groups of properties separated by a blank line are sorted independently. #### caseSensitive type: `boolean` default: `true` Whether the sort comparison is case-sensitive (A < a when true). #### minKeys type: `integer` default: `2` Minimum number of properties required in an object before sorting is enforced. #### natural type: `boolean` default: `false` Use natural sort order so that, for example, "a2" comes before "a10". ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/sort-vars.md --- ### What it does When declaring multiple variables within the same block, sorting variable names make it easier to find necessary variable easier at a later time. ### Why is this bad? Unsorted variable declarations can make the code harder to read and maintain. ### Examples Examples of **incorrect** code for this rule: ```js var b, a; var a, B, c; ``` Examples of **correct** code for this rule: ```js var a, b, c, d; var B, a, c; ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignoreCase type: `boolean` default: `false` When `true`, the rule ignores case-sensitivity when sorting variables. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/symbol-description.md --- ### What it does Require symbol descriptions. ### Why is this bad? The Symbol function may have an optional description. ```js var foo = Symbol("some description"); var someString = "some description"; var bar = Symbol(someString); ``` Using `description` promotes easier debugging: when a symbol is logged the description is used: ```js var foo = Symbol("some description"); console.log(foo); // prints - Symbol(some description) ``` ### Examples Examples of **incorrect** code for this rule: ```javascript var foo = Symbol(); ``` Examples of **correct** code for this rule: ```javascript var foo = Symbol("some description"); ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/unicode-bom.md --- ### What it does Require or disallow Unicode byte order mark (BOM) ### Why is this bad? The Unicode Byte Order Mark (BOM) is used to specify whether code units are big endian or little endian. That is, whether the most significant or least significant bytes come first. UTF-8 does not require a BOM because byte ordering does not matter when characters are a single byte. Since UTF-8 is the dominant encoding of the web, we make "never" the default option. ### Examples Examples of **incorrect** code for this rule: ```javascript var a = 123; ``` ## Configuration This rule accepts one of the following string values: ### `"always"` Always require a Unicode BOM (Byte Order Mark) at the beginning of the file. ### `"never"` Never allow a Unicode BOM (Byte Order Mark) at the beginning of the file. This is the default option. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/use-isnan.md --- ### What it does Disallows checking against `NaN` without using `isNaN()` call. ### Why is this bad? In JavaScript, `NaN` is a special value of the Number type. It’s used to represent any of the “not-a-number” values represented by the double-precision 64-bit format as specified by the IEEE Standard for Binary Floating-Point Arithmetic. Because `NaN` is unique in JavaScript by not being equal to anything, including itself, the results of comparisons to `NaN` are confusing: * `NaN === NaN` or `NaN == NaN` evaluate to false * `NaN !== NaN` or `NaN != NaN` evaluate to true Therefore, use `Number.isNaN()` or global `isNaN()` functions to test whether a value is `NaN`. ### Examples Examples of **incorrect** code for this rule: ```javascript foo == NaN; foo === NaN; foo <= NaN; foo > NaN; ``` ## Configuration This rule accepts a configuration object with the following properties: ### enforceForIndexOf type: `boolean` default: `false` Whether to disallow NaN as arguments of `indexOf` and `lastIndexOf` ### enforceForSwitchCase type: `boolean` default: `true` Whether to disallow NaN in switch cases and discriminants ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/valid-typeof.md --- ### What it does Enforce comparing `typeof` expressions against valid strings. ### Why is this bad? For a vast majority of use cases, the result of the `typeof` operator is one of the following string literals: `"undefined"`, `"object"`, `"boolean"`, `"number"`, `"string"`, `"function"`, `"symbol"`, and `"bigint"`. It is usually a typing mistake to compare the result of a `typeof` operator to other string literals. ### Examples Examples of **incorrect** code for this rule: ```js typeof foo === "strnig"; typeof foo == "undefimed"; typeof bar != "nunber"; // spellchecker:disable-line typeof bar !== "fucntion"; // spellchecker:disable-line ``` Examples of **correct** code for this rule: ```js typeof foo === "string"; typeof bar == "undefined"; typeof foo === baz; typeof bar === typeof qux; ``` ## Configuration This rule accepts a configuration object with the following properties: ### requireStringLiterals type: `boolean` default: `false` The `requireStringLiterals` option when set to `true`, allows the comparison of `typeof` expressions with only string literals or other `typeof` expressions, and disallows comparisons to any other value. Default is `false`. With `requireStringLiterals` set to `true`, the following are examples of **incorrect** code: ```js typeof foo === undefined; typeof bar == Object; typeof baz === "strnig"; typeof qux === "some invalid type"; typeof baz === anotherVariable; typeof foo == 5; ``` With `requireStringLiterals` set to `true`, the following are examples of **correct** code: ```js typeof foo === "undefined"; typeof bar == "object"; typeof baz === "string"; typeof bar === typeof qux; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/vars-on-top.md --- ### What it does Enforces that all `var` declarations are placed at the top of their containing scope. ### Why is this bad? In JavaScript, `var` declarations are hoisted to the top of their containing scope. Placing `var` declarations at the top explicitly improves code readability and maintainability by making the scope of variables clear. ### Examples Examples of **incorrect** code for this rule: ```js function doSomething() { if (true) { var first = true; } var second; } function doSomethingElse() { for (var i = 0; i < 10; i++) {} } f(); var a; class C { static { if (something) { var a = true; } } static { f(); var a; } } ``` Examples of **correct** code for this rule: ```js function doSomething() { var first; var second; if (true) { first = true; } } function doSomethingElse() { var i; for (i = 0; i < 10; i++) {} } var a; f(); class C { static { var a; if (something) { a = true; } } static { var a; f(); } } ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/eslint/yoda.md --- ### What it does Require or disallow "Yoda" conditions. This rule aims to enforce consistent style of conditions which compare a variable to a literal value. ### Why is this bad? Yoda conditions are so named because the literal value of the condition comes first while the variable comes second. For example, the following is a Yoda condition: ```js if ("red" === color) { } ``` This is called a Yoda condition because it reads as, "if red equals the color", similar to the way the Star Wars character Yoda speaks. Compare to the other way of arranging the operands: ```js if (color === "red") { // ... } ``` This typically reads, "if the color equals red", which is arguably a more natural way to describe the comparison. Proponents of Yoda conditions highlight that it is impossible to mistakenly use `=` instead of `==` because you cannot assign to a literal value. Doing so will cause a syntax error and you will be informed of the mistake early on. This practice was therefore very common in early programming where tools were not yet available. Opponents of Yoda conditions point out that tooling has made us better programmers because tools will catch the mistaken use of `=` instead of `==` (ESLint will catch this for you). Therefore, they argue, the utility of the pattern doesn't outweigh the readability hit the code takes while using Yoda conditions. ### Examples #### never Examples of **incorrect** code for the default `"never"` option: ```js if ("red" === color) { // ... } if (`red` === color) { // ... } if (`red` === `${color}`) { // ... } if (true == flag) { // ... } if (0 <= x && x < 1) { // ... } ``` Examples of **correct** code for the default `"never"` option: ```js if (5 & value) { // ... } if (value === "red") { // ... } if (value === `red`) { // ... } if (`${value}` === `red`) { } ``` #### exceptRange Examples of **correct** code for the `"never", { "exceptRange": true }` options: ```js function isReddish(color) { return color.hue < 60 || 300 < color.hue; } if (x < -1 || 1 < x) { // ... } if (count < 10 && 0 <= rand && rand < 1) { // ... } if (`blue` < x && x < `green`) { // ... } function howLong(arr) { return 0 <= arr.length && arr.length < 10 ? "short" : "long"; } ``` #### onlyEquality Examples of **correct** code for the `"never", { "onlyEquality": true }` options: ```js if (x < -1 || 9 < x) { } if (x !== "foo" && "bar" != x) { } if (x !== `foo` && `bar` != x) { } ``` #### always Examples of **incorrect** code for the `"always"` option: ```js if (color == "blue") { // ... } if (color == `blue`) { // ... } ``` Examples of **correct** code for the `"always"` option: ```js if ("blue" == value) { // ... } if (`blue` == value) { // ... } if (`blue` == `${value}`) { // ... } if (-1 < str.indexOf(substr)) { // ... } ``` ## Configuration ### The 1st option type: `"never" | "always"` #### `"never"` The default `"never"` option can have exception options in an object literal, via `exceptRange` and `onlyEquality`. #### `"always"` The `"always"` option requires that literal values must always come first in comparisons. ### The 2nd option This option is an object with the following properties: #### exceptRange type: `boolean` default: `false` If the `"exceptRange"` property is `true`, the rule *allows* yoda conditions in range comparisons which are wrapped directly in parentheses, including the parentheses of an `if` or `while` condition. A *range* comparison tests whether a variable is inside or outside the range between two literal values. #### onlyEquality type: `boolean` default: `false` If the `"onlyEquality"` property is `true`, the rule reports yoda conditions *only* for the equality operators `==` and `===`. The `onlyEquality` option allows a superset of the exceptions which `exceptRange` allows, thus both options are not useful together. ## How to use ## References --- --- url: /docs/guide/usage/minifier/faq.md --- # FAQ ## Top level variables are removed Top level variables are removed when the source type is `module`. This is because top level variables in module code are not accessible from other modules. Contrary to that, top level variables in script code are treated as global variables and are accessible from other scripts. If you expect the top level variables to be kept, you should not use a `.mjs` filename nor enable the `module` option. ## New lines in strings are not removed It may be surprising that new lines in strings are not removed and replaced with `\n` in minified code. This behavior is because the character escape sequences `\n` is two bytes long while the new line character is one byte long. ```js // this code is 16 bytes const foo="a\nb" // this code is 15 bytes const foo=`a b` ``` --- --- url: /docs/contribute/formatter.md --- # Formatter (oxfmt) We are currently porting Prettier and Biome Formatter to Oxc to create a high-performance, Prettier-compatible formatter. ## Architecture Overview The Oxc formatter is built around the same core concepts as Prettier but with significant performance optimizations: * **Document Model**: Uses Prettier and Biome's document IR (Intermediate Representation) * **Pretty Printing**: Implements Wadler's pretty printing algorithm * **AST Integration**: Leverages Oxc's fast parser for optimal performance ## Performance Considerations ### Optimization Strategies * **Memory Arena**: AST allocated in bump allocator * **String Interning**: Reuse common strings * **Lazy Evaluation**: Defer expensive computations ## Current Challenges ### Technical Challenges 1. **Comment Handling**: Preserving comment placement and formatting 2. **JavaScript Quirks**: Handling edge cases in JavaScript syntax 3. **Performance vs Compatibility**: Balancing speed with exact Prettier output 4. **Memory Management**: Efficient handling of large files ### Missing Features * \[ ] Plugin system compatibility * \[x] Configuration file support * \[ ] Editor integrations * \[x] CLI tool * \[x] Language server protocol --- --- url: /docs/contribute/development.md --- # Getting Started ## Clone Repository ```bash git clone -c core.longpaths=true git@github.com:oxc-project/oxc.git ``` ## Set Up Project ### Install Rust If you have not yet installed Rust, follow [the official instruction](https://www.rust-lang.org/tools/install) and install Rust. After installing Rust, run the following command on the project root: ```bash rustup show ``` `rustup show` reads the `./rust-toolchain.toml` file and installs the correct Rust toolchain and components for this project. ### `cargo binstall` Some Cargo tools are required to develop OXC, and it is recommended to use [cargo binstall](https://github.com/cargo-bins/cargo-binstall), which provides a low-complexity mechanism to install rust binaries and is faster way than building them from source by running `cargo install`. ```bash cargo install cargo-binstall ``` You can also download [the pre-compiled binary](https://github.com/cargo-bins/cargo-binstall#installation) and save it in `~/.cargo/bin`. ### `just` OXC utilizes [`just`](https://github.com/casey/just), which is a handy way to save and run project-specific commands: ```bash cargo binstall just -y ``` ### Install CMake Install CMake by downloading from the official [website](https://cmake.org/download/). [Homebrew](https://brew.sh/) users can alternatively install with: ```bash brew install cmake ``` ### Install pnpm Install `pnpm` (a package manager for node.js, similar to `npm`) by following instructions from the official [website](https://pnpm.io/installation). #### Dependencies Run the following command in `justfile` at the project root to install dependencies: ```bash just init ``` You can see the list of available commands by running `just`. You can run `just ready` (or, `just r` in short) to make sure the whole project builds and runs correctly. ## macOS: Faster Compilation macOS has an antivirus feature called XProtect that scans executables for malware on first run. This can significantly slow down Rust builds, especially build scripts and test executables. You can speed up compilation by adding Terminal as a "developer tool" in System Settings: 1. Open System Settings > Privacy & Security > Developer Tools 2. Add your terminal app (Terminal, iTerm, etc.) 3. Restart the terminal app **Note:** This disables an OS security feature. Only do this if you're comfortable with the trade-off. More details: https://nnethercote.github.io/2025/09/04/faster-rust-builds-on-mac.html --- --- url: /docs/guide/introduction.md --- # Getting Started [What is Oxc?](/docs/guide/what-is-oxc) ## Lint or format a codebase * Lint: [Oxlint](/docs/guide/usage/linter) * Format: [Oxfmt](/docs/guide/usage/formatter) ## Build tooling on top of Oxc * Parse JavaScript and TypeScript: [Parser](/docs/guide/usage/parser) * Transform TypeScript, JSX, and modern JavaScript: [Transformer](/docs/guide/usage/transformer) * Minify JavaScript for production builds: [Minifier](/docs/guide/usage/minifier) * Resolve modules for JavaScript and TypeScript: [Resolver](/docs/guide/usage/resolver) ## Contribute or learn * [Contribute](/docs/contribute/introduction) * [Learn](/docs/learn/parser_in_rust/intro) ## Other resources * [Troubleshooting](/docs/guide/troubleshooting) * [Benchmarks](/docs/guide/benchmarks) * [Projects using Oxc](/docs/guide/projects) * [Talks and media](/docs/guide/media) * [Team](/team) * [Endorsements](/endorsements) * [Release Blog](/blog/) * [Releases](https://github.com/oxc-project/oxc/releases) --- --- url: /docs/guide/usage/transformer/global-variable-replacement.md --- # Global Variable Replacement Oxc transformer supports replacing global variables. ## Define "Define" feature provides a way to replace global variables with constant expressions. This feature is similar to [Terser](https://terser.org/)'s `global_defs` option and [esbuild's `define` option](https://esbuild.github.io/api/#define). ```js // input const foo = __DEV__ ? 1 : 2; // output const foo = 1; ``` ```js // Example import { transform } from "oxc-transform"; const result = await transform("lib.js", sourceCode, { define: { __DEV__: "true", }, }); ``` Each `define` entry maps an expression to a string of code containing an expression. The keys of it must be an identifier (e.g. `__DEV__`), or a dotted sequence of identifiers (e.g. `process.env.NODE_ENV`, `import.meta.env.MODE`). The values of it must be a valid expression. ::: tip Always quote the values The values of `define` are the string of expressions. This means the value should always a string. If you mean a string literal, you should quote it (e.g. `__MODE__: '"development"'`, `__MODE__: JSON.stringify("development")`). ::: ::: tip The object reference are not shared Differently from esbuild, when passing an object to the value of the `define` option, the object reference is not shared. This means that if you change the object, the changes will not be reflected in the other places. ```js const foo = __OBJECT__; foo.bar = 1; console.log(foo.bar); // 1 const bar = __OBJECT__; console.log(foo.bar); // undefined ``` ```js // Example import { transform } from "oxc-transform"; const result = await transform("lib.js", sourceCode, { define: { __OBJECT__: "{}", }, }); ``` ::: ## Inject "Inject" feature provides a way to replace global variables with an import from a module. This feature is similar to [esbuild's `inject` option](https://esbuild.github.io/api/#inject) and [`@rollup/plugin-inject`](https://github.com/rollup/plugins/tree/master/packages/inject). ```js // input const foo = new Promise((resolve) => resolve(1)); // output import { Promise as P } from "es6-promise"; const foo = new P((resolve) => resolve(1)); ``` ```js // Example import { transform } from "oxc-transform"; const result = await transform("lib.js", sourceCode, { inject: { P: ["es6-promise", "Promise"], }, }); ``` Each `inject` entry maps an expression to an imported identifier. The keys of it must be an identifier (e.g. `__DEV__`), or a dotted sequence of identifiers (e.g. `process.env.NODE_ENV`). The values of it must be a string of the import source, or a tuple of strings of the import source and the import name (`*` is namespace import). ```js const examples = { // import { Promise } from 'es6-promise' Promise: ["es6-promise", "Promise"], // import { Promise as P } from 'es6-promise' P: ["es6-promise", "Promise"], // import $ from 'jquery' $: "jquery", // import * as fs from 'fs' fs: ["fs", "*"], // use a local module instead of a third-party one "Object.assign": path.resolve("src/helpers/object-assign.js"), }; ``` --- --- url: /docs/learn/ecmascript/grammar.md --- # Grammar JavaScript has one of the most challenging grammar to parse, this tutorial details all the sweat and tears I had while learning it. ## LL(1) Grammar According to [Wikipedia](https://en.wikipedia.org/wiki/LL_grammar), > an LL grammar is a context-free grammar that can be parsed by an LL parser, which parses the input from Left to right The first **L** means the scanning the source from **L**eft to right, and the second **L** means the construction of a **L**eftmost derivation tree. Context-free and the (1) in LL(1) means a tree can be constructed by just peeking at the next token and nothing else. LL Grammars are of particular interest in academia because we are lazy human beings and we want to write programs that generate parsers automatically so we don't need to write parsers by hand. Unfortunately, most industrial programming languages do not have a nice LL(1) grammar, and this applies to JavaScript too. :::info Mozilla started the [jsparagus](https://github.com/mozilla-spidermonkey/jsparagus) project a few years ago and wrote a [LALR parser generator in Python](https://github.com/mozilla-spidermonkey/jsparagus/tree/master/jsparagus). They haven't updated it much in the past two years and they sent a strong message at the end of [js-quirks.md](https://github.com/mozilla-spidermonkey/jsparagus/blob/master/js-quirks.md) > What have we learned today? > > * Do not write a JS parser. > * JavaScript has some syntactic horrors in it. But hey, you don't make the world's most widely used programming language by avoiding all mistakes. You do it by shipping a serviceable tool, in the right circumstances, for the right users. ::: *** The only practical way to parse JavaScript is to write a recursive descent parser by hand because of the nature of its grammar, so let's learn all the quirks in the grammar before we shoot ourselves in the foot. The list below starts simple and will become difficult to grasp, so please take grab a coffee and take your time. ## Identifiers There are three types of identifiers defined in `#sec-identifiers`, ``` IdentifierReference[Yield, Await] : BindingIdentifier[Yield, Await] : LabelIdentifier[Yield, Await] : ``` `estree` and some ASTs do not distinguish the above identifiers, and the specification does not explain them in plain text. `BindingIdentifier`s are declarations and `IdentifierReference`s are references to binding identifiers. For example in `var foo = bar`, `foo` is a `BindingIdentifier` and `bar` is a `IdentifierReference` in the grammar: ``` VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] opt Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] ``` follow `AssignmentExpression` into `PrimaryExpression` we get ``` PrimaryExpression[Yield, Await] : IdentifierReference[?Yield, ?Await] ``` Declaring these identifiers differently in the AST will greatly simply downstream tools, especially for semantic analysis. ```rust pub struct BindingIdentifier { pub node: Node, pub name: Atom, } pub struct IdentifierReference { pub node: Node, pub name: Atom, } ``` *** ## Class and Strict Mode ECMAScript Class is born after strict mode, so they decided that everything inside a class must be strict mode for simplicity. It is stated as such in `#sec-class-definitions` with just a `Node: A class definition is always strict mode code.` It is easy to declare strict mode by associating it with function scopes, but a `class` declaration does not have a scope, we need to keep an extra state just for parsing classes. ```rust // https://github.com/swc-project/swc/blob/f9c4eff94a133fa497778328fa0734aa22d5697c/crates/swc_ecma_parser/src/parser/class_and_fn.rs#L85 fn parse_class_inner( &mut self, _start: BytePos, class_start: BytePos, decorators: Vec, is_ident_required: bool, ) -> PResult<(Option, Class)> { self.strict_mode().parse_with(|p| { expect!(p, "class"); ``` *** ## Legacy Octal and Use Strict `#sec-string-literals-early-errors` disallows escaped legacy octal inside strings `"\01"`: ``` EscapeSequence :: LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence It is a Syntax Error if the source text matched by this production is strict mode code. ``` The best place to detect this is inside the lexer, it can ask the parser for strict mode state and throw errors accordingly. But, this becomes impossible when mixed with directives: ```javascript reference https://github.com/tc39/test262/blob/747bed2e8aaafe8fdf2c65e8a10dd7ae64f66c47/test/language/literals/string/legacy-octal-escape-sequence-prologue-strict.js#L16-L19 ``` `use strict` is declared after the escaped legacy octal, yet the syntax error needs to be thrown. Fortunately, no real code uses directives with legacy octals ... unless you want to pass the test262 case from above. *** ## Non-simple Parameter and Strict Mode Identical function parameters is allowed in non-strict mode `function foo(a, a) { }`, and we can forbid this by adding `use strict`: `function foo(a, a) { "use strict" }`. Later on in es6, other grammars were added to function parameters, for example `function foo({ a }, b = c) {}`. Now, what happens if we write the following where "01" is a strict mode error? ```javaScript function foo( value = (function() { return "\01"; }()), ) { "use strict"; return value; } ``` More specifically, what should we do if there is a strict mode syntax error inside the parameters thinking from the parser perspective? So in `#sec-function-definitions-static-semantics-early-errors`, it just bans this by stating ``` FunctionDeclaration : FunctionExpression : It is a Syntax Error if FunctionBodyContainsUseStrict of FunctionBody is true and IsSimpleParameterList of FormalParameters is false. ``` Chrome throws this error with a mysterious message "Uncaught SyntaxError: Illegal 'use strict' directive in function with non-simple parameter list". A more in-depth explanation is described in [this blog post](https://humanwhocodes.com/blog/2016/10/the-ecmascript-2016-change-you-probably-dont-know/) by the author of ESLint. :::info Fun fact, the above rule does not apply if we are targeting `es5` in TypeScript, it transpiles to ```javaScript function foo(a, b) { "use strict"; if (b === void 0) b = "\01"; } ``` ::: *** ## Parenthesized Expression Parenthesized expressions are supposed to not have any semantic meanings? For instance the AST for `((x))` can just be a single `IdentifierReference`, not `ParenthesizedExpression` -> `ParenthesizedExpression` -> `IdentifierReference`. And this is the case for JavaScript grammar. But ... who would have thought it can have runtime meanings. Found in [this estree issue](https://github.com/estree/estree/issues/194), it shows that ```javascript > fn = function () {}; > fn.name < "fn" > (fn) = function () {}; > fn.name < '' ``` So eventually acorn and babel added the `preserveParens` option for compatibility. *** ## Function Declaration in If Statement If we follow the grammar precisely in `#sec-ecmascript-language-statements-and-declarations`: ``` Statement[Yield, Await, Return] : ... lots of statements Declaration[Yield, Await] : ... declarations ``` The `Statement` node we define for our AST would obviously not contain `Declaration`, but in Annex B `#sec-functiondeclarations-in-ifstatement-statement-clauses`, it allows declaration inside the statement position of `if` statements in non-strict mode: ```javascript if (x) { function foo() {} } else function bar() {} ``` *** ## Label statement is legit We probably have never written a single line of labelled statement, but it is legit in modern JavaScript and not banned by strict mode. The following syntax is correct, it returns a labelled statement (not object literal). ```javascript { baz: "quaz"; }} /> // ^^^^^^^^^^^ `LabelledStatement` ``` *** ## `let` is not a keyword `let` is not a keyword so it is allowed to appear anywhere unless the grammar explicitly states `let` is not allowed in such positions. Parsers need to peek at the token after the `let` token and decide what it needs to be parsed into, e.g.: ```javascript let a; let = foo; let instanceof x; let + 1; while (true) let; a = let[0]; ``` *** ## For-in / For-of and the \[In] context If we look at the grammar for `for-in` and `for-of` in `#prod-ForInOfStatement`, it is immediately confusing to understand how to parse these. There are two major obstacles for us to understand: the `[lookahead ≠ let]` part and the `[+In]` part. If we have parsed to `for (let`, we need to check the peeking token is: * not `in` to disallow `for (let in)` * is `{`, `[` or an identifier to allow `for (let {} = foo)`, `for (let [] = foo)` and `for (let bar = foo)` Once reached the `of` or `in` keyword, the right-hand side expression needs to be passed with the correct \[+In] context to disallow the two `in` expressions in `#prod-RelationalExpression`: ``` RelationalExpression[In, Yield, Await] : [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] Note 2: The [In] grammar parameter is needed to avoid confusing the in operator in a relational expression with the in operator in a for statement. ``` And this is the only application for the `[In]` context in the entire specification. Also to note, the grammar `[lookahead ∉ { let, async of }]` forbids `for (async of ...)`, and it needs to be explicitly guarded against. *** ## Block-Level Function Declarations In Annex B.3.2 `#sec-block-level-function-declarations-web-legacy-compatibility-semantics`, an entire page is dedicated to explain how `FunctionDeclaration` is supposed to behave in `Block` statements. It boils down to ```javascript reference https://github.com/acornjs/acorn/blob/11735729c4ebe590e406f952059813f250a4cbd1/acorn/src/scope.js#L30-L35 ``` The name of a `FunctionDeclaration` needs to be treated the same as a `var` declaration if its inside a function declaration. This code snippet errors with a re-declaration error since `bar` is inside a block scope: ```javascript function foo() { if (true) { var bar; function bar() {} // redeclaration error } } ``` meanwhile, the following does not error because it is inside a function scope, function `bar` is treated as a var declaration: ```javascript function foo() { var bar; function bar() {} } ``` *** ## Grammar Context The syntactic grammar has 5 context parameters for allowing and disallowing certain constructs, namely `[In]`, `[Return]`, `[Yield]`, `[Await]` and `[Default]`. It is best to keep a context during parsing, for example in Biome: ```rust // https://github.com/rome/tools/blob/5a059c0413baf1d54436ac0c149a829f0dfd1f4d/crates/rome_js_parser/src/state.rs#L404-L425 pub(crate) struct ParsingContextFlags: u8 { /// Whether the parser is in a generator function like `function* a() {}` /// Matches the `Yield` parameter in the ECMA spec const IN_GENERATOR = 1 << 0; /// Whether the parser is inside a function const IN_FUNCTION = 1 << 1; /// Whatever the parser is inside a constructor const IN_CONSTRUCTOR = 1 << 2; /// Is async allowed in this context. Either because it's an async function or top level await is supported. /// Equivalent to the `Async` generator in the ECMA spec const IN_ASYNC = 1 << 3; /// Whether the parser is parsing a top-level statement (not inside a class, function, parameter) or not const TOP_LEVEL = 1 << 4; /// Whether the parser is in an iteration or switch statement and /// `break` is allowed. const BREAK_ALLOWED = 1 << 5; /// Whether the parser is in an iteration statement and `continue` is allowed. const CONTINUE_ALLOWED = 1 << 6; ``` And toggle and check these flags accordingly by following the grammar. ## AssignmentPattern vs BindingPattern In `estree`, the left-hand side of an `AssignmentExpression` is a `Pattern`: ``` extend interface AssignmentExpression { left: Pattern; } ``` and the left-hand side of a `VariableDeclarator` is a `Pattern`: ``` interface VariableDeclarator <: Node { type: "VariableDeclarator"; id: Pattern; init: Expression | null; } ``` A `Pattern` can be a `Identifier`, `ObjectPattern`, `ArrayPattern`: ``` interface Identifier <: Expression, Pattern { type: "Identifier"; name: string; } interface ObjectPattern <: Pattern { type: "ObjectPattern"; properties: [ AssignmentProperty ]; } interface ArrayPattern <: Pattern { type: "ArrayPattern"; elements: [ Pattern | null ]; } ``` But from the specification perspective, we have the following JavaScript: ```javascript // AssignmentExpression: { foo } = bar; ^^^ IdentifierReference [ foo ] = bar; ^^^ IdentifierReference // VariableDeclarator var { foo } = bar; ^^^ BindingIdentifier var [ foo ] = bar; ^^^ BindingIdentifier ``` This starts to become confusing because we now have a situation where we cannot directly distinguish whether the `Identifier` is a `BindingIdentifier` or a `IdentifierReference` inside a `Pattern`: ```rust enum Pattern { Identifier, // Is this a `BindingIdentifier` or a `IdentifierReference`? ArrayPattern, ObjectPattern, } ``` This will lead to all sorts of unnecessary code further down the parser pipeline. For example, when setting up the scope for semantic analysis, we need to inspect the parents of this `Identifier` to determine whether we should bind it to the scope or not. A better solution is to fully understand the specification and decide what to do. The grammar for `AssignmentExpression` and `VariableDeclaration` are defined as: ``` 13.15 Assignment Operators AssignmentExpression[In, Yield, Await] : LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] 13.15.5 Destructuring Assignment In certain circumstances when processing an instance of the production AssignmentExpression : LeftHandSideExpression = AssignmentExpression the interpretation of LeftHandSideExpression is refined using the following grammar: AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ``` ``` 14.3.2 Variable Statement VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] ``` The specification distinguishes this two grammar by defining them separately with an `AssignmentPattern` and a `BindingPattern`. So in situations like this, do not be afraid to deviate from `estree` and define extra AST nodes for our parser: ```rust enum BindingPattern { BindingIdentifier, ObjectBindingPattern, ArrayBindingPattern, } enum AssignmentPattern { IdentifierReference, ObjectAssignmentPattern, ArrayAssignmentPattern, } ``` I was in a super confusing state for a whole week until I finally reached enlightenment: we need to define an `AssignmentPattern` node and a `BindingPattern` node instead of a single `Pattern` node. * `estree` must be correct because people have been using it for years so it cannot be wrong? * how are we going to cleanly distinguish the `Identifier`s inside the patterns without defining two separate nodes? I just cannot find where the grammar is? * After a whole day of navigating the specification ... the grammar for `AssignmentPattern` is in the 5th subsection of the main section "13.15 Assignment Operators" with the subtitle "Supplemental Syntax" 🤯 - this is really out of place because all grammar is defined in the main section, not like this one defined after the "Runtime Semantics" section *** :::tip The following cases are really difficult to grasp. Here be dragons. ::: ## Ambiguous Grammar Let's first think like a parser and solve the problem - given the `/` token, is it a division operator or the start of a regex expression? ```javascript a / b; a / / regex /; a /= / regex /; / regex / / b; /=/ / /=/; ``` It is almost impossible, isn't it? Let's break these down and follow the grammar. The first thing we need to understand is that the syntactic grammar drives the lexical grammar as stated in `#sec-ecmascript-language-lexical-grammar` > There are several situations where the identification of lexical input elements is sensitive to the syntactic grammar context that is consuming the input elements. This means that the parser is responsible for telling the lexer which token to return next. The above example indicates that the lexer needs to return either a `/` token or a `RegExp` token. For getting the correct `/` or `RegExp` token, the specification says: > The InputElementRegExp goal symbol is used in all syntactic grammar contexts where a RegularExpressionLiteral is permitted ... > In all other contexts, InputElementDiv is used as the lexical goal symbol. And the syntax for `InputElementDiv` and `InputElementRegExp` are ``` InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator <---------- the `/` and `/=` token RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral <-------- the `RegExp` token ``` This means whenever the grammar reaches `RegularExpressionLiteral`, `/` need to be tokenized as a `RegExp` token (and throw an error if it does not have a matching `/`). All other cases we'll tokenize `/` as a slash token. Let's walk through an example: ``` a / / regex / ^ ------------ PrimaryExpression:: IdentifierReference ^ ---------- MultiplicativeExpression: MultiplicativeExpression MultiplicativeOperator ExponentiationExpression ^^^^^^^^ - PrimaryExpression: RegularExpressionLiteral ``` This statement does not match any other start of `Statement`, so it'll go down the `ExpressionStatement` route: `ExpressionStatement` --> `Expression` --> `AssignmentExpression` --> ... --> `MultiplicativeExpression` --> ... --> `MemberExpression` --> `PrimaryExpression` --> `IdentifierReference`. We stopped at `IdentifierReference` and not `RegularExpressionLiteral`, the statement "In all other contexts, InputElementDiv is used as the lexical goal symbol" applies. The first slash is a `DivPunctuator` token. Since this is a `DivPunctuator` token, the grammar `MultiplicativeExpression: MultiplicativeExpression MultiplicativeOperator ExponentiationExpression` is matched, the right-hand side is expected to be an `ExponentiationExpression`. Now we are at the second slash in `a / /`. By following `ExponentiationExpression`, we reach `PrimaryExpression: RegularExpressionLiteral` because `RegularExpressionLiteral` is the only matching grammar with a `/`: ``` RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags ``` This second `/` will be tokenized as `RegExp` because the specification states "The InputElementRegExp goal symbol is used in all syntactic grammar contexts where a RegularExpressionLiteral is permitted". :::info As an exercise, try and follow the grammar for `/=/ / /=/`. ::: *** ## Cover Grammar Read the [V8 blog post](https://v8.dev/blog/understanding-ecmascript-part-4) on this topic first. To summarize, the specification states the following three cover grammars: #### CoverParenthesizedExpressionAndArrowParameterList ``` PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] When processing an instance of the production PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar: ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ``` ``` ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ``` These definitions defines: ```javascript let foo = (a, b, c); // SequenceExpression let bar = (a, b, c) => {}; // ArrowExpression ^^^^^^^^^ CoverParenthesizedExpressionAndArrowParameterList ``` A simple but cumbersome approach to solving this problem is to parse it as a `Vec` first, then write a converter function to convert it to `ArrowParameters` node, i.e. each individual `Expression` need to be converted to a `BindingPattern`. It should be noted that, if we are building the scope tree within the parser, i.e. create the scope for arrow expression during parsing, but do not create one for a sequence expression, it is not obvious how to do this. [esbuild](https://github.com/evanw/esbuild) solved this problem by creating a temporary scope first, and then dropping it if it is not an `ArrowExpression`. This is stated in its [architecture document](https://github.com/evanw/esbuild/blob/master/docs/architecture.md#symbols-and-scopes): > This is mostly pretty straightforward except for a few places where the parser has pushed a scope and is in the middle of parsing a declaration only to discover that it's not a declaration after all. This happens in TypeScript when a function is forward-declared without a body, and in JavaScript when it's ambiguous whether a parenthesized expression is an arrow function or not until we reach the => token afterwards. This would be solved by doing three passes instead of two so we finish parsing before starting to set up scopes and declare symbols, but we're trying to do this in just two passes. So instead we call popAndDiscardScope() or popAndFlattenScope() instead of popScope() to modify the scope tree later if our assumptions turn out to be incorrect. *** #### CoverCallExpressionAndAsyncArrowHead ``` CallExpression : CoverCallExpressionAndAsyncArrowHead When processing an instance of the production CallExpression : CoverCallExpressionAndAsyncArrowHead the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar: CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] ``` ``` AsyncArrowFunction[In, Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] When processing an instance of the production AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar: AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await] ``` These definitions define: ```javascript async (a, b, c); // CallExpression async (a, b, c) => {} // AsyncArrowFunction ^^^^^^^^^^^^^^^ CoverCallExpressionAndAsyncArrowHead ``` This looks strange because `async` is not a keyword. The first `async` is a function name. *** #### CoverInitializedName ``` 13.2.5 Object Initializer ObjectLiteral[Yield, Await] : ... PropertyDefinition[Yield, Await] : CoverInitializedName[?Yield, ?Await] Note 3: In certain contexts, ObjectLiteral is used as a cover grammar for a more restricted secondary grammar. The CoverInitializedName production is necessary to fully cover these secondary grammars. However, use of this production results in an early Syntax Error in normal contexts where an actual ObjectLiteral is expected. 13.2.5.1 Static Semantics: Early Errors In addition to describing an actual object initializer the ObjectLiteral productions are also used as a cover grammar for ObjectAssignmentPattern and may be recognized as part of a CoverParenthesizedExpressionAndArrowParameterList. When ObjectLiteral appears in a context where ObjectAssignmentPattern is required the following Early Error rules are not applied. In addition, they are not applied when initially parsing a CoverParenthesizedExpressionAndArrowParameterList or CoverCallExpressionAndAsyncArrowHead. PropertyDefinition : CoverInitializedName I* t is a Syntax Error if any source text is matched by this production. ``` ``` 13.15.1 Static Semantics: Early Errors AssignmentExpression : LeftHandSideExpression = AssignmentExpression If LeftHandSideExpression is an ObjectLiteral or an ArrayLiteral, the following Early Error rules are applied: * LeftHandSideExpression must cover an AssignmentPattern. ``` These definitions define: ```javascript ({ prop = value } = {}); // ObjectAssignmentPattern ({ prop: value }); // ObjectLiteral with SyntaxError ``` Parsers need to parse `ObjectLiteral` with `CoverInitializedName`, and throw the syntax error if it does not reach `=` for `ObjectAssignmentPattern`. As an exercise, which one of the following `=` should throw a syntax error? ```javascript let { x = 1 } = ({ x = 1 } = { x: 1 }); ``` --- --- url: /docs/guide/usage/formatter/ignore-files.md --- # Ignore files Oxfmt provides several ways to exclude files from formatting. ## `ignorePatterns` The recommended way to ignore files. Add to `.oxfmtrc.json`: ```json [.oxfmtrc.json] { "ignorePatterns": ["dist/**", "*.min.js"] } ``` * Uses `.gitignore` syntax * Paths are resolved relative to the directory containing the Oxfmt config file * Formatter-specific and independent of Git Files matching `ignorePatterns` **cannot be formatted**, even if explicitly specified. ## `.gitignore` Oxfmt respects `.gitignore` files in the current directory tree. * Global gitignore and parent `.gitignore` files are not read * A `.git` directory is not required Files ignored by `.gitignore` **can still be formatted** if explicitly specified. ## VCS directories and `node_modules` Ignored by default: `.git`, `.svn`, `.jj`, `node_modules` Use `--with-node-modules` to include `node_modules`. ## Lock files `package-lock.json`, `pnpm-lock.yaml`, etc. are always ignored. ## `.prettierignore` Supported for Prettier compatibility. Uses `.gitignore` syntax. Files in `.prettierignore` cannot be formatted, even when explicitly specified. For new projects, prefer `ignorePatterns`. --- --- url: /docs/guide/usage/linter/ignore-files.md description: Control which files Oxlint lints. --- # Ignore files Large repositories contain files that should not be linted, such as build output, vendored code, snapshots, or generated artifacts. Oxlint provides a predictable ignore model that works well in monorepos and CI. > \[!TIP] > It is strongly recommended to use `"ignorePatterns"` in your Oxlint config file (`.oxlintrc.json` or `oxlint.config.ts`) for ignoring files rather than a separate ignore file. This ensures that every developer will have the same ignores across all tools and commands running Oxlint, especially IDE/editor integrations. It also keeps your configuration centralized to one file. ## Default ignores Oxlint automatically ignores: * `.git` directories * Minified files containing `.min.`, `-min.`, or `_min.` in the file name * Files matched by `.gitignore` (global gitignore files are not respected) Hidden files are not automatically ignored. ## `ignorePatterns` The recommended approach is to define ignores in your config file using `ignorePatterns`. This keeps ignores close to the configuration they belong to and works naturally with nested configs. Patterns are resolved relative to the configuration file. ::: code-group ```json [.oxlintrc.json] { "$schema": "./node_modules/oxlint/configuration_schema.json", "ignorePatterns": ["dist/**", "coverage/**", "vendor/**", "test/snapshots/**"] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ ignorePatterns: ["dist/**", "coverage/**", "vendor/**", "test/snapshots/**"], }); ``` ::: In monorepos, nested configs can ignore package specific output without affecting the rest of the repository. ## `.eslintignore` Oxlint also supports `.eslintignore` for compatibility with existing ESLint setups. Existing `.eslintignore` files can remain in place during migration. The syntax is compatible with `.gitignore`, including comments and negation patterns. New projects should prefer `"ignorePatterns"` in their config file, and we strongly recommend moving over to `"ignorePatterns"` soon after migrating, if not during migration. ## Ignore from the command line CLI flags are useful for one-off changes in CI or local debugging. Use a custom ignore file: ```bash oxlint --ignore-path path/to/ignorefile ``` Add additional ignore patterns: ```bash oxlint --ignore-pattern 'dist/**' --ignore-pattern 'coverage/**' ``` Quote patterns to avoid shell glob expansion. ## Unignoring files Ignore files support negation patterns, which allow a directory to be ignored while keeping specific files. To ignore everything under `build/` except one file, ignore the contents rather than the directory itself: ::: code-group ```json [.oxlintrc.json] { "$schema": "./node_modules/oxlint/configuration_schema.json", "ignorePatterns": ["build/**/*", "!build/keep.js"] } ``` ```ts [oxlint.config.ts] import { defineConfig } from "oxlint"; export default defineConfig({ ignorePatterns: ["build/**/*", "!build/keep.js"], }); ``` ::: This keeps traversal possible while still ignoring almost everything. ## Disable ignoring To disable all ignore behavior, including ignore files and CLI ignore options, use `--no-ignore`: ```bash oxlint --no-ignore ``` --- --- url: /docs/guide/usage/formatter/ignoring.md --- # Ignoring ## Ignore files Oxfmt provides several ways to ignore files. ### `.gitignore` Respects `.gitignore` in the current working directory and subdirectories. Does not respect global, exclude, or `.gitignore` in parent directories. Does not require `.git` directory to exist. Files listed here can still be formatted if explicitly specified. This is safe for use cases like `husky`, as ignored files are never staged. ### `.prettierignore` / `oxfmtrc.ignorePatterns` These are formatter-specific ignore settings, separate from Git, and each operates within its own scope. `.prettierignore` is only read from the current working directory. For `.oxfmtrc.json(c)`, see [Configuration](./config). The syntax is the same as `.gitignore`, and paths are resolved relative to the directory containing the ignore file. Files ignored here cannot be formatted even if explicitly specified. This behavior is intended for use cases like `husky`. You can also specify custom ignore paths with `--ignore-path`, or use `!`-prefixed positional paths to exclude files. ### VCS directories and `node_modules` Directories like `.git`, `.svn` and `.jj` are ignored by default. The `node_modules` directory is also ignored unless `--with-node_modules` flag is specified. If the current working directory is inside these directories, formatting is still possible. ### Lock files Files like `package-lock.json` and `pnpm-lock.yaml` are ignored by default. These cannot be formatted even if explicitly specified. ## Ignore comments For JS/TS files, you can use a `prettier-ignore` comment. This takes effect on the next statement/expression. ```js // prettier-ignore const a=42; /* prettier-ignore */ const x=()=>{return 2;} <> {/* prettier-ignore */} ; ``` ::: warning (Not documented, but) Prettier supports trailing ignore comment too. However, we don't support it to avoid a performance hit. Please update your code in that case. ::: For non-JS files, the same convention as Prettier works. Please see Prettier's [documentation](https://prettier.io/docs/ignore#html). For TOML files, ignore comments are not supported. --- --- url: /docs/guide/usage/linter/rules/import/consistent-type-specifier-style.md --- ### What it does This rule either enforces or bans the use of inline type-only markers for named imports. ### Why is this bad? Mixing top-level `import type { Foo } from 'foo'` with inline `{ type Bar }` forces readers to mentally switch contexts when scanning your imports. Enforcing one style makes it immediately obvious which imports are types and which are value imports. ### Examples Examples of incorrect code for the default `prefer-top-level` option: ```typescript import { type Foo } from "Foo"; import Foo, { type Bar } from "Foo"; ``` Examples of correct code for the default option: ```typescript import type { Foo } from "Foo"; import type Foo, { Bar } from "Foo"; ``` Examples of incorrect code for the `prefer-inline` option: ```typescript import type { Foo } from "Foo"; import type Foo, { Bar } from "Foo"; ``` Examples of correct code for the `prefer-inline` option: ```typescript import { type Foo } from "Foo"; import Foo, { type Bar } from "Foo"; ``` ## Configuration This rule accepts one of the following string values: ### `"prefer-top-level"` Prefer `import type { Foo } from 'foo'` for type imports. ### `"prefer-inline"` Prefer `import { type Foo } from 'foo'` for type imports. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/default.md --- ### What it does If a default import is requested, this rule will report if there is no default export in the imported module. ### Why is this bad? Using a default import when there is no default export can lead to confusion and runtime errors. It can make the code harder to understand and maintain, as it may suggest that a module has a default export when it does not, leading to unexpected behavior. ### Examples Examples of **incorrect** code for this rule: ```javascript // ./bar.js export function bar() { return null; } // ./foo.js import bar from "./bar"; // no default export found in ./bar ``` Examples of **correct** code for this rule: ```javascript // ./bar.js export default function bar() { return null; } // ./foo.js import { bar } from "./bar"; // correct usage of named import ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/export.md --- ### What it does Reports funny business with exports, like repeated exports of names or defaults. ### Why is this bad? Having multiple exports of the same name can lead to ambiguity and confusion in the codebase. It makes it difficult to track which export is being used and can result in runtime errors if the wrong export is referenced. ### Examples Examples of **incorrect** code for this rule: ```javascript let foo; export { foo }; // Multiple exports of name 'foo'. export * from "./export-all"; // Conflicts if export-all.js also exports foo ``` Examples of **correct** code for this rule: ```javascript let foo; export { foo as foo1 }; // Renamed export to avoid conflict export * from "./export-all"; // No conflict if export-all.js also exports foo ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/exports-last.md --- ### What it does This rule enforces that all exports are declared at the bottom of the file. This rule will report any export declarations that comes before any non-export statements. ### Why is this bad? Exports scattered throughout the file can lead to poor code readability and increase the cost of locating the export quickly ### Examples Examples of **incorrect** code for this rule: ```js const bool = true; export const foo = "bar"; const str = "foo"; ``` Examples of **correct** code for this rule: ```js const arr = ["bar"]; export const bool = true; export const str = "foo"; export function func() { console.log("Hello World"); } ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/extensions.md --- ### What it does Some file resolve algorithms allow you to omit the file extension within the import source path. For example the node resolver (which does not yet support ESM/import) can resolve ./foo/bar to the absolute path /User/someone/foo/bar.js because the .js extension is resolved automatically by default in CJS. Depending on the resolver you can configure more extensions to get resolved automatically. In order to provide a consistent use of file extensions across your code base, this rule can enforce or disallow the use of certain file extensions. ### Why is this bad? ESM-based file resolve algorithms (e.g., the one that Vite provides) recommend specifying the file extension to improve performance. Without extensions, the bundler must check for various possible file extensions, which can slow down the build process on large projects. In addition, common ESM environments (such as browsers and Node.js) typically require fully specified relative imports, which means extensionless imports are not supported there. For personal preference and compatibility reasons, the rule also allows configuration to *disallow* extensions in imports. This is generally not recommended, but it can be done if preferred. ### Examples Examples of **incorrect** code for this rule: The following patterns are considered problems when configuration set to "always": ```js import foo from "./foo"; import bar from "./bar"; import Component from "./Component"; import foo from "@/foo"; ``` The following patterns are considered problems when configuration set to "never": ```js import foo from "./foo.js"; import bar from "./bar.json"; import Component from "./Component.jsx"; import express from "express/index.js"; ``` Examples of **correct** code for this rule: The following patterns are not considered problems when configuration set to "always": ```js import foo from "./foo.js"; import bar from "./bar.json"; import Component from "./Component.jsx"; import * as path from "path"; import foo from "@/foo.js"; ``` The following patterns are not considered problems when configuration set to "never": ```js import foo from "./foo"; import bar from "./bar"; import Component from "./Component"; import express from "express/index"; import * as path from "path"; ``` **Per-extension configuration examples**: ```js // Configuration: { "vue": "always", "ts": "never" } import Component from "./Component.vue"; // ✓ OK - .vue configured as "always" import utils from "./utils"; // ✓ OK - .ts configured as "never" import styles from "./styles.css"; // ✓ OK - .css not configured, ignored // Configuration: ["ignorePackages", { "js": "never", "ts": "never" }] import foo from "./foo"; // ✓ OK - no extension import bar from "lodash/fp"; // ✓ OK - package import, ignored (ignorePackages sets this to true) ``` ### Differences compared to `eslint-plugin-import` If you see differences between this rule implementation and the original `eslint-plugin-import` rule, please note that there are some intentional, inherent differences in the behavior of this rule and the original. Oxlint understands and can resolve TypeScript paths out-of-the-box. If your ESLint configuration did not include `eslint-import-resolver-typescript` or similar, then the original rule will not have been able to resolve TypeScript paths correctly, and so the behavior between ESLint and Oxlint may differ. Generally, this means that Oxlint will catch *more* valid violations than the original rule, though this depends on the specific configuration. Oxlint is also able to resolve multiple `tsconfig.json` files in a single repo, and so in a monorepo setup will be more capable with regards to resolving file paths. ## Configuration This rule accepts three types of configuration: 1. **Global rule** (string): `"always"`, `"never"`, or `"ignorePackages"` ```jsonc { "rules": { // this would require extensions for all imports, *including from packages* // e.g. `import React from 'react';` would be disallowed. // You should generally always set `ignorePackages` to `true` when using `always`. "import/extensions": ["error", "always"], }, } ``` 2. **Per-extension rules** (object): `{ "js": "always", "jsx": "never", ... }` ```jsonc { "rules": { "import/extensions": [ "error", // per-extension rules: // require extensions for .js imports and disallow them for .ts imports { "js": "always", "ts": "never", "ignorePackages": true }, ], }, } ``` 3. **Combined** (array): `["error", "always", { "js": "never" }]` or `["error", { "js": "always" }]` ```jsonc { "rules": { "import/extensions": [ "error", "always", // by default, require extensions for all imports { "ts": "never", // override the global value and disallow extensions on imports for specific file types "ignorePackages": true, }, ], }, } ``` **Default behavior (no configuration)**: All imports - of all kinds - pass. Unconfigured file extensions are ignored, to avoid false positives. This rule accepts a configuration object with the following properties: ### checkTypeImports type: `boolean` default: `false` Whether to check type imports when enforcing extension rules. ```ts // If checkTypeImports is `false`, we don't care about // whether these imports have file extensions or not, both are always allowed: import type { Foo } from "./foo"; import type { Foo } from "./foo.ts"; ``` ### ignorePackages type: `boolean` default: `false` Whether to ignore package imports when enforcing extension rules. > \[!IMPORTANT] > When setting this rule to `always`, you should also set `ignorePackages` to `true`. > Otherwise, package imports without extensions (such as `import React from 'react';`) > will be disallowed, which is not desirable and is not fixable. A boolean option (not per-extension) that exempts package imports from the "always" rule. Can be set in the config object: `["error", "always", { "ignorePackages": true }]` Legacy shorthand: `["error", "ignorePackages"]` is equivalent to `["error", "always", { "ignorePackages": true }]` * **With "always"**: When `true`, package imports (e.g., `lodash`, `@babel/core`) don't require extensions * **With "never"**: This option has no effect; extensions are still forbidden on package imports Example: `["error", "always", { "ignorePackages": true }]` allows `import foo from "lodash"` but requires `import bar from "./bar.js"` ### pathGroupOverrides type: `array` default: `[]` Path group overrides for bespoke import specifiers. Array of pattern-action pairs for custom import protocols (monorepo tools, custom resolvers). Each override has: `{ "pattern": "", "action": "enforce" | "ignore" }` **Pattern matching**: Uses glob patterns (`*`, `**`, `{a,b}`) to match import specifiers. Note that the pattern matching is done in Rust with the fast-glob library, and so may differ from the JavaScript glob library used by the original ESLint rule. **Actions**: * `"enforce"`: Apply normal extension validation (respect global/per-extension rules) * `"ignore"`: Skip all extension validation for matching imports **Precedence**: First matching pattern wins. **Examples:** ```json { "pattern": "rootverse{*,*/**}", "action": "ignore" } ``` Matches imports from `rootverse+debug:src`, `rootverse+bfe:src/symbols` and ignores whether or not they have an extension. #### pathGroupOverrides\[n] type: `object` ##### pathGroupOverrides\[n].action type: `"enforce" | "ignore"` Action to take for path group overrides. Determines how import extensions are validated for matching bespoke import specifiers. ###### `"enforce"` Enforce extension validation for matching imports (require extensions based on config). ###### `"ignore"` Ignore matching imports entirely (skip all extension validation). ##### pathGroupOverrides\[n].pattern type: `string` Glob pattern to match import specifiers. This uses Rust's fast-glob library for matching. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/first.md --- ### What it does Forbids any non-import statements before imports except directives. ### Why is this bad? Notably, imports are hoisted, which means the imported modules will be evaluated before any of the statements interspersed between them. Keeping all imports together at the top of the file may prevent surprises resulting from this part of the spec ### Examples Examples of **incorrect** code for this rule: ```js import { x } from "./foo"; export { x }; import { y } from "./bar"; ``` Examples of **correct** code for this rule: ```js import { x } from "./foo"; import { y } from "./bar"; export { x, y }; ``` ## Configuration This rule accepts one of the following string values: ### `"absolute-first"` Forces absolute imports to be listed before relative imports. Examples of **incorrect** code for this rule with `"absolute-first"`: ```js import { x } from "./foo"; import { y } from "bar"; ``` Examples of **correct** code for this rule with `"absolute-first"`: ```js import { y } from "bar"; import { x } from "./foo"; ``` ### `"disable-absolute-first"` Disables the absolute-first behavior. This is the default behavior. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/group-exports.md --- ### What it does Reports when named exports are not grouped together in a single export declaration or when multiple assignments to CommonJS module.exports or exports object are present in a single file. ### Why is this bad? An export declaration or module.exports assignment can appear anywhere in the code. By requiring a single export declaration all your exports will remain at one place, making it easier to see what exports a module provides. ### Examples Examples of **incorrect** code for this rule: ```js export const first = true; export const second = true; ``` Examples of **correct** code for this rule: ```js const first = true; const second = true; export { first, second }; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/max-dependencies.md --- ### What it does Forbid modules to have too many dependencies (`import` statements only). ### Why is this bad? This is a useful rule because a module with too many dependencies is a code smell, and usually indicates the module is doing too much and/or should be broken up into smaller modules. **NOTE**: This rule only counts `import` statements, and does not count dependencies from CommonJS `require()` statements. This is a difference from the original eslint-import-plugin rule. ### Examples Given `{ "max": 2 }` Examples of **incorrect** code for this rule: ```javascript import a from "./a"; import b from "./b"; import c from "./c"; // Too many dependencies: 3 (max: 2) ``` Examples of **correct** code for this rule: ```javascript import a from "./a"; import b from "./b"; // Allowed: 2 dependencies (max: 2) ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignoreTypeImports type: `boolean` default: `false` Whether to ignore type imports when counting dependencies. ```ts // Neither of these count as dependencies if `ignoreTypeImports` is true: import type { Foo } from "./foo"; import { type Foo } from "./foo"; ``` ### max type: `integer` default: `10` Maximum number of dependencies allowed in a file. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/named.md --- ### What it does Verifies that all named imports are part of the set of named exports in the referenced module. For `export`, verifies that all named exports exist in the referenced module. Note: for packages, the plugin will find exported names from `jsnext:main` (deprecated) or `module`, if present in `package.json`. Redux's npm module includes this key, and thereby is lintable, for example. A module path that is ignored or not unambiguously an ES module will not be reported when imported. Note that type imports and exports, as used by Flow, are always ignored. ### Why is this bad? Importing or exporting names that do not exist in the referenced module can lead to runtime errors and confusion. It may suggest that certain functionality is available when it is not, making the code harder to maintain and understand. This rule helps ensure that your code accurately reflects the available exports, improving reliability. ### Examples Given ```js // ./foo.js export const foo = "I'm so foo"; ``` Examples of **incorrect** code for this rule: ```js // ./baz.js import { notFoo } from "./foo"; // re-export export { notFoo as defNotBar } from "./foo"; // will follow 'jsnext:main', if available import { dontCreateStore } from "redux"; ``` Examples of **correct** code for this rule: ```js // ./bar.js import { foo } from "./foo"; // re-export export { foo as bar } from "./foo"; // node_modules without jsnext:main are not analyzed by default // (import/ignore setting) import { SomeNonsenseThatDoesntExist } from "react"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/namespace.md --- ### What it does Enforces names exist at the time they are dereferenced, when imported as a full namespace (i.e. `import * as foo from './foo'; foo.bar();` will report if bar is not exported by `./foo.`). Will report at the import declaration if there are no exported names found. Also, will report for computed references (i.e. `foo["bar"]()`). Reports on assignment to a member of an imported namespace. ### Why is this bad? Dereferencing a name that does not exist can lead to runtime errors and unexpected behavior in your code. It makes the code less reliable and harder to maintain, as it may not be clear which names are valid. This rule helps ensure that all referenced names are defined, improving the clarity and robustness of your code. ### Examples Given ```javascript // ./foo.js export const bar = "I'm bar"; ``` Examples of **incorrect** code for this rule: ```javascript // ./qux.js import * as foo from "./foo"; foo.notExported(); // Error: notExported is not exported // Assignment to a member of an imported namespace foo.bar = "new value"; // Error: bar cannot be reassigned // Computed reference to a non-existent export const method = "notExported"; foo[method](); // Error: notExported does not exist ``` Examples of **correct** code for this rule: ```javascript // ./baz.js import * as foo from "./foo"; console.log(foo.bar); // Valid: bar is exported // Computed reference const method = "bar"; foo[method](); // Valid: method refers to an exported function ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowComputed type: `boolean` default: `false` Whether to allow computed references to an imported namespace. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-absolute-path.md --- ### What it does This rule forbids the import of modules using absolute paths. ### Why is this bad? Node.js allows the import of modules using an absolute path such as `/home/xyz/file.js`. That is a bad practice as it ties the code using it to your computer, and therefore makes it unusable in packages distributed on npm for instance. ### Examples Examples of **incorrect** code for this rule: ```js import f from "/foo"; import f from "/some/path"; var f = require("/foo"); var f = require("/some/path"); ``` Examples of **correct** code for this rule: ```js import _ from "lodash"; import foo from "foo"; import foo from "./foo"; var _ = require("lodash"); var foo = require("foo"); var foo = require("./foo"); ``` Examples of **incorrect** code for the `{ amd: true }` option: ```js define("/foo", function (foo) {}); require("/foo", function (foo) {}); ``` Examples of **correct** code for the `{ amd: true }` option: ```js define("./foo", function (foo) {}); require("./foo", function (foo) {}); ``` ## Configuration This rule accepts a configuration object with the following properties: ### amd type: `boolean` default: `false` If set to `true`, dependency paths for AMD-style define and require calls will be resolved: ```js /* import/no-absolute-path: ["error", { "commonjs": false, "amd": true }] */ define(["/foo"], function (foo) { /*...*/ }); // reported require(["/foo"], function (foo) { /*...*/ }); // reported const foo = require("/foo"); // ignored because of explicit `commonjs: false` ``` ### commonjs type: `boolean` default: `true` If set to `true`, dependency paths for CommonJS-style require calls will be resolved: ```js var foo = require("/foo"); // reported ``` ### esmodule type: `boolean` default: `true` If set to `true`, dependency paths for ES module import statements will be resolved: ```js import foo from "/foo"; // reported ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-amd.md --- ### What it does Forbids the use of AMD `require` and `define` calls. ### Why is this bad? AMD (Asynchronous Module Definition) is an older module format that is less common in modern JavaScript development, especially with the widespread use of ES modules and CommonJS in Node.js. AMD introduces unnecessary complexity and is often considered outdated. This rule enforces the use of more modern module systems to improve maintainability and consistency across the codebase. ### Examples Examples of **incorrect** code for this rule: ```javascript require([a, b], function () {}); ``` Examples of **correct** code for this rule: ```javascript require("../name"); require(`../name`); ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-anonymous-default-export.md --- ### What it does Reports if a module's default export is unnamed. This includes several types of unnamed data types; literals, object expressions, arrays, anonymous functions, arrow functions, and anonymous class declarations. ### Why is this bad? Ensuring that default exports are named helps improve the grepability of the codebase by encouraging the re-use of the same identifier for the module's default export at its declaration site and at its import sites. ### Examples Examples of **incorrect** code for this rule: ```js export default []; export default () => {}; export default class {}; export default function() {}; export default foo(bar); export default 123; export default {}; export default new Foo(); export default `foo`; export default /^123/; ``` Examples of **correct** code for this rule: ```js const foo = 123; export default foo; export default function foo() {}; export default class MyClass {}; export default function foo() {}; export default foo(bar); /* import/no-anonymous-default-export: ["error", { "allowLiteral": true }] */ export default 123; /* import/no-anonymous-default-export: ["error", { "allowArray": true }] */ export default [] /* import/no-anonymous-default-export: ["error", { "allowArrowFunction": true }] */ export default () => {}; /* import/no-anonymous-default-export: ["error", { "allowAnonymousClass": true }] */ export default class {}; /* import/no-anonymous-default-export: ["error", { "allowAnonymousFunction": true }] */ export default function() {}; /* import/no-anonymous-default-export: ["error", { "allowObject": true }] */ export default {}; /* import/no-anonymous-default-export: ["error", { "allowNew": true }] */ export default new Foo(); /* import/no-anonymous-default-export: ["error", { "allowCallExpression": true }] */ export default foo(bar); ``` By default, all types of anonymous default exports are forbidden, but any types can be selectively allowed by toggling them on in the options. ## Configuration This rule accepts a configuration object with the following properties: ### allowAnonymousClass type: `boolean` default: `false` Allow anonymous class as default export. ### allowAnonymousFunction type: `boolean` default: `false` Allow anonymous function as default export. ### allowArray type: `boolean` default: `false` Allow anonymous array as default export. ### allowArrowFunction type: `boolean` default: `false` Allow anonymous arrow function as default export. ### allowCallExpression type: `boolean` default: `true` Allow anonymous call expression as default export. ### allowLiteral type: `boolean` default: `false` Allow anonymous literal as default export. ### allowNew type: `boolean` default: `false` Allow anonymous new expression as default export. ### allowObject type: `boolean` default: `false` Allow anonymous object as default export. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-commonjs.md --- ### What it does Forbids the use of CommonJS `require` calls. Also forbids `module.exports` and `exports.*`. ### Why is this bad? ESM modules or Typescript uses `import` and `export` syntax instead of CommonJS syntax. This rule enforces the use of more modern module systems to improve maintainability and consistency across the codebase. ### Examples Examples of **incorrect** code for this rule: ```js var mod = require("fs"); var exports = (module.exports = {}); exports.sayHello = function () { return "Hello"; }; module.exports = "Hola"; ``` Examples of **correct** code for this rule: ```js var a = b && require("c"); if (typeof window !== "undefined") { require("somelib"); } var fs = null; try { fs = require("fs"); } catch (error) {} ``` ## Configuration This rule accepts a configuration object with the following properties: ### allowConditionalRequire type: `boolean` default: `true` When set to `true`, allows conditional `require()` calls (e.g., inside `if` statements or try-catch blocks). This is useful for places where you need to conditionally load via commonjs requires if ESM imports are not supported. ### allowPrimitiveModules type: `boolean` default: `false` If `allowPrimitiveModules` option is set to true, the following is valid: ```js module.exports = "foo"; module.exports = function rule(context) { return { /* ... */ }; }; ``` but this is still reported: ```js module.exports = { x: "y" }; exports.z = function bark() { /* ... */ }; ``` ### allowRequire type: `boolean` default: `false` If set to `true`, `require` calls are valid: ```js var mod = require("./mod"); ``` but `module.exports` is reported as usual. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-cycle.md --- ### What it does Ensures that there is no resolvable path back to this module via its dependencies. This includes cycles of depth 1 (imported module imports me) to an effectively infinite value, if the `maxDepth` option is not set. ### Why is this bad? Dependency cycles lead to confusing architectures where bugs become hard to find. It is common to import an `undefined` value that is caused by a cyclic dependency. ### Examples Examples of **incorrect** code for this rule: ```javascript // dep-b.js import "./dep-a.js"; export function b() { /* ... */ } ``` ```javascript // dep-a.js import { b } from "./dep-b.js"; // reported: Dependency cycle detected. export function a() { /* ... */ } ``` In this example, `dep-a.js` and `dep-b.js` import each other, creating a circular dependency, which is problematic. Examples of **correct** code for this rule: ```javascript // dep-b.js export function b() { /* ... */ } ``` ```javascript // dep-a.js import { b } from "./dep-b.js"; // no circular dependency export function a() { /* ... */ } ``` In this corrected version, `dep-b.js` no longer imports `dep-a.js`, breaking the cycle. ## Configuration This rule accepts a configuration object with the following properties: ### allowUnsafeDynamicCyclicDependency type: `boolean` default: `false` Allow cyclic dependency if there is at least one dynamic import in the chain ### ignoreExternal type: `boolean` default: `false` Ignore external modules ### ignoreTypes type: `boolean` default: `true` Ignore type-only imports ### maxDepth type: `integer` default: `4294967295` Maximum dependency depth to traverse ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-default-export.md --- ### What it does Forbids a module from having default exports. This helps your editor provide better auto-import functionality, as named exports offer more explicit and predictable imports compared to default exports. ### Why is this bad? Default exports can lead to confusion, as the name of the imported value can vary based on how it's imported. This can make refactoring and auto-imports less reliable. ### Examples Examples of **incorrect** code for this rule: ```javascript export default 'bar'; const foo = 'foo'; export { foo as default } ``` Examples of **correct** code for this rule: ```javascript export const foo = "foo"; export const bar = "bar"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-duplicates.md --- ### What it does Reports if a resolved path is imported more than once in the same module. This helps avoid unnecessary duplicate imports and keeps the code clean. ### Why is this bad? Importing the same module multiple times can lead to redundancy and unnecessary complexity. It also affects maintainability, as it might confuse developers and result in inconsistent usage of imports across the code. ### Examples Examples of **incorrect** code for this rule: ```javascript import { foo } from "./module"; import { bar } from "./module"; import a from "./module"; import { b } from "./module"; ``` Examples of **correct** code for this rule: ```typescript import { foo, bar } from "./module"; import * as a from "foo"; // separate statements for namespace imports import { b } from "foo"; import { c } from "foo"; // separate type imports, unless import type { d } from "foo"; // `prefer-inline` is true ``` ## Configuration This rule accepts a configuration object with the following properties: ### considerQueryString type: `boolean` default: `false` When set to `true`, the rule will consider the query string part of the import path when determining if imports are duplicates. This is useful when using loaders like webpack that use query strings to configure how a module should be loaded. Examples of **correct** code with this option set to `true`: ```javascript import x from "./bar?optionX"; import y from "./bar?optionY"; ``` ### preferInline type: `boolean` default: `false` When set to `true`, prefer inline type imports instead of separate type import statements for TypeScript code. Examples of **correct** code with this option set to `true`: ```typescript import { Foo, type Bar } from "./module"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-dynamic-require.md --- ### What it does Forbids imports that use an expression for the module argument. This includes dynamically resolved paths in `require` or `import` statements. ### Why is this bad? Using expressions that are resolved at runtime in import statements makes it difficult to determine where the module is being imported from. This can complicate code navigation and hinder static analysis tools, which rely on predictable module paths for linting, bundling, and other optimizations. ### Examples Examples of **incorrect** code for this rule: ```javascript require(name); require(`../${name}`); ``` Examples of **correct** code for this rule: ```javascript require("../name"); require(`../name`); ``` ## Configuration This rule accepts a configuration object with the following properties: ### esmodule type: `boolean` default: `false` When `true`, also check `import()` expressions for dynamic module specifiers. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-empty-named-blocks.md --- ### What it does Enforces that named import blocks are not empty. ### Why is this bad? Empty named imports serve no practical purpose and often result from accidental deletions or tool-generated code. ### Examples Examples of **incorrect** code for this rule: ```js import {} from "mod"; import Default from "mod"; ``` Examples of **correct** code for this rule: ```js import { mod } from "mod"; import Default, { mod } from "mod"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-mutable-exports.md --- ### What it does Forbids the use of mutable exports with var or let. ### Why is this bad? In general, we should always export constants ### Examples Examples of **incorrect** code for this rule: ```js export let count = 2; export var count = 3; let count = 4; export { count }; ``` Examples of **correct** code for this rule: ```js export const count = 1; export function getCount() {} export class Counter {} ``` ### Functions/Classes Note that exported function/class declaration identifiers may be reassigned, but are not flagged by this rule at this time. They may be in the future. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-named-as-default.md --- ### What it does Reports use of an exported name as the locally imported name of a default export. This happens when an imported default export is assigned a name that conflicts with a named export from the same module. ### Why is this bad? Using a named export's identifier for a default export can cause confusion and errors in understanding which value is being imported. It also reduces code clarity, making it harder for other developers to understand the intended imports. ### Examples Given ```javascript // foo.js export default "foo"; export const bar = true; ``` Examples of **incorrect** code for this rule: ```javascript // Invalid: using exported name 'bar' as the identifier for default export. import bar from "./foo.js"; ``` Examples of **correct** code for this rule: ```javascript // Valid: correctly importing default export with a non-conflicting name. import foo from "./foo.js"; ``` ### Differences compared to `eslint-plugin-import` If you see differences between this rule implementation and the original `eslint-plugin-import` rule, please note that the behavior may differ in certain cases due to differences in how module resolution is implemented and configured. For example, the original rule may require additional resolver configuration to handle certain imports, especially when TypeScript paths are used or in monorepo setups with multiple `tsconfig.json` files. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-named-as-default-member.md --- ### What it does Reports the use of an exported name (named export) as a property on the default export. This occurs when trying to access a named export through the default export, which is incorrect. ### Why is this bad? Accessing a named export via the default export is incorrect and will not work as expected. Named exports should be imported directly, while default exports are accessed without properties. This mistake can lead to runtime errors or undefined behavior. ### Examples Given ```javascript // ./bar.js export function bar() { return null; } export default () => { return 1; }; ``` Examples of **incorrect** code for this rule: ```javascript // ./foo.js import foo from "./bar"; const bar = foo.bar; // Incorrect: trying to access named export via default ``` Examples of **correct** code for this rule: ```javascript // ./foo.js import { bar } from "./bar"; // Correct: accessing named export directly ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-named-default.md --- ### What it does Reports use of a default export as a locally named import. ### Why is this bad? Rationale: the syntax exists to import default exports expressively, let's use it. ### Examples Examples of **incorrect** code for this rule: ```js // message: Using exported name 'bar' as identifier for default export. import { default as foo } from "./foo.js"; import { default as foo, bar } from "./foo.js"; ``` Examples of **correct** code for this rule: ```js import foo from "./foo.js"; import foo, { bar } from "./foo.js"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-named-export.md --- ### What it does Prohibit named exports. ### Why is this bad? Named exports require strict identifier matching and can lead to fragile imports, while default exports enforce a single, consistent module entry point. ### Examples Examples of **incorrect** code for this rule: ```js export const foo = "foo"; const bar = "bar"; export { bar }; ``` Examples of **correct** code for this rule: ```js export default 'bar'; const foo = 'foo'; export { foo as default } ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-namespace.md --- ### What it does Enforce a convention of not using namespaced (a.k.a. "wildcard" \*) imports. ### Why is this bad? Namespaced imports, while sometimes used, are generally considered less ideal in modern JavaScript development for several reasons: 1. **Specificity and Namespace Pollution**: * **Specificity**: Namespaced imports import the entire module, bringing in everything, even if you only need a few specific functions or classes. This can lead to potential naming conflicts if different modules have the same names for different functions. * **Pollution**: Importing an entire namespace pollutes your current scope with potentially unnecessary functions and variables. It increases the chance of accidental use of an unintended function or variable, leading to harder-to-debug errors. 2. **Maintainability**: * **Clarity**: Namespaced imports can make it harder to understand which specific functions or classes are being used in your code. This is especially true in larger projects with numerous imports. * **Refactoring**: If a function or class name changes within the imported module, you might need to update several parts of your code if you are using namespaced imports. This becomes even more challenging when dealing with multiple namespaces. 3. **Modern Practice**: * **Explicit Imports**: Modern JavaScript practices encourage explicit imports for specific components. This enhances code readability and maintainability. * **Tree-Shaking**: Tools like Webpack and Rollup use tree-shaking to remove unused code from your bundles. Namespaced imports can prevent efficient tree-shaking, leading to larger bundle sizes. ### Examples Examples of **incorrect** code for this rule: ```js import * as user from "user-lib"; import some, * as user from "./user"; ``` Examples of **correct** code for this rule: ```js import { getUserName, isUser } from "user-lib"; import user from "user-lib"; import defaultExport, { isUser } from "./user"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### ignore type: `string[]` default: `[]` An array of glob strings for modules that should be ignored by the rule. For example, `["*.json"]` will ignore all JSON imports. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-nodejs-modules.md --- ### What it does Forbid the use of Node.js builtin modules. Can be useful for client-side web projects that do not have access to those modules. ### Why is this bad? Node.js builtins (e.g. `fs`, `path`, `crypto`) are not available in browsers, so importing them in client bundles causes runtime failures or forces bundlers to inject heavy polyfills/shims. This increases bundle size, can leak server-only logic to the client, and may hide environment mismatches until production. ### Examples Examples of **incorrect** code for this rule: ```js import fs from "fs"; import path from "path"; var fs = require("fs"); var path = require("path"); ``` Examples of **correct** code for this rule: ```js import _ from "lodash"; import foo from "foo"; import foo from "./foo"; var _ = require("lodash"); var foo = require("foo"); var foo = require("./foo"); /* import/no-nodejs-modules: ["error", {"allow": ["path"]}] */ import path from "path"; ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` Array of names of allowed modules. Defaults to an empty array. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-relative-parent-imports.md --- ### What it does Forbids importing modules from parent directories using relative paths. ### Why is this bad? This restriction enforces tree-like folder structures instead of complex graph-like structures, making large codebases easier to maintain. Dependencies flow in one direction (parent to child), which clarifies module relationships. ### Examples Examples of **incorrect** code for this rule: ```javascript import foo from "../bar"; import foo from "../../utils/helper"; const baz = require("../config"); export { qux } from "../shared"; ``` Examples of **correct** code for this rule: ```javascript import foo from "lodash"; import a from "./lib/a"; import b from "./b"; ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-self-import.md --- ### What it does Forbids a module from importing itself. This can sometimes happen accidentally, especially during refactoring. ### Why is this bad? Importing a module into itself creates a circular dependency, which can cause runtime issues, including infinite loops, unresolved imports, or `undefined` values. ### Examples Examples of **incorrect** code for this rule: ```javascript // foo.js import foo from "./foo.js"; // Incorrect: module imports itself const foo = require("./foo"); // Incorrect: module imports itself ``` Examples of **correct** code for this rule: ```javascript // foo.js import bar from "./bar.js"; // Correct: module imports another module ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-unassigned-import.md --- ### What it does This rule aims to remove modules with side-effects by reporting when a module is imported but not assigned. ### Why is this bad? With both CommonJS' require and the ES modules' import syntax, it is possible to import a module but not to use its result. This can be done explicitly by not assigning the module to a variable. Doing so can mean either of the following things: * The module is imported but not used * The module has side-effects. Having side-effects, makes it hard to know whether the module is actually used or can be removed. It can also make it harder to test or mock parts of your application. ### Examples Examples of **incorrect** code for this rule: ```js import "should"; require("should"); ``` Examples of **correct** code for this rule: ```js import _ from "foo"; import _, { foo } from "foo"; import _, { foo as bar } from "foo"; const _ = require("foo"); const { foo } = require("foo"); const { foo: bar } = require("foo"); bar(require("foo")); ``` ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` default: `[]` A list of glob patterns to allow unassigned imports for specific modules. For example: `{ "allow": ["**/*.css"] }` will allow unassigned imports for any module ending with `.css`. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/no-webpack-loader-syntax.md --- ### What it does Forbids using Webpack loader syntax directly in import or require statements. ### Why is this bad? This loader syntax is non-standard, so it couples the code to Webpack. The recommended way to specify Webpack loader configuration is in a [Webpack configuration file](https://webpack.js.org/concepts/loaders/#configuration). ### Examples Examples of **incorrect** code for this rule: ```javascript import myModule from "my-loader!my-module"; import theme from "style!css!./theme.css"; var myModule = require("my-loader!./my-module"); var theme = require("style!css!./theme.css"); ``` Examples of **correct** code for this rule: ```javascript import myModule from "./my-module"; import theme from "./theme.css"; var myModule = require("./my-module"); var theme = require("./theme.css"); ``` ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/prefer-default-export.md --- ### What it does In exporting files, this rule checks if there is default export or not. ### Why is this bad? This rule exists to standardize module exports by preferring default exports when a module only has one export, enhancing readability, maintainability. ### Examples Examples of **incorrect** code for the `{ target: "single" }` option: ```js export const foo = "foo"; ``` Examples of **correct** code for the `{ target: "single" }` option: ```js export const foo = "foo"; const bar = "bar"; export default bar; ``` Examples of **incorrect** code for the `{ target: "any" }` option: ```js export const foo = "foo"; export const baz = "baz"; ``` Examples of **correct** code for the `{ target: "any" }` option: ```js export default function bar() {} ``` ## Configuration This rule accepts a configuration object with the following properties: ### target type: `"single" | "any"` default: `"single"` Configuration option to specify the target type for preferring default exports. #### `"single"` Prefer default export when there is only one export in the module. #### `"any"` Prefer default export in any module that has exports. ## How to use ## References --- --- url: /docs/guide/usage/linter/rules/import/unambiguous.md --- ### What it does Warn if a `module` could be mistakenly parsed as a `script` instead of as a pure [ES module](https://nodejs.org/api/esm.html#modules-ecmascript-modules). ### Why is this bad? For ESM-only environments, ambiguous files may lead to unexpected results and problems. ### Examples Examples of **incorrect** code for this rule: ```js function x() {} (function x() { return 42; })(); ``` Examples of **correct** code for this rule: ```js import "foo"; function x() { return 42; } export function x() { return 42; } (function x() { return 42; })(); export {}; // simple way to mark side-effects-only file as 'module' without any imports/exports ``` ## How to use ## References --- --- url: /docs/guide/usage/formatter/ignore-comments.md --- # Inline ignore comments For JS/TS files, use `oxfmt-ignore` to skip formatting the next statement: ```js // oxfmt-ignore const a = 42; /* oxfmt-ignore */ const x = () => { return 2; }; <> {/* oxfmt-ignore */} ; ``` For JS-in-Vue, use `oxfmt-ignore` inside 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., `