# @wordpress/eslint-plugin

> ESLint plugin for WordPress development.

Latest version **28.1.0** (published 2026-11-04) · GPL-2.0-or-later license · 0 weekly downloads

## Install

```sh
npm install @wordpress/eslint-plugin
pnpm add @wordpress/eslint-plugin
yarn add @wordpress/eslint-plugin
bun add @wordpress/eslint-plugin
```

## Health

**Score 65/100 (B)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score; popular repo.

Warnings: low downloads; no types.

## Facts

| | |
|---|---|
| Version | 28.1.0 |
| Published | 2026-11-04 |
| First published | 2018-12-12 |
| Weekly downloads | 0 |
| License | GPL-2.0-or-later |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Node | >=22.13.0 |
| Dependencies | 18 |
| Unpacked size | 300.2 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 11780 |
| Author | The WordPress Contributors |
| Maintainers | garypendergast, adamsilverstein, gziolo, ntwb, riad, noisysocks, kadamwhite, gutenbergplugin, jorgefilipecosta, ellatrix, iandunn206, whyisjake, ockham, sirreal, nosolosw, wpisabel, ntsekouras, nerrad, desrosj, talldanwp, peterwilsoncc, ryanwelcher, mamaduka, aduth, johnbillion |
| Keywords | wordpress, gutenberg, eslint, plugin |

## Links

- npm: https://www.npmjs.com/package/@wordpress/eslint-plugin
- Repository: https://github.com/WordPress/gutenberg
- Homepage: https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/README.md
- Issues: https://github.com/WordPress/gutenberg/issues
- npm.io page: https://npm.io/package/@wordpress/eslint-plugin

## Dependencies (18)

