--- url: /guide/getting-started.md --- # Getting Started {#getting-started} A powerful ESLint configuration extending the popular Airbnb style guide, with added support for TypeScript. It comes with two core packages * [`eslint-config-airbnb-extended`](../config/installation): Extends Airbnb's ESLint config to support TypeScript and custom rules. * [`create-airbnb-x-config`](../cli/guide): A CLI tool to quickly set up and customize your ESLint configuration with the Airbnb Extended setup. ## Goodbye Legacy, Hello to Flat Config {#hello-to-flat-config} This package is designed **exclusively for ESLint’s new Flat Config system**. Legacy `.eslintrc*` files are **not supported**. If your project still relies on `.eslintrc`, you should continue using the older Airbnb packages. By focusing only on Flat Config, this package stays **modern, lightweight, and future-proof**. ## Note {#note} This package was created by taking reference from the following ESLint configuration packages: * [`eslint-config-airbnb-base`](https://www.npmjs.com/package/eslint-config-airbnb-base) * [`eslint-config-airbnb`](https://www.npmjs.com/package/eslint-config-airbnb) * [`eslint-config-airbnb-typescript`](https://www.npmjs.com/package/eslint-config-airbnb-typescript) These packages are no longer maintained. To ensure continued compatibility and keep up-to-date with the latest versions of dependencies, I have updated the dependencies and extended their functionality, resulting in the creation of the `eslint-config-airbnb-extended` package, which is actively maintained and fully supports TypeScript. ## Migration {#migration} Please refer to the [migration guide](../migration/upgrade-to-extended) for more details. --- --- url: /guide/why.md --- # Why? {#why} Writing clean and consistent code is super important, not just for you, but for your entire team. A consistent coding style makes projects easier to maintain, reduces bugs, and helps every developer quickly understand each other’s code. That’s exactly why we rely on **[ESLint](https://eslint.org/)**, a powerful tool that analyzes your code and provides instant feedback to keep things in shape. ## Problem 😬 {#problem} One of the most popular ESLint style guides out there is the **Airbnb ESLint Config**. For years, developers have trusted it as a reliable, opinionated set of rules that enforce best practices and readable code. It became a kind of *“gold standard”* in the JavaScript community. But here’s the issue: * The Airbnb config hasn’t been updated in **over 4 years**. * It doesn’t work well with **ESLint 9** (and beyond). * It lacks **TypeScript support**. * It contains **some rules** that create unnecessary friction. In today’s fast-moving JavaScript ecosystem, three years is a long time. By the time ESLint 9 came around, the old Airbnb config simply couldn’t keep up. --- --- url: /config/installation.md --- # Installation {#installation} Setting up `eslint-config-airbnb-extended` is simple and flexible. You can either use the automated **CLI tool** (`create-airbnb-x-config`) or perform a **manual installation** (not recommended). We strongly suggest using the CLI tool since it ensures you always have the latest configuration and avoids unnecessary setup mistakes. ## Automate the Setup with `create-airbnb-x-config` {#with-cli} The easiest way to get started is by running the CLI tool inside your project directory: ::: code-group ```sh [npm] $ npx create-airbnb-x-config ``` ```sh [yarn] $ yarn dlx create-airbnb-x-config ``` ```sh [pnpm] $ pnpx create-airbnb-x-config ``` ```sh [bun] $ bunx create-airbnb-x-config ``` ::: This tool will guide you step by step, helping you configure ESLint quickly with the **Airbnb Extended setup**. For a full list of options and advanced usage, check out the [guide](../cli/guide). ## Manual Installation (Not Recommended) {#manual-installation} While you can install everything by hand, we **do not recommend it**. Manual installation requires you to: * Identify all required packages * Install them individually * Keep them updated manually This approach can lead to inconsistencies if new changes are introduced in the configuration. If you still prefer this method, refer to the [Packages Used](./packages-used) section for a breakdown of dependencies. --- --- url: /config/extended-config.md --- # Extended Config {#extended-config} The **Extended config** is a modern version of Airbnb’s ESLint setup, built for today’s **TypeScript** and **JavaScript** projects. It uses the latest **Flat Config format**, adds better support for **imports**, **styles**, and **TypeScript**, and is fully ready for **ESLint 9+**. ## Features {#features} * **Optional Strict Rules** → Turn on extra checks for **imports**, **React**, and **TypeScript** when needed. See [Strict Rules](../customization/strict-rules.md). * **Smarter Imports** → Uses `eslint-plugin-import-x` to detect invalid imports, enforce import order, and provide better TypeScript support compared to the old `eslint-plugin-import`. * **Consistent Code Style** → Uses `@stylistic/eslint-plugin` for spacing, quotes, semicolons, and indentation. Replaces deprecated ESLint style rules. * **Modern Node Support** → Replaces deprecated ESLint Node rules with `eslint-plugin-n`. * **Next.js Best Practices** → Uses `@next/eslint-plugin-next` to enforce Next.js standards, catch common issues, and promote performance optimizations. * **TypeScript Path Aliases** → Built-in `eslint-import-resolver-typescript` support for `tsconfig.json` paths to prevent false-positive import errors. ## Overview {#overview} The **Extended package** in `eslint-config-airbnb-extended` provides four main exports: * **Rules** → Core rule groups that enforce good coding practices and are used in configs. * **Plugins** → External ESLint plugins used to power specific rules (e.g., React, TypeScript, Next.js). * **Extensions** → Helper layers that bring together rules, parsers, and settings from recommended configs so you can build your own base config with full customization. * **Configs** → Predefined sets of rules (built from rules + extensions) that map directly to the Airbnb family. * **Helpers** → Reusable utilities for managing ESLint extensions, dev-only file patterns, and import resolver settings across JS and TS projects. --- --- url: /config/extended-config/rules.md --- # Rules {#rules} The `rules` are the **building blocks** of each config. Every config is just a collection of these rule groups. ## Base Rules {#base-rules} | Rule Group | Description | | ------------------ | ------------------------------------------------------------------------------- | | **Best Practices** | Enforces common best practices to improve code quality and maintainability. | | **Errors** | Helps catch runtime errors and unsafe patterns early. | | **ES6** | Provides rules specific to ES6+ syntax and features. | | **Imports** | Ensures proper import/export usage with `eslint-plugin-import`. | | **Imports Strict** | See [Strict Imports](../../customization/strict-rules.md#strict-imports-rules). | | **Strict** | Enables strict mode rules. | | **Style** | Covers general code style rules such as spacing, quotes, and semicolons. | | **Stylistic** | Uses `@stylistic/eslint-plugin` for consistent formatting. | | **Variables** | Validates variable declarations, usage, and scoping rules. | ### Example {#base-rules-example} ```ts import { rules } from 'eslint-config-airbnb-extended'; export default [ // Best Practices rules.base.bestPractices, // Imports rules.base.imports, ]; ``` ## Node Rules {#node-rules} | Rule Group | Description | | --------------------------- | ----------------------------------------------------------------------------------------------- | | **Base** | Core Node.js linting rules. | | **Globals** | Enforces using Node.js globals such as `console` and `process` directly without requiring them. | | **Promises** | Enforces using promise based variants of core modules such as `fs` and `dns` variant. | | **No Unsupported Features** | Prevents usage of Node features not supported in your target version. | ### Example {#node-rules-example} ```ts import { rules } from 'eslint-config-airbnb-extended'; export default [ // Promises rules.node.promises, ]; ``` ## React Rules {#react-rules} | Rule Group | Description | | --------------------- | --------------------------------------------------------------------------- | | **Base** | Core React rules for JSX and component structure. | | **JSX Accessibility** | Accessibility rules via `eslint-plugin-jsx-a11y` for inclusive UIs. | | **Hooks** | Rules from `eslint-plugin-react-hooks` ensuring proper hook usage. | | **Stylistic** | Ensures consistent styling inside JSX and React code. | | **React Strict** | See [Strict React](../../customization/strict-rules.md#strict-react-rules). | ### Example {#react-rules-example} ```ts import { rules } from 'eslint-config-airbnb-extended'; export default [ // JSX Accessibility rules.react.jsxA11y, // Hooks rules.react.hooks, ]; ``` ## Next.js Rules {#nextjs-rules} | Rule Group | Description | | ------------------- | ---------------------------------------------------------------------- | | **Base** | Applies general Next.js linting best practices. | | **Core Web Vitals** | Enforces performance and SEO improvements recommended by Next.js team. | ### Example {#nextjs-rules-example} ```ts import { rules } from 'eslint-config-airbnb-extended'; export default [ // Base rules.next.base, ]; ``` ## TypeScript Rules {#typescript-rules} | Rule Group | Description | | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | **Base** | Adjusts ESLint by disabling rules covered by TypeScript and enabling ones that benefit from type-checking. | | **Stylistic** | Uses `@stylistic/eslint-plugin` to enforce consistent TypeScript code formatting. | | **TypeScript ESLint** | Rules powered by `typescript-eslint`. | | **Imports** | Activates `eslint-plugin-import-x` rules needed for TypeScript while disabling rules already covered by TypeScript to avoid redundancy. | | **TypeScript ESLint Strict** | See [Strict TypeScript ESLint](../../customization/strict-rules.md#strict-typescript-rules). | ### Example {#typescript-rules-example} ```ts import { rules } from 'eslint-config-airbnb-extended'; export default [ // Base rules.typescript.base, // Imports rules.typescript.imports, ]; ``` --- --- url: /config/extended-config/plugins.md --- # Plugins {#plugins} The **plugins** are external packages that add extra linting power to ESLint. They provide the actual rules for different ecosystems like **React**, **Next.js**, and **TypeScript**. Without these plugins, the rules cannot run. Each plugin brings its own set of checks to improve code quality and consistency. | Package | Purpose | | ---------------------------------------------------------------------------------------- | -------------------------- | | **[@stylistic/eslint-plugin](https://eslint.style)** | Styling & formatting rules | | **[eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x)** | Import/export validation | | **[eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)** | Node.js best practices | | **[eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react)** | React-specific linting | | **[eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)** | Rules of Hooks | | **[eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)** | Accessibility for JSX | | **[@next/eslint-plugin-next](https://nextjs.org/docs/app/api-reference/config/eslint)** | Next.js-specific linting | | **[@typescript-eslint](https://typescript-eslint.io)** | TypeScript linting support | ### Example {#plugins-example} ```ts import { plugins } from 'eslint-config-airbnb-extended'; export default [ // Stylistic plugin plugins.stylistic, // TypeScript ESLint plugin plugins.typescriptEslint, ]; ``` --- --- url: /config/extended-config/extensions.md --- # Extensions {#extensions} Normally, many plugins hide their **recommended configs**. That means if you want to build a fully custom config, you can’t access everything. Extensions solve this problem. An **extension** = `rules + parser + settings` → combined into a reusable layer. Now, every **Extended config** is built as `rules + extension = config`. This makes it easier to create your own **base config** with full customization. | Extension | Variant | Description | | ----------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------- | | **Base** | Recommended | Adds parser, resolver, and import settings for JavaScript. Disables legacy stylistic JS rules. | | | TypeScript | Adds parser, resolver, and import settings for TypeScript. Also disables JS rules not recommended by the TypeScript team. | | **React** | Recommended | Adds parser, resolver, and import settings for React. Enables required ESLint and stylistic rules. | | | TypeScript | Adds parser, resolver, and import settings for TypeScript. Adjusts specific React rules to work better with TypeScript. | | **Next.js** | Recommended | Disables certain import rules based on Next.js best practices and also turns off React rules that are unnecessary in Next.js projects. | | **Node** | Recommended | Detects if the project uses CommonJS or ESM and adjusts rules accordingly. | ### Example {#extensions-example} ```ts import { extensions } from 'eslint-config-airbnb-extended'; export default [ // Recommended base extension ...extensions.base.recommended, // Recommended Next.js extension ...extensions.next.recommended, ]; ``` --- --- url: /config/extended-config/configs.md --- # Configs {#configs} **Configs** are ready-to-use collections of rule groups combined with extensions. They give you a complete setup out of the box for different environments like **Base**, **React**, **Next.js**, and **Node**. Each config has variants like **recommended**, **typescript**, and **all**, so you can pick exactly what fits your project. ## Base Config {#base-config} | Variant | Description | | --------------- | ------------------------------------------------------------------------------------------------- | | **Recommended** | Includes Base rules (without **Imports Strict**) + the Base Recommended extension. | | **TypeScript** | Includes TypeScript rules (without **TypeScript ESLint Strict**) + the Base TypeScript extension. | | **All** | Combines both Base **Recommended** and **TypeScript** configs. | ### Example {#base-example} ```ts import { configs } from 'eslint-config-airbnb-extended'; export default [ // Base recommended config ...configs.base.recommended, // Base TypeScript config ...configs.base.typescript, ]; ``` ## React Config {#react-config} | Variant | Description | | --------------- | ---------------------------------------------------------------------------------- | | **Recommended** | Includes React rules (without **React Strict**) + the React Recommended extension. | | **TypeScript** | Includes React TypeScript extension. | | **All** | Combines both React **Recommended** and **TypeScript** configs. | ### Example {#react-example} ```ts import { configs } from 'eslint-config-airbnb-extended'; export default [ // React recommended config ...configs.react.recommended, // React TypeScript config ...configs.react.typescript, ]; ``` ## Next.js Config {#nextjs-config} | Variant | Description | | --------------- | ---------------------------------------------------------------------------------- | | **Recommended** | Includes React Recommended config + Next.js rules + Next.js Recommended extension. | | **TypeScript** | Uses the same React TypeScript config. | | **All** | Combines both Next.js **Recommended** and **TypeScript** configs. | ### Example {#nextjs-example} ```ts import { configs } from 'eslint-config-airbnb-extended'; export default [ // Next.js recommended config ...configs.next.recommended, // Next.js TypeScript config ...configs.next.typescript, ]; ``` ## Node Config {#node-config} | Variant | Description | | --------------- | -------------------------------------------------------- | | **Recommended** | Includes Node.js rules + the Node Recommended extension. | ### Example {#node-example} ```ts import { configs } from 'eslint-config-airbnb-extended'; export default [ // Node recommended config ...configs.node.recommended, ]; ``` --- --- url: /config/extended-config/helpers.md --- # Helpers {#helpers} The `helpers` object provides a set of reusable utilities designed to simplify ESLint configuration and reduce duplication across JavaScript and TypeScript setups. These helpers focus on **file extensions**, **development-only file patterns**, and **import resolver settings**, ensuring consistent behavior across different environments and frameworks. | Helper | Purpose | | ------------------------------------ | ---------------------------------------------------- | | `extensions` | Centralized extension & file pattern definitions | | `getDevDepsList` | Dev-only file globs for import rules | | `getImportSettings` | Import resolver & extension settings | | `createAutoTypeScriptImportResolver` | TypeScript resolver with per-file tsconfig discovery | ## extensions {#extensions} A centralized collection of file extensions and glob patterns used across the configuration. * Defines **JavaScript** and **TypeScript** file extensions * Provides **React-aware** extensions (`.jsx`, `.tsx`) * Exposes glob patterns for ESLint targeting * Ensures consistent extension handling across rules, resolvers, and configs ### Example {#extensions-example} ```ts import { helpers } from 'eslint-config-airbnb-extended'; const { jsFiles, tsFiles } = helpers; export default [ { files: [...jsFiles, ...tsFiles], }, ]; ``` ## getDevDepsList(language) {#get-dev-deps-list} Returns a list of glob patterns that should be treated as **development-only files** for ESLint import rules. ```ts type GetDevDepsList = (language: 'javascript' | 'typescript') => string[]; ``` * Generates file patterns for: * Test files * Mocks * Config files (Jest, Vite, Webpack, ESLint, etc.) * Automatically adapts extensions based on the selected language * Helps configure rules like `import-x/no-extraneous-dependencies` ### Example {#get-dev-deps-list-example} ```ts import { helpers } from 'eslint-config-airbnb-extended'; const { getDevDepsList } = helpers; export default [ { rules: { 'import-x/no-extraneous-dependencies': [ 'error', { devDependencies: getDevDepsList('typescript'), }, ], }, }, ]; ``` ## getImportSettings(params) {#get-import-settings} Generates ESLint `settings` for `eslint-plugin-import-x` with proper resolvers and extensions. ```ts import type { TypeScriptResolverOptions } from 'eslint-import-resolver-typescript'; type GetImportSettingsParams = { javascript: boolean; typescript: boolean; jsx: boolean; typescriptResolver?: TypeScriptResolverOptions; }; ``` * Configures **Node** and **TypeScript** import resolvers * Automatically selects extensions based on: * JavaScript vs TypeScript * React / JSX usage * Adds TypeScript-specific parsing and type resolution when enabled * `typescriptResolver` forwards extra options to `eslint-import-resolver-typescript`, merged over the default `{ alwaysTryTypes: true }` ### Example {#get-import-settings-example} ```ts import { getImportSettings } from '@/helpers'; export default [ { settings: getImportSettings({ javascript: false, typescript: true, jsx: true, }), }, ]; ``` ### Monorepo Example {#get-import-settings-monorepo-example} Path aliases are resolved automatically per linted file (see [`createAutoTypeScriptImportResolver`](#create-auto-typescript-import-resolver)), so monorepos need no extra configuration. Use `typescriptResolver` only to pin a package to a specific tsconfig, e.g. a non-standard name or location: ```ts // apps/web/eslint.config.js import { fileURLToPath } from 'node:url'; import { configs, helpers } from 'eslint-config-airbnb-extended'; export default [ ...configs.next.typescript, { settings: helpers.getImportSettings({ javascript: false, typescript: true, jsx: true, typescriptResolver: { project: fileURLToPath(new URL('tsconfig.json', import.meta.url)), }, }), }, ]; ``` ## createAutoTypeScriptImportResolver(options?) {#create-auto-typescript-import-resolver} A drop-in replacement for `createTypeScriptImportResolver` from `eslint-import-resolver-typescript` that picks the `tsconfig.json` **closest to each linted file** instead of relying on the process working directory. All prebuilt configs and `getImportSettings` use it internally, so monorepos work out of the box. ```ts import type { TypeScriptResolverOptions } from 'eslint-import-resolver-typescript'; type CreateAutoTypeScriptImportResolver = (options?: TypeScriptResolverOptions) => NewResolver; ``` * Discovers the nearest `tsconfig.json` per linted file by walking up from the file's directory, and caches one underlying resolver per discovered tsconfig * In monorepos where sibling packages declare the same path alias (e.g. `@/*`), this guarantees imports never resolve across package boundaries — otherwise a single editor ESLint session can resolve one app's alias through another app's tsconfig, producing false `import-x/no-unresolved`, `import-x/extensions`, and `import-x/no-extraneous-dependencies` errors * Files with no `tsconfig.json` anywhere up the tree fall back to the resolver's default behavior, so single-repo setups are unaffected * `options` are forwarded to every underlying resolver, merged over the default `{ alwaysTryTypes: true }` * Passing an explicit `options.project` disables the automatic discovery and behaves exactly like `createTypeScriptImportResolver({ alwaysTryTypes: true, ...options })` ### Example {#create-auto-typescript-import-resolver-example} The prebuilt configs already use this resolver, so reach for it directly only when building custom `import-x` settings: ```ts import { helpers } from 'eslint-config-airbnb-extended'; import { createNodeResolver } from 'eslint-plugin-import-x'; export default [ { settings: { 'import-x/resolver-next': [ createNodeResolver(), helpers.createAutoTypeScriptImportResolver(), ], }, }, ]; ``` --- --- url: /config/legacy-config.md --- # Legacy Config {#legacy-config} The **Legacy Config** is designed for teams who want a **One-To-One/Drop-In Replacement** for the original Airbnb ESLint configs, but with support for **Flat Config** (ESLint 9+). Instead of rewriting rules, this mode focuses on **parity and smooth migration**. If your team already uses: * `eslint-config-airbnb` * `eslint-config-airbnb-base` * `eslint-config-airbnb-typescript` You can switch to `eslint-config-airbnb-extended/legacy` with **minimal diffs** while being future-ready. ## Overview {#overview} The `legacy` entrypoint provides: * **Configs** → Predefined sets of rules that map directly to the Airbnb family. * **Rules** → Core rule groups that enforce good coding practices and are used in configs. This ensures your project setup is familiar, stable, and ESLint 9-ready. ## Configs {#configs} The configs mirror the original Airbnb packages, making migration straightforward. ### 1. For [`eslint-config-airbnb-base`](https://www.npmjs.com/package/eslint-config-airbnb-base) {#for-eslint-config-airbnb-base} Use this if you want **only JavaScript base rules** without React or TypeScript. ::: code-group ```ts [eslint.config.mjs] import { configs } from 'eslint-config-airbnb-extended/legacy'; // Equivalent to airbnb-base/legacy export default [...configs.base.legacy]; // Equivalent to airbnb-base export default [...configs.base.recommended]; ``` ::: ### 2. For [`eslint-config-airbnb`](https://www.npmjs.com/package/eslint-config-airbnb) {#for-eslint-config-airbnb} Use this when working with **React**. It provides a one-to-one mapping with all the standard Airbnb React presets, including `hooks`. ::: code-group ```ts [eslint.config.mjs] import { configs } from 'eslint-config-airbnb-extended/legacy'; // Equivalent to airbnb/legacy export default [...configs.react.legacy]; // Equivalent to airbnb/base export default [...configs.react.base]; // Equivalent to airbnb export default [...configs.react.recommended]; // Equivalent to airbnb/hooks export default [...configs.react.hooks]; ``` ::: ### 3. For [`eslint-config-airbnb-typescript`](https://www.npmjs.com/package/eslint-config-airbnb-typescript) {#for-eslint-config-airbnb-typescript} Use this if you’re on **TypeScript** and want the Airbnb TypeScript rules, but in **Flat Config format** without breaking compatibility. ::: code-group ```ts [eslint.config.mjs] import { configs } from 'eslint-config-airbnb-extended/legacy'; // Equivalent to airbnb-typescript/base export default [...configs.base.typescript]; // Equivalent to airbnb-typescript export default [...configs.react.typescript]; ``` ::: ## Rules {#rules} The `rules` are the building blocks of `configs`. Each config combines these rule groups. ### Base Rules {#base-rules} | Rule Group | Description | | ------------------ | --------------------------------------------------------------------------- | | **Best Practices** | Enforces common best practices to improve code quality and maintainability. | | **Errors** | Helps catch runtime errors and unsafe patterns early. | | **ES6** | Provides rules specific to ES6+ syntax and features. | | **Imports** | Ensures proper import/export usage with `eslint-plugin-import`. | | **Node** | Includes Node.js-specific rules for server-side development. | | **Strict** | Enables strict mode rules. | | **Style** | Covers general code style rules such as spacing, quotes, and semicolons. | | **Variables** | Validates variable declarations, usage, and scoping rules. | ### React Rules {#react-rules} | Rule Group | Description | | --------------------- | ------------------------------------------------------------------- | | **Base** | Core React rules for JSX and component structure. | | **JSX Accessibility** | Accessibility rules via `eslint-plugin-jsx-a11y` for inclusive UIs. | | **Hooks** | Rules from `eslint-plugin-react-hooks` ensuring proper hook usage. | ### TypeScript Rules {#typescript-rules} | Rule Group | Description | | ------------- | ---------------------------------------------------------------------------------------------------------- | | **Base** | Core TypeScript linting rules for types, syntax, and consistency. | | **Overrides** | Adjusts ESLint by disabling rules covered by TypeScript and enabling ones that benefit from type-checking. | | **Settings** | Additional config values for TypeScript resolver and parser options. | ## Why Legacy Config Exists {#why-legacy-config-exists} * **1:1 replacements** → drop-in equivalents of Airbnb configs. * **Flat Config ready** → works with ESLint 9 and beyond. * **Migration path** → lets you start simple, then move to `extended` or `strict` configs later. * **Less churn** → developers see fewer rule changes when upgrading. If you’re upgrading a project that **already relies on Airbnb configs**, start with **Legacy Config** to make the transition safe and low-friction. Once you’re stable, you can move on to **Extended** (modernized rules) or even **Strict Mode** for maximum consistency. --- --- url: /config/extended-vs-legacy.md --- # Extended vs Legacy {#extended-vs-legacy} `eslint-config-airbnb-extended` ships in two flavors. Both are **flat-config only** (no `.eslintrc*`) and work great with TypeScript, what differs is their philosophy and how opinionated they are. ::: tip NOTE This package doesn’t support `.eslintrc*`. If you’re still on legacy config files, migrate to `eslint.config.mjs` first. See [migration guide](../migration/upgrade-to-extended) for detailed information. ::: ## Overview {#overview} | Aspect | **Extended** | **Legacy** | | ---------- | ---------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | Purpose | Modern, TypeScript-first, opinionated defaults for new and existing codebases | Provide **drop-in replacement** of the original Airbnb ESLint configurations using the new flat config format. | | Strictness | Tighter defaults out of the box, pairs nicely with the optional **Strict Rules** add-on | Conservative defaults, easier drop-in when migrating from old Airbnb configs | | TypeScript | Fully supported, encourages TS-aware patterns | Fully supported, fewer extra opinions | | Imports | Uses `eslint-plugin-import-x` (faster fork of `eslint-plugin-import`) for modern import checks | Uses `eslint-plugin-import` to keep migration noise low | | Styling | Uses **ESLint Stylistic** for formatting-style rules you can autofix and tune | Uses `deprecated` ESLint styling rules for easy migration | | Best for | Teams who want a maintained, modernized successor to Airbnb with sensible opinions | Teams moving from `airbnb`, `airbnb-base`, or `airbnb-typescript` configs who want to keep the same behavior initially and improve gradually. | ## Which one should I choose? {#which-one-i-choose} Choose **Extended** if you: * are starting fresh or ready to modernize, * looking for TypeScript-aware checks along with a cleaner, more consistent import and style setup, * plan to enable the **Strict Rules** bundle later for even tighter consistency. Choose **Legacy** if you: * are migrating from `airbnb`, `airbnb-base`, or `airbnb-typescript` configs and want minimal diffs first, * have a large codebase and prefer a gentler, low-friction transition path, * plan to adopt the Extended (or Strict rules) opinions gradually after migration. --- --- url: /config/packages-used.md --- # Packages Used {#packages-used} This configuration relies on a set of essential ESLint plugins that extend Airbnb’s base rules to support **TypeScript, React, Node.js, accessibility, and import handling**. ## Quick Overview {#overview} | Package | Purpose | Key Benefits | | ------------------------------------------------------------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------- | | **[@stylistic/eslint-plugin](https://eslint.style)** | Styling & formatting rules | Ensures consistent code style (spacing, quotes, semicolons, indentation) directly in ESLint | | **[eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x)** | Import/export validation | Detects invalid imports, enforces ordering, supports TypeScript better than legacy `eslint-plugin-import` | | **[eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n)** | Node.js best practices | Prevents use of deprecated APIs, enforces modern Node.js coding standards | | **[eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react)** | React-specific linting | Catches JSX errors, enforces prop validation, encourages React best practices | | **[eslint-plugin-react-hooks](https://www.npmjs.com/package/eslint-plugin-react-hooks)** | Rules of Hooks | Ensures hooks are used correctly and dependencies are properly declared | | **[eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y)** | Accessibility for JSX | Detects missing `alt` text, incorrect ARIA attributes, improves WCAG compliance | | **[@next/eslint-plugin-next](https://nextjs.org/docs/app/api-reference/config/eslint)** | Next.js-specific linting | Enforces Next.js best practices, catches common issues, and ensures consistency with official standards | | **[@typescript-eslint](https://typescript-eslint.io)** | TypeScript linting support | Adds type-aware rules, catches unsafe patterns, integrates TS with Airbnb config | | **[eslint-import-resolver-typescript](https://github.com/import-js/eslint-import-resolver-typescript)** | TS import resolution | Supports `tsconfig.json` path aliases, prevents false-positive import errors | ## Detailed Explanation {#detailed-explanation} ### 1. @stylistic/eslint-plugin {#stylistic-eslint-plugin} Provides fine-grained styling and formatting rules, covering details like spacing, quotes, indentation, and semicolons. This ensures consistent formatting across JavaScript and TypeScript files without relying on an external formatter. ### 2. eslint-plugin-import-x {#eslint-plugin-import-x} A modern fork of `eslint-plugin-import` with better TypeScript support and performance. It validates import/export syntax, detects duplicate or invalid imports, and enforces consistent ordering and grouping. ### 3. eslint-plugin-n {#eslint-plugin-n} Focuses on Node.js best practices. It warns about deprecated APIs, incorrect callback usage, and ensures compatibility with the Node.js version defined in your project. ### 4. eslint-plugin-react {#eslint-plugin-react} Linting rules tailored for React. It ensures JSX is valid, encourages best practices in both functional and class components, and enforces prop validation to prevent runtime issues. ### 5. eslint-plugin-react-hooks {#eslint-plugin-react-hooks} Enforces React’s official **Rules of Hooks**. It prevents invalid hook usage (like calling hooks in loops or conditions) and ensures dependencies in hooks like `useEffect` are declared correctly. ### 6. eslint-plugin-jsx-a11y {#eslint-plugin-jsx-a11y} Improves accessibility in React apps. It detects missing `alt` text on images, incorrect ARIA attributes, and highlights accessibility issues in JSX to help create inclusive apps. ### 7. @next/eslint-plugin-next {#eslint-plugin-next} Enforces Next.js best practices and catches common issues with images, head, and scripts. It also promotes performance optimizations and keeps your project consistent with official Next.js standards. ### 8. @typescript-eslint {#typescript-eslint} Provides ESLint support for TypeScript. It integrates with the type system to catch unsafe patterns, unused variables, and improves type safety while working seamlessly with Airbnb’s base rules. ### 9. eslint-import-resolver-typescript {#eslint-import-resolver-typescript} Extends `eslint-plugin-import-x` to resolve TypeScript path aliases defined in `tsconfig.json`. Helps prevent false positives when working with custom alias-based imports. ## Why These Packages Together? {#why-packages-together} By combining these packages, `eslint-config-airbnb-extended` achieves: * Consistent **code style** across JavaScript & TypeScript (`@stylistic/eslint-plugin`). * Safe and reliable **imports** (`eslint-plugin-import-x`, `eslint-import-resolver-typescript`). * Strong **Node.js rules** (`eslint-plugin-n`). * Best practices for **React & Hooks** (`eslint-plugin-react`, `eslint-plugin-react-hooks`). * Improved **accessibility** (`eslint-plugin-jsx-a11y`). * Enforces framework-specific best practices (`@next/eslint-plugin-next`) * Full **TypeScript integration** (`typescript-eslint`). --- --- url: /config/faq.md --- # FAQ {#faq} Here are some of the most common questions and clarifications about using `eslint-config-airbnb-extended`. This section will help you understand differences, setup tips, and design decisions behind the package. ## 1. Does this package support `.eslintrc` configs? {#legacy-support} No. This package is designed exclusively for the **Flat Config system** introduced in ESLint 9. The legacy `.eslintrc` format is now **deprecated** and will not receive further updates or improvements. If your project still depends on `.eslintrc`, we recommend continuing with the older Airbnb packages, see [Note](../guide/getting-started#note). If you’d like to migrate to the Flat Config format instead, follow our [Migration Guide](../migration/upgrade-to-extended). ## 2. Difference between Extended vs Legacy Config {#extended-vs-legacy} See the detailed comparison [here](./extended-vs-legacy). ## 3. How to Configure for a Monorepo? {#configure-monorepo} Monorepo setups often include multiple apps or packages under a single repository. ESLint configuration can be tricky in such environments. Here are your options: 1. **Install per package** – Run the installation command inside each sub-folder (e.g., `/apps/web`, `/apps/api`) where you want to apply the config. This keeps things isolated and easy to manage. 2. **Install once at the root** – Alternatively, you can install the config at the root of the repo and share it across packages. In this case, you’ll need to customize the `eslint.config.mjs` file to include overrides for different folders. ::: tip If you skip the the package installation in the CLI, the CLI will generate a set of ready-to-use commands based on your selection, so you can copy-paste and adapt them to your monorepo’s structure. ::: ## 4. Why did we switch from `import` to `import-x`? {#import-vs-import-x} We moved from [`eslint-plugin-import`](https://www.npmjs.com/package/eslint-plugin-import) to [`eslint-plugin-import-x`](https://www.npmjs.com/package/eslint-plugin-import-x) because it is a **superior, modern alternative**. Key reasons: * **Better TypeScript support** – Provides more accurate and reliable linting for TS files. * **Actively maintained** – Frequent updates and bug fixes, unlike the original `import` plugin which is less active. * **Fewer open issues** – More stable and trustworthy in production projects. * **Performance improvements** – Lightweight and optimized for faster linting. In short, `import-x` is the **community-recommended successor** to `import` and ensures your project stays future-proof. ## 5. Why are `plugins` separated from the `config` in this package? {#why-separated-plugins} If you’ve ever used multiple ESLint configs together, you may have run into this frustrating error: ::: danger Error Config "package": Key "plugins": Cannot redefine plugin "key". ::: This happens because ESLint doesn’t allow multiple configs to define the same plugin name. If shared configs **bundle plugins inside them**, conflicts are unavoidable. To solve this, **our package separates the plugin definitions**: * The config focuses only on **rules and settings**. * The plugins are exported separately via the `plugins` export. This design has several **benefits**: * No plugin redefinition errors when combining configs. * Works seamlessly with other ESLint configs (official or community). * Gives developers flexibility: import only the plugins you need. For more details on the plugins used, refer to [Packages Used](./packages-used). --- --- url: /cli/guide.md --- # CLI {#cli} The `create-airbnb-x-config` tool helps you quickly scaffold an **ESLint configuration** based on the `eslint-config-airbnb-extended` presets. It guides you through a series of prompts and generates a ready-to-use config tailored to your project. ## Installation {#installation} You don’t need to install this tool globally. Just run it directly inside your project: ::: code-group ```sh [npm] $ npx create-airbnb-x-config ``` ```sh [yarn] $ yarn dlx create-airbnb-x-config ``` ```sh [pnpm] $ pnpx create-airbnb-x-config ``` ```sh [bun] $ bunx create-airbnb-x-config ``` ::: ## Guide {#guide} When you run the CLI, it will guide you through several prompts to build the right ESLint setup. Here’s what each step means: *** ### 1. Config Type {#config-type} Choose the style of configuration you want: * **Legacy →** A drop-in replacement for the original Airbnb ESLint configs, but in the new flat config format. * **Extended →** A modern, TypeScript-friendly setup with opinionated defaults for both new and existing projects. *** ### 2. Are you using TypeScript? {#are-you-using-typescript} * **Yes →** Adds TypeScript-related configs and plugins like `typescript-eslint` and `eslint-import-resolver-typescript`. * **No →** Keeps the setup for plain JavaScript only. *** ### 3. Are you using Prettier? {#are-you-using-prettier} * **Yes →** Integrates Prettier with `eslint-plugin-prettier` and `eslint-config-prettier` so formatting works directly in ESLint. * **No →** Skips Prettier integration. *** ### Extended Config Prompts {#extended-prompts} If you selected **Extended**, The CLI will **automatically include** `@stylistic/eslint-plugin` and `eslint-plugin-import-x`. The following questions apply only to **Extended** configs. #### 4. Are you using? {#are-you-using-extended} * **React/React Router →** Enables React-specific linting with support for hooks and accessibility rules, ensuring your React code follows best practices. It installs `eslint-plugin-react`, `eslint-plugin-react-hooks`, and `eslint-plugin-jsx-a11y`. * **Next.js →** Extends the React setup with additional Next.js rules to catch framework-specific issues. It installs everything from React plus `@next/eslint-plugin-next`. * **Node →** Adds Node.js-focused rules that enforce best practices and catch common issues in server-side code. It installs `eslint-plugin-n`. #### 5. Do you want to add strict configs? {#add-strict-configs} * **Yes →** You’ll be prompted to select which strict rule sets to apply: **Import**, **React**, or **TypeScript**. * **No →** Keeps the default balanced configuration without strict rules. *** ### Legacy Config Prompts {#legacy-prompts} If you selected **Legacy**, The CLI will **automatically include** `eslint-plugin-import`. The following questions apply only to **Legacy** configs. #### 4. Are you using? {#are-you-using-legacy} * **Base Config →** Installs `eslint-plugin-import` to handle module import/export rules and best practices. Use this if you only need a minimal setup without React-specific rules. * **React Config →** Installs `eslint-plugin-react` and `eslint-plugin-jsx-a11y` to enforce React best practices and accessibility checks. Recommended if your project uses React for UI development. #### 5. Are you using hooks? {#are-you-using-hooks} * **Yes →** Installs `eslint-plugin-react-hooks` to enforce the rules of React hooks. * **No →** Skips installing hook rules. Choose this if your React project doesn’t use hooks. *** ### Final Common Prompts {#final-prompts} No matter which config type you choose, the CLI will end with these questions: #### 6. Should I create an `eslint.config.mjs` file for you? {#create-eslint-config-mjs} * **Yes →** Generates a ready-to-use config file based on your answers. At the end, you’ll also get a link labeled **Created Config** showing the template used. * **No →** You’ll need to create it manually. A link labeled **Config** will be shown at the end with the template you can copy. #### 7. Do you want to skip the package installation? {#skip-package-installation} * **Yes →** Skips auto-installation. At the end, you’ll see a list of **Commands** you can run manually. * **No →** Automatically installs everything for you. At the end, you’ll also see the **Executed Commands** for reference. Here’s a polished rephrase in simpler, user-friendly language: ## Example Output {#example-output} Once you finish answering the prompts, the CLI will show you a **ready-to-run command** that installs all the required dependencies using your preferred package manager. Example installation command: ::: code-group ```sh [npm] $ npm install -D eslint @eslint/compat @eslint/js eslint-config-airbnb-extended ``` ```sh [yarn] $ yarn add -D eslint @eslint/compat @eslint/js eslint-config-airbnb-extended ``` ```sh [pnpm] $ pnpm install -D eslint @eslint/compat @eslint/js eslint-config-airbnb-extended ``` ```sh [bun] $ bun add -D eslint @eslint/compat @eslint/js eslint-config-airbnb-extended ``` ::: Example config file: ```txt https://github.com/eslint-config/airbnb-extended/tree/master/apps/build-templates/templates/legacy/base/prettier/ts/default/eslint.config.mjs ``` ## Optional Steps {#optional-steps} 1. Run the installation command if you didn’t skip dependency installation. 2. Check that `eslint.config.mjs` is created in your project’s root folder. 3. Add useful scripts in your `package.json` for quick linting: ::: code-group ```json [package.json] { "scripts": { "lint": "eslint .", "lint:fix": "eslint . --fix" } } ``` ::: --- --- url: /cli/options.md --- # Setup {#setup} When you run the CLI, it launches an **interactive wizard**. You’ll be asked a series of questions, for example: ```sh ✔ Are you using TypeScript? … No / Yes ``` Each answer updates the final ESLint setup for your project. If you prefer to skip the questions, you can pass **command-line options** to configure everything in one step: ::: code-group ```sh [npm] $ npx create-airbnb-x-config --lang typescript --runtime react --pm npm ``` ```sh [yarn] $ yarn dlx create-airbnb-x-config --lang typescript --runtime react --pm yarn ``` ```sh [pnpm] $ pnpx create-airbnb-x-config --lang typescript --runtime react --pm pnpm ``` ```sh [bun] $ bunx create-airbnb-x-config --lang typescript --runtime react --pm bun ``` ::: This example sets up ESLint with TypeScript + React rules and installs dependencies using pnpm. ## Options {#options} Here’s the full list of options you can use: ### General {#general} * `-v, --version` → Show the current CLI version. * `-h, --help` → Display help info. ### Config {#config} The following values are available for `--config`: * `extended` → Use **extended configuration** (modern, TypeScript-first, opinionated defaults). * `legacy` → Use **legacy configuration** (1:1 Airbnb replacement in flat config). ### Language {#language} The following values are available for `--lang`: * `typescript` → Setup for a **TypeScript** project. * `javascript` → Setup for a **JavaScript** project. ### Formatter {#formatter} The following values are available for `--formatter`: * `prettier` → Add Prettier integration (`eslint-plugin-prettier`, `eslint-config-prettier`). * `none` → No formatter integration (keeps ESLint setup without Prettier). ### Runtime {#runtime} The following values are available for `--runtime`: * `react` → Add React rules (`eslint-plugin-react`, `eslint-plugin-react-hooks`, and `eslint-plugin-jsx-a11y`). * `remix` → Same as `react` runtime rules. * `react-router` → Same as `react` runtime rules. * `next` → Add Next.js rules (`@next/eslint-plugin-next`). * `node` → Add Node.js rules (`eslint-plugin-n`). ### Strict Rules {#strict-rules} The following values are available for `--strict`: * `import` → Enable **strict Import** rules. * `react` → Enable **strict React** rules. * `typescript` → Enable **strict TypeScript** rules. * `none` → No strict configurations are applied. ### Legacy Config Variants {#legacy-configs} The following values are available for `--legacy`: * `base` → Legacy Base config. * `react` → Legacy React config. * `react-hooks` → Legacy React Hooks config. ### Package Managers {#package-managers} The following values are available for `--pm`: * `npm` → Use npm for installs. * `yarn` → Use Yarn for installs. * `pnpm` → Use pnpm for installs. * `bun` → Use Bun for installs. ### File & Install Options {#file-install-options} * `--create-eslint-file` → Generate `eslint.config.mjs` automatically. * `--skip-install` → Skip dependency installation (you’ll need to install them manually). ## Why use Options instead of Interactive Prompts? {#why-options} While the **interactive mode** is great for first-time setup (because it guides you step by step), the **options (flags)** are better when: 1. **Speed** → You can skip all prompts and generate a config instantly with a single command. 2. **Consistency** → Perfect for teams/projects where everyone should use the same ESLint setup without relying on different answers in prompts. 3. **Automation** → Options can be used in scripts, CI pipelines, or project generators (like `create-*` tools) to auto-generate ESLint configs. 4. **Repeatability** → If you’re setting up multiple projects, you don’t need to click through prompts each time, just reuse the same command. 5. **Customization** → Options give you more fine-grained control (e.g., picking strict configs, skipping install, forcing a package manager) without extra steps. ::: tip Interactive mode is great for learning and trying things out. Options are great for speed, automation, and team-wide consistency. ::: --- --- url: /customization/strict-rules.md --- # Strict Rules {#strict-rules} The `eslint-config-airbnb-extended` package comes with a set of **stricter ESLint rules** for `Imports`, `React`, and `TypeScript` that go beyond the default configuration. By default, these rules are **not enabled**, so you can choose whether your project needs them. They are best suited for teams that want **maximum consistency, fewer edge-case bugs, and stronger guarantees** around code quality. ## How to Enable Strict Rules {#enable-strict-rules} To enable strict rules, import them directly from the package: ::: code-group ```ts [eslint.config.mjs] import { rules } from 'eslint-config-airbnb-extended'; ``` ::: Then extend them in your ESLint configuration file (`eslint.config.mjs`): ::: code-group ```ts [eslint.config.mjs] export default [ // Your existing configs rules.base.importsStrict, rules.react.strict, rules.typescript.typescriptEslintStrict, ]; ``` ::: This setup ensures that the strict rules are applied on top of your current configuration, without losing flexibility to override them later. ## What Do These Strict Rules Include? {#what-strict-rules-include} #### 1. Strict Imports {#strict-imports-rules} These rules are designed to keep your imports **organized, efficient, and predictable**. Key features include: * Enforcing a consistent and logical import order (e.g., external → internal → local modules). * Differentiating clearly between **type imports** (`import type`) and **value imports**. * Preventing duplicate imports or unnecessary re-exports. * Detecting unresolved imports earlier. * and many more... This ensures your codebase remains **clean and easy to navigate**, even as it scales. *** #### 2. Strict React {#strict-react-rules} These rules ensure React code stays **readable, predictable, and TypeScript-friendly**. Key features include: * Enforcing `key` props on list-rendered elements to prevent rendering bugs. * Sorting JSX props for consistent readability across components. * Disabling `prop-types` since TypeScript provides stronger typing guarantees. * and many more... This results in **more consistent React components** and fewer runtime issues. *** #### 3. Strict TypeScript ESLint {#strict-typescript-rules} These rules encourage **best practices in TypeScript** and protect against unsafe patterns. Key features include: * Disallowing `@ts-ignore` in favor of `@ts-expect-error`, making ignored errors intentional and visible. * Banning the use of `any` to maintain strict typing guarantees. * Disallowing non-null assertions (`!`) that can hide potential runtime errors. * Encouraging modern TypeScript features like the **Nullish Coalescing Operator (`??`)** and **Optional Chaining (`?.`)**. * and many more... This keeps your TypeScript code **robust, maintainable, and future-proof**. ## When To Use Strict Rules? {#when-to-use-strict-rules} Strict Rules is **ideal for teams or projects** that: * Want maximum consistency across the codebase. * Need stricter guarantees around type safety and React usage. * Prefer a **"lint-first, catch bugs early"** development philosophy. If your team values flexibility and faster prototyping, the default configuration may be sufficient. But if your goal is **production-grade reliability and long-term maintainability**, enabling Strict Rules is highly recommended. --- --- url: /migration/upgrade-to-v3.md --- # Upgrade to v3 {#upgrade-to-v3} Version **v3** is the biggest upgrade so far, introducing several long-awaited improvements and structural changes. ### What’s new in v3 * **Significantly smaller package** - the new version reduces the unpacked size by ~72% compared to the previous release * **Node.js v16 support dropped** - v3 requires **Node 18.18 or higher** * **ESM-only architecture** - the entire package now uses native ES modules * **All batteries included** - everything you need ships out of the box * **Redesigned CLI options** - aligned with clearer, more explicit configurations * **Updated dependencies** - all packages are upgraded to their latest stable versions …and much much more ### Repository migration As part of this release, the project has moved from a **personal repository** to a dedicated **organization repository**: * From: * To: This change ensures better long-term maintenance and community collaboration. ## Config {#config} * **The config is now ESM-only** - You must use an environment that supports **native ES modules** to run the config. * **Node.js v16 support dropped** - v3 requires **Node 18.18 or higher**. * **Introduced helper utilities** - For more details, see the [docs](../config/extended-config/helpers) * **Batteries included** - All required ESLint plugins and resolvers are bundled internally, so no additional plugins are needed. You only need to install: * `eslint` * `eslint-config-airbnb-extended` You should **remove** the following packages if they are already installed, as they are now included by default: * `@next/eslint-plugin-next` * `@stylistic/eslint-plugin` * `eslint-import-resolver-typescript` * `eslint-plugin-import-x` * `eslint-plugin-jsx-a11y` * `eslint-plugin-react` * `eslint-plugin-react-hooks` * `typescript-eslint` * `eslint-plugin-n` * `eslint-plugin-import` (legacy) ::: code-group ```sh [npm] $ npm uninstall @next/eslint-plugin-next @stylistic/eslint-plugin eslint-import-resolver-typescript eslint-plugin-import-x eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks typescript-eslint eslint-plugin-n eslint-plugin-import ``` ```sh [yarn] $ yarn remove @next/eslint-plugin-next @stylistic/eslint-plugin eslint-import-resolver-typescript eslint-plugin-import-x eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks typescript-eslint eslint-plugin-n eslint-plugin-import ``` ```sh [pnpm] $ pnpm remove @next/eslint-plugin-next @stylistic/eslint-plugin eslint-import-resolver-typescript eslint-plugin-import-x eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks typescript-eslint eslint-plugin-n eslint-plugin-import ``` ```sh [bun] $ bun remove @next/eslint-plugin-next @stylistic/eslint-plugin eslint-import-resolver-typescript eslint-plugin-import-x eslint-plugin-jsx-a11y eslint-plugin-react eslint-plugin-react-hooks typescript-eslint eslint-plugin-n eslint-plugin-import ``` ::: ## CLI {#cli} * **CLI is now ESM-only** - You must run the CLI in an environment that supports **native ES modules**. * **Node.js v16 support dropped** - v3 requires **Node 18.18 or higher**. * **Redesigned CLI options** - Many flags have been renamed or restructured for better consistency. ### CLI Options {#cli-options} Refer to the table to update your existing scripts or commands. | Category | Old Command | New Command | | -------------------------- | ----------------------------- | ------------------------ | | **Config Type** | `--extended` | `--config extended` | | | `--legacy` | `--config legacy` | | **Language** | `--ts`, `--typescript` | `--lang typescript` | | | `--js`, `--javascript` | `--lang javascript` | | **Prettier** | `--prettier` | `--formatter prettier` | | **Frameworks & Runtimes** | `--react` | `--runtime react` | | | `--react-router` | `--runtime react-router` | | | `--remix` | `--runtime remix` | | | `--next` | `--runtime next` | | | `--node` | `--runtime node` | | **Strict Rules** | `--strict-import-config` | `--strict import` | | | `--strict-react-config` | `--strict react` | | | `--strict-typescript-config` | `--strict typescript` | | **Legacy Config Variants** | `--legacy-base-config` | `--legacy base` | | | `--legacy-react-config` | `--legacy react` | | | `--legacy-react-hooks-config` | `--legacy react-hooks` | | **Package Managers** | `--use-npm` | `--pm npm` | | | `--use-yarn` | `--pm yarn` | | | `--use-pnpm` | `--pm pnpm` | | | `--use-bun` | `--pm bun` | --- --- url: /migration/upgrade-to-extended.md --- # Migration Guide {#migration} Migrating from the old Airbnb ESLint configs to **eslint-config-airbnb-extended** is straightforward, but there are a few key changes you need to be aware of, especially around ESLint’s new **Flat Config** system. Follow these steps to safely migrate your project. ## 1. Uninstall Old Packages {#uninstall-old-packages} Remove the following legacy Airbnb packages from your `package.json`: * `eslint-config-airbnb-base` * `eslint-config-airbnb` * `eslint-config-airbnb-typescript` You no longer need them, as `eslint-config-airbnb-extended` consolidates all of their functionality into a single modern config. ::: code-group ```sh [npm] $ npm uninstall eslint-config-airbnb-base eslint-config-airbnb eslint-config-airbnb-typescript ``` ```sh [yarn] $ yarn remove eslint-config-airbnb-base eslint-config-airbnb eslint-config-airbnb-typescript ``` ```sh [pnpm] $ pnpm remove eslint-config-airbnb-base eslint-config-airbnb eslint-config-airbnb-typescript ``` ```sh [bun] $ bun remove eslint-config-airbnb-base eslint-config-airbnb eslint-config-airbnb-typescript ``` ::: ## 2. Migrate to Flat Config {#migrate-flat-config} The extended config works **only with ESLint’s Flat Config system**. This means you cannot use legacy `.eslintrc.*` files anymore. Instead, your project root will use `eslint.config.mjs`. If you're still using `.eslintrc`, follow ESLint’s official [migration guide](https://eslint.org/docs/latest/use/configure/migration-guide) and ESLint’s blog posts on the new config system [Part 1](https://eslint.org/blog/2022/08/new-config-system-part-1/) and [Part 2](https://eslint.org/blog/2022/08/new-config-system-part-2/). ## 3. Follow Installation Steps {#follow-installation-steps} Once your project is ready for Flat Config, Follow the [installation steps](../config/installation) to add the new config to your project. ## 4. Update `import/*` Rules {#update-rules} One important change in this package is the switch from the `import/*` rules to `import-x/*`. ::: code-group ```js [eslint.config.mjs] "import/no-unresolved": "off" // [!code --] "import-x/no-unresolved": "off" // [!code ++] ``` ::: Why the change? See the explanation [here](../config/faq#faq). ## 5. Verify and Clean Up {#verify-clean-up} Once migration is complete: * Run `eslint .` and check that the linter works without errors. * Remove any unused ESLint-related dependencies that may still be lingering. * Commit your changes so the whole team benefits from the new setup. ## All Done! {#all-done} Your project is now using the **modern, TypeScript-ready Airbnb Extended config** with ESLint 9+. Enjoy a cleaner, more consistent codebase without the hassle of outdated configs! --- --- url: /contribute/guide.md --- # Contributing {#contributing} Thank you for considering contributing to `eslint-config-airbnb-extended`. We welcome all contributions, whether it’s fixing a bug, improving documentation, or suggesting new rules. ## How to Contribute {#how-to-contribute} ### 1. Fork & Clone the Repository {#for-clone-repository} ::: code-group ```sh [SSH] $ git clone git@github.com:eslint-config/airbnb-extended.git $ cd eslint-config-airbnb-extended ``` ```sh [HTTPS] $ git clone https://github.com/eslint-config/airbnb-extended.git $ cd eslint-config-airbnb-extended ``` ::: ### 2. Install Dependencies {#install-dependencies} Check the `.nvmrc` file for the required Node.js version. For `pnpm` version, see the `packageManager` field in the root `package.json`. This project is a **monorepo** managed with **pnpm**. Install dependencies with: ```sh $ pnpm install ``` ### 3. Project Structure {#project-structure} The repo is organized as a monorepo with two main packages: * `packages/eslint-config-airbnb-extended` → The ESLint configuration package * `packages/create-airbnb-x-config` → The CLI tool for quick setup * `docs/` → Documentation site (built with VitePress) ### 4. Making Changes {#making-changes} * Always create a new branch: ```sh $ git checkout -b fix/your-change ``` * For rule changes → update the config. * For docs → check formatting and verify links. ### 5. Linting & Formatting {#linting-formatting} Run checks and fixes before committing: ::: code-group ```sh [Check] $ pnpm lint $ pnpm format ``` ```sh [Fix] $ pnpm lint:fix $ pnpm format:fix ``` ::: ### 6. Commit Guidelines {#commit-guidelines} We follow **Conventional Commits** for a clean commit history. Examples: * `feat: add strict rules for TypeScript` * `fix: resolve path alias issue in eslint-import-resolver-typescript` * `docs: update installation steps` ### 7. Running Scripts {#running-scripts} Before pushing, ensure all scripts pass: ```sh $ pnpm script:lint ``` ### 8. Submitting a PR {#submitting-pr} * Push your branch and open a Pull Request against `canary`. * Clearly describe the problem, your solution, and reference any related issues/discussions. * Maintainers will review, suggest improvements if needed, and merge once approved. ## Code of Conduct {#code-of-conduct} This project follows a [**Code of Conduct**](https://github.com/eslint-config/airbnb-extended/blob/master/CODE_OF_CONDUCT.md). Please be respectful, collaborative, and inclusive. ## Suggestions & Issues {#suggestions-issues} * Found a bug? → [Open an Issue](https://github.com/eslint-config/airbnb-extended/issues/new/choose) * Want a new feature or rule? → Use the same link to create an issue, or start a discussion before opening a PR. --- --- url: /README.md --- # @airbnb-extended/docs Eslint Airbnb Extended Documentation