- [globals](https://npm.io/package/globals.md) ^16.0.0
- [cosmiconfig](https://npm.io/package/cosmiconfig.md) ^7.0.0
- [requireindex](https://npm.io/package/requireindex.md) ^1.2.0
- [@eslint/compat](https://npm.io/package/@eslint/compat.md) ^2.0.0
- [@wordpress/theme](https://npm.io/package/@wordpress/theme.md) ^4.0.0
- [typescript-eslint](https://npm.io/package/typescript-eslint.md) ^8.70.1
- [eslint-plugin-jest](https://npm.io/package/eslint-plugin-jest.md) ^29.16.5
- [eslint-plugin-jsdoc](https://npm.io/package/eslint-plugin-jsdoc.md) ^64.0.0
- [eslint-plugin-react](https://npm.io/package/eslint-plugin-react.md) ^7.37.0
- [eslint-plugin-import](https://npm.io/package/eslint-plugin-import.md) ^2.32.0
- [@vitest/eslint-plugin](https://npm.io/package/@vitest/eslint-plugin.md) ^1.6.27
- [eslint-config-prettier](https://npm.io/package/eslint-config-prettier.md) ^10.0.0
- [eslint-plugin-jsx-a11y](https://npm.io/package/eslint-plugin-jsx-a11y.md) ^6.10.0
- [eslint-plugin-prettier](https://npm.io/package/eslint-plugin-prettier.md) ^5.5.5
- [eslint-plugin-playwright](https://npm.io/package/eslint-plugin-playwright.md) ^2.1.0
- [eslint-plugin-react-hooks](https://npm.io/package/eslint-plugin-react-hooks.md) ^7.1.1
- [@wordpress/prettier-config](https://npm.io/package/@wordpress/prettier-config.md) ^5.1.0
- [eslint-import-resolver-typescript](https://npm.io/package/eslint-import-resolver-typescript.md) ^4.4.4

## Alternatives

- [eslint-plugin-sonarjs](https://npm.io/package/eslint-plugin-sonarjs.md) — 2.9M weekly downloads
- [eslint-config-expo](https://npm.io/package/eslint-config-expo.md) — 1.5M weekly downloads
- [@matter/protocol](https://npm.io/package/@matter/protocol.md) — 63.5K weekly downloads
- [@eventcatalog/linter](https://npm.io/package/@eventcatalog/linter.md) — 24.8K weekly downloads
- [@pandacss/eslint-plugin](https://npm.io/package/@pandacss/eslint-plugin.md) — 18.7K weekly downloads

## Recent versions

- 28.1.0 (latest) — 2026-11-04
- 27.0.1-next.v.202609171837.0 (next) — 2026-09-17
- 24.2.1 (wp-7.0) — 2026-06-30
- 22.19.1 (wp-6.9) — 2025-10-28
- 22.5.1 (wp-6.8) — 2025-03-10
- 21.1.2 (wp-6.7) — 2024-09-19
- 19.0.1 (wp-6.6) — 2024-06-11
- 17.8.1 (wp-6.5) — 2024-02-20
- 16.0.13 (wp-6.4) — 2023-11-13
- 14.8.2 (wp-6.3) — 2023-10-12
- 13.10.4 (wp-6.2) — 2023-10-12
- 13.1.1 (wp-6.1) — 2022-09-20
- 12.0.1 (wp-6.0) — 2022-04-19
- 9.3.0 (wp-5.9) — 2021-11-15
- 9.0.6 (wp-5.8) — 2021-05-31
- … 247 more at https://npm.io/package/@wordpress/eslint-plugin/versions

## README

# ESLint Plugin

[ESLint](https://eslint.org/) plugin including configurations and custom rules for WordPress development.

## Installation

Install the module

```bash
npm install @wordpress/eslint-plugin --save-dev
```

**Note**: This package requires Node.js version with long-term support status (check [Active LTS or Maintenance LTS releases](https://nodejs.org/en/about/previous-releases)). It is not compatible with older versions.

## Usage

**Minimum ESLint version:** `^9.0.0 || ^10.0.0`

> **Upgrading from an older version?** See the [ESLint v10 migration guide](https://github.com/WordPress/gutenberg/blob/HEAD/docs/how-to-guides/eslint-v10-migration.md) for a comprehensive walkthrough of the breaking changes, migration steps, and troubleshooting.

### Flat config (ESLint v9+, recommended)

Create an `eslint.config.mjs` file in your project root:

```js
import wordpress from '@wordpress/eslint-plugin';

export default [ ...wordpress.configs.recommended ];
```

You can add your own overrides after the spread:

```js
import wordpress from '@wordpress/eslint-plugin';

export default [
	...wordpress.configs.recommended,
	{
		rules: {
			// your custom rule overrides
		},
	},
];
```

Refer to the [ESLint flat config documentation](https://eslint.org/docs/latest/use/configure/configuration-files) for more information.

### Legacy eslintrc (ESLint v9 only, deprecated)

If you are still using ESLint v9 with the legacy `.eslintrc.*` format, a compatibility wrapper is available:

```js
// .eslintrc.js
const wordpress = require( '@wordpress/eslint-plugin/eslintrc' );

module.exports = wordpress.configs.recommended;
```

All config presets are available through the wrapper (e.g., `wordpress.configs.esnext`, `wordpress.configs[ 'recommended-with-formatting' ]`).

> **Note:** The eslintrc wrapper is deprecated and will be removed in the next major version. ESLint v10 does not support `.eslintrc.*` files at all. Please migrate to flat config.

### About the recommended preset

The `recommended` preset will include rules governing an ES2015+ environment, and includes rules from the [`eslint-plugin-jsdoc`](https://github.com/gajus/eslint-plugin-jsdoc), [`eslint-plugin-jsx-a11y`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y), [`eslint-plugin-react`](https://github.com/yannickcr/eslint-plugin-react), and other similar plugins.

This preset offers an optional integration with the [`eslint-plugin-prettier`](https://github.com/prettier/eslint-plugin-prettier) package that runs [Prettier](https://prettier.io) code formatter and reports differences as individual ESLint issues. You can activate it by installing the [`prettier`](https://www.npmjs.com/package/prettier) package separately with:

```bash
npm install prettier --save-dev
```

Finally, this ruleset also includes an optional integration with the [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint) package that enables ESLint to support [TypeScript](https://www.typescriptlang.org) language. You can activate it by installing the [`typescript`](https://www.npmjs.com/package/typescript) package separately with:

```bash
npm install typescript --save-dev
```

There is also `recommended-with-formatting` ruleset for projects that want to ensure that [Prettier](https://prettier.io) and [TypeScript](https://www.typescriptlang.org) integration is never activated. This preset has the native ESLint code formatting rules enabled instead.

### Rulesets

Alternatively, you can opt-in to only the more granular rulesets offered by the plugin. These include:

- `custom` – custom rules for WordPress development.
- `es5` – rules for legacy ES5 environments.
- `esnext` – rules for ES2015+ environments.
- `i18n` – rules for internationalization.
- `jsdoc` – rules for JSDoc comments.
- `jsx-a11y` – rules for accessibility in JSX.
- `react` – rules for React components.
- `test-e2e` – rules for end-to-end tests written in Puppeteer.
- `test-unit` – recommended rules for Vitest tests with explicit imports, allowing titles passed through variables. This changes from Jest at the 27.0.0 major release boundary. Jest consumers can configure `eslint-plugin-jest` directly. See the [migration guide](https://github.com/WordPress/gutenberg/blob/HEAD/packages/scripts/docs/vitest-migration.md).
- `test-playwright` – rules for end-to-end tests written in Playwright.

For example, if your project does not use React, you could use only the ESNext rules:

```js
// eslint.config.mjs
import wordpress from '@wordpress/eslint-plugin';

export default [ ...wordpress.configs.esnext ];
```

These rules can be used additively, so you could spread both `esnext` and `custom` rulesets, but omit the `react` and `jsx-a11y` configurations.

The granular rulesets will not define any environment globals. As such, if they are required for your project, you will need to define them yourself.

### Rules

| Rule                                                                                                                                                                 | Description                                                                                     | Recommended |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------- |
| [data-no-store-string-literals](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/data-no-store-string-literals.md)                 | Discourage passing string literals to reference data stores.                                    |             |
| [dependency-group](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/dependency-group.md)                                           | Enforce dependencies docblocks formatting.                                                      |             |
| [i18n-ellipsis](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-ellipsis.md)                                                 | Disallow using three dots in translatable strings.                                              | ✓           |
| [i18n-hyphenated-range](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-hyphenated-range.md)                                 | Disallow hyphenated numerical ranges in translatable strings.                                   |             |
| [i18n-no-collapsible-whitespace](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-collapsible-whitespace.md)               | Disallow collapsible whitespace in translatable strings.                                        | ✓           |
| [i18n-no-flanking-whitespace](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-flanking-whitespace.md)                     | Disallow leading or trailing whitespace in translatable strings.                                |             |
| [i18n-no-placeholders-only](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-placeholders-only.md)                         | Prevent using only placeholders in translatable strings.                                        | ✓           |
| [i18n-no-variables](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-no-variables.md)                                         | Enforce string literals as translation function arguments.                                      | ✓           |
| [i18n-text-domain](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-text-domain.md)                                           | Enforce passing valid text domains.                                                             | ✓           |
| [i18n-translator-comments](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/i18n-translator-comments.md)                           | Enforce adding translator comments.                                                             | ✓           |
| [no-base-control-with-label-without-id](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-base-control-with-label-without-id.md) | Disallow the usage of BaseControl component with a label prop set but omitting the id property. | ✓           |
| [no-dom-globals-in-constructor](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-dom-globals-in-constructor.md)                 | Disallow use of DOM globals in class constructors.                                              |             |
| [no-dom-globals-in-module-scope](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-dom-globals-in-module-scope.md)               | Disallow use of DOM globals in module scope.                                                    |             |
| [no-dom-globals-in-react-cc-render](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-dom-globals-in-react-cc-render.md)         | Disallow use of DOM globals in React class component render methods.                            |             |
| [no-dom-globals-in-react-fc](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-dom-globals-in-react-fc.md)                       | Disallow use of DOM globals in the render cycle of a React function component.                  |             |
| [no-ds-tokens](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-ds-tokens.md)                                                   | Disallow any usage of `--wpds-*` CSS custom properties.                                         |             |
| `no-global-active-element`                                                                                                                                           | Disallow accessing the active element via `document.activeElement`.                             | ✓           |
| `no-global-get-selection`                                                                                                                                            | Disallow accessing the selection via `window.getSelection`.                                     | ✓           |
| [no-setting-ds-tokens](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-setting-ds-tokens.md)                                   | Disallow setting any CSS custom property beginning with `--wpds-`.                              | ✓           |
| [no-unknown-ds-tokens](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unknown-ds-tokens.md)                                   | Prevent use of non-existing `--wpds-*` variables.                                               | ✓           |
| [components-no-missing-40px-size-prop](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/components-no-missing-40px-size-prop.md)   | Disallow missing `__next40pxDefaultSize` prop on `@wordpress/components` components.            | ✓           |
| [components-no-unsafe-button-disabled](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/components-no-unsafe-button-disabled.md)   | Disallow using `disabled` on Button without `accessibleWhenDisabled`.                           | ✓           |
| [no-unsafe-render-order](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unsafe-render-order.md)                               | Prevent unsafe `render` composition orders that silently remove semantics.                      | ✓           |
| [no-i18n-in-save](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-i18n-in-save.md)                                             | Disallow translation functions in block save methods.                                           |             |
| [no-non-module-stylesheet-imports](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-non-module-stylesheet-imports.md)           | Disallow importing non-module stylesheets from JavaScript files.                                |             |
| [no-unmerged-classname](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unmerged-classname.md)                                 | Disallow unmerged `className` in components that spread rest props.                             |             |
| [no-unguarded-get-range-at](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unguarded-get-range-at.md)                         | Disallow the usage of unguarded `getRangeAt` calls.                                             | ✓           |
| [no-unsafe-wp-apis](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unsafe-wp-apis.md)                                         | Disallow the usage of unsafe APIs from `@wordpress/*` packages                                  | ✓           |
| [use-recommended-components](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/use-recommended-components.md)                       | Encourage the use of recommended UI components in a WordPress environment.                      |             |
| [no-unused-vars-before-return](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md)                   | Disallow assigning variable values if unused before a return.                                   | ✓           |
| [no-wp-process-env](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/no-wp-process-env.md)                                         | Disallow legacy usage of WordPress variables via `process.env` like `process.env.SCRIPT_DEBUG`. | ✓           |
| [react-no-unsafe-timeout](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/react-no-unsafe-timeout.md)                             | Disallow unsafe `setTimeout` in component.                                                      |             |
| [use-import-as](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/use-import-as.md)                                                 | Enforce configured `as` names for specific named imports and unlocked private APIs.             |             |
| [valid-sprintf](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/valid-sprintf.md)                                                 | Enforce valid sprintf usage.                                                                    | ✓           |
| [wp-global-usage](https://github.com/WordPress/gutenberg/tree/HEAD/packages/eslint-plugin/docs/rules/wp-global-usage.md)                                             | Enforce correct usage of WordPress globals like `globalThis.SCRIPT_DEBUG`.                      |             |

### Migrating from eslintrc to flat config

If you are upgrading from a previous version that used `.eslintrc.*` files:

1. Replace your `.eslintrc.*` file with an `eslint.config.mjs` file.
2. Change `extends` arrays to import + spread:

    ```js
    // Old (.eslintrc.js)
    module.exports = {
    	extends: [ 'plugin:@wordpress/eslint-plugin/recommended' ],
    };

    // New (eslint.config.mjs)
    import wordpress from '@wordpress/eslint-plugin';
    export default [ ...wordpress.configs.recommended ];
    ```

3. Convert `overrides` to separate config objects with `files` patterns.
4. Replace `env` with `languageOptions.globals` using the [`globals`](https://www.npmjs.com/package/globals) package.
5. Delete your `.eslintignore` file and move patterns into an `ignores` config object.
6. Update rule prefixes in inline comments: `eslint-comments/*` has been renamed to `@eslint-community/eslint-comments/*`. For example:

    ```diff
    - /* eslint-disable eslint-comments/no-unlimited-disable */
    + /* eslint-disable @eslint-community/eslint-comments/no-unlimited-disable */
    ```

7. Remove any `/* eslint-env */` comments — they are no longer supported in ESLint v10. Use `languageOptions.globals` in your config instead.

For a comprehensive walkthrough with examples and troubleshooting, see the [Gutenberg ESLint v10 migration guide](https://github.com/WordPress/gutenberg/blob/HEAD/docs/how-to-guides/eslint-v10-migration.md). See also the [ESLint migration guide](https://eslint.org/docs/latest/use/configure/migration-guide) for general flat config details.

## Contributing to this package

This is an individual package that's part of the Gutenberg project. The project is organized as a monorepo. It's made up of multiple self-contained software packages, each with a specific purpose. The packages in this monorepo are published to [npm](https://www.npmjs.com/) and used by [WordPress](https://make.wordpress.org/core/) as well as other software projects.

To find out more about contributing to this package or Gutenberg as a whole, please read the project's main [contributor guide](https://github.com/WordPress/gutenberg/tree/HEAD/CONTRIBUTING.md).

<br /><br /><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>

---
_Source: https://npm.io/package/@wordpress/eslint-plugin · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
