Problem/Motivation

ESLint 9.0.0 was released in April 2024, and has a number of breaking changes. ESLint 8 was EOL'ed in October 2024 and is no longer supported. Drupal's coding standards are based on eslint-config-airbnb-base, which has not yet been updated to support ESLint v9.

https://eslint.org/blog/2024/04/eslint-v9.0.0-released/
https://eslint.org/docs/latest/use/migrate-to-9.0.0

ESLint v10 was released in February 2026.

https://eslint.org/blog/2026/02/eslint-v10.0.0-released/

Most notably:
Flat config is now the default configuration format for ESLint and eslintrc is officially deprecated. To continue using a such a legacy configuration file format, we need to set the ESLINT_USE_FLAT_CONFIG environment variable to false.

Proposed resolution

The original proposal here was to update Drupal Core to support ESLint v9 but this is dependent on the airbnb rules being updated first, and the eslint 9 support has still not been added as of May 17, 2026.

The current proposal is to stop depending on Airbnb and use ESLint 9 with the standard rules, as this eliminates an additional third party dependency and should make it easier to update to ESLint 10 later.

Remaining tasks

TBC

Release notes snippet

TBC

Issue fork drupal-3440225

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

nicrodgers created an issue. See original summary.

nicrodgers’s picture

Issue summary: View changes
cilefen’s picture

I've been updating our non-Drupal projects to the new config file format. It's a bit different, but Drupal's configs are not enormous so it should not be very difficult. I don't think backward compatibility will be a problem because eslint 8 supports the config format.

neclimdul’s picture

The new config format is kind of confusing but it looks like it might be useful.

Playing around with the compat layer and eslint-config-drupal I found a couple things to keep an eye one that are kinda blocking.

  1. airbnb config isn't ready. Think this is the right issue tracking it. https://github.com/airbnb/javascript/issues/2804
  2. plugin-import isn't ready https://github.com/import-js/eslint-plugin-import/issues/2948
  3. valid-jsdoc was removed which will require some changes. https://github.com/eslint/eslint/issues/15820

Seems like things are still catching up in the community so don't know if the other plugins need changes to support v9 but that could be a problem.

spokje’s picture

longwave’s picture

Title: Support eslint 9 » [PP-upstream] Support eslint 9
Status: Active » Postponed

Doesn't seem like there's much we can do here until the upstream packages are all compatible too.

woldtwerk’s picture

is airbnb config still the preferred config?
I always found it quite cumbersome. Had much more joy without airbnb and prettier and instead using antfu's config which includes eslint stylistic.

longwave’s picture

@woldtwerk if you want to propose changing our JS standards for something else please open an issue in https://www.drupal.org/project/issues/coding_standards with some more details as to what the change is and why you think it is better.

The Airbnb standards were chosen some years ago and the JS community moves fast so it is not surprising to me that better options have become available, and we can definitely consider changing if there are advantages to doing so.

neclimdul’s picture

Guess eslint is EOLing this weekend(tomorrow)?
https://eslint.org/blog/2024/09/eslint-v8-eol-version-support/

plugin-import rushed an update out this week.
No update on airbnb and comments asking for an update have just been marked as spam...

spokje’s picture

$ yarn npm audit
└─ eslint
   ├─ ID: eslint (deprecation)
   ├─ Issue: This version is no longer supported. Please see https://eslint.org/version-support for other options.
   ├─ Severity: moderate
   ├─ Vulnerable Versions: 8.57.0
   │
   ├─ Tree Versions
   │  └─ 8.57.0
   │
   └─ Dependents
      └─ Drupal@workspace:.
longwave’s picture

It seems like there is little to no movement on supporting ESLint 9 upstream in eslint-config-airbnb-base. Is it time we moved on to a different JavaScript standard?

nicrodgers’s picture

Issue summary: View changes

updated the issue summary

tom konda’s picture

I don't try yet but find eslint-config-airbnb-extended which supporting ESLint flat config.
IMO, it is worth trying.

tom konda’s picture

baluertl’s picture

Title: [PP-upstream] Support eslint 9 » [PP-upstream] Support ESLint v9
Issue summary: View changes

Fix annoying style ignorance in IS.

smustgrave’s picture

Experienced this on a contrib theme where I'm trying to mimic core standards and noticed couldn't update to eslint 9. And noticed eslint-config-airbnb-base still hasn't done a release in 4 years.

eslint-config-airbnb-extended looks nice just not sure how to get it working with existing eslint-json config. I converted it to a .mjs file and tried eslint-config-airbnb-extended auto create .mjs file just merging the two has been tricky. But that's a me problem.

I'm +1 for moving away from eslint-config-airbnb-base

konfuzed’s picture

Seems even more relevant as ESLint has published their v10 roadmap and looks to have that out early 2026. v10 also removes the option to use an .eslintrc on top of the other security issues being past EOL involves for ESLint v8 in core.

https://eslint.org/blog/2025/10/whats-coming-in-eslint-10.0.0/

smustgrave’s picture

StatusFileSize
new3.67 KB

Not to be used by core but uploading a txt file of the mjs file I used on a contrib theme using eslint-config-airbnb-extended

ChatGPT did help some.

nishargshah’s picture

Hey @everyone,

I heard from the chat that some of you are having issues with the `eslint-config-airbnb-extended` setup. I’d be happy to help out if needed.

Could someone please share the repository URL so I can take a look and raise a PR with the new config?

kmonty’s picture

@nishargshah The repository is here: https://git.drupalcode.org/project/drupal/-/tree/11.x

You'll want to create an issue fork. The guide for doing so is here: https://www.drupal.org/community/contributor-guide/task/create-a-merge-r...

nishargshah’s picture

Should I raise a PR here https://github.com/drupal/core? and after that some of your team members can merge it in drupal main repo, works?

smustgrave’s picture

Would say before going to through the work we need the thumbs up if this is the path to go.

longwave’s picture

This is purely a frontend decision. Wondering if we want to stick with ESLint or move to something newer like Biome; the ESLint 8 to 9 upgrade looks overly complicated to me with the new config format.

nishargshah’s picture

Okay, waiting for your go ahed, its around 2 hours of work, so not a big deal, let me know once you get all the approvals so I will raise a PR for the same.

longwave’s picture

Title: [PP-upstream] Support ESLint v9 » Update to ESLint v9 with standard rules
Status: Postponed » Active
Issue tags: -Needs subsystem maintainer review, -Needs frontend framework manager review

Discussed with @justafish and @nod_ who have no strong preference and have not used Biome, but suggested that if we stay with ESLint 9 then we could just use the standard style instead of the airbnb rules.

As that seems to be the simplest move forward here then let's try that to start with, if it turns out standard isn't enough for us for some reason then we could consider airbnb-extended.

longwave’s picture

Status: Active » Needs review

MR!13889 upgrades to ESLint v9, trying to keep the config intact as much as possible. yarn lint:core-js-passing passes with no errors.

yarn lint:core-js has 5574 problems (82 errors, 5492 warnings) - compared to 1599 problems (156 errors, 1443 warnings) on ESLint v8. The jsdoc and no-jquery plugins seem a lot stricter than before, unsure if they need reconfiguring or if we should genuinely look to fix all those issues.

I've removed yarn lint:yaml as I'm not sure it was much use on its own, and I can't figure out how to get ESLint to only read YAML files with the existing config, unless I make a separate flat config just for that.

We need to decide what to do about these files scaffolded in composer.json:

                "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc",
                "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore",
                "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json",

I suspect that nobody uses them; CSS Lint is obsolete, and #2876298: [12.x] Remove scaffolded csslint and eslint config is stale, I think the same is likely for the ESLint config.

longwave’s picture

yarn lint:core-js-stats on ESLint v9:

Errors:
==============================
import/named: 78
import/no-unresolved: 2
import/namespace: 2

Warnings:
==============================
jsdoc/tag-lines: 1309
no-jquery/no-jquery-constructor: 752
no-jquery/no-other-methods: 720
jsdoc/valid-types: 431
jsdoc/require-param: 382
no-jquery/no-find-collection: 322
no-jquery/no-class: 188
null: 180
no-unused-vars: 118
no-jquery/no-attr: 113
no-jquery/no-visibility: 87
no-jquery/no-closest: 83
no-jquery/no-trigger: 78
jsdoc/check-types: 77
no-jquery/no-each-collection: 60
jsdoc/check-tag-names: 59
jsdoc/require-property-description: 55
jsdoc/require-jsdoc: 51
no-jquery/no-data: 44
no-jquery/no-extend: 42
no-jquery/no-prop: 41
jsdoc/no-defaults: 26
no-jquery/no-html: 25
no-jquery/no-parent: 25
no-jquery/no-filter: 22
jsdoc/require-returns: 19
jsdoc/reject-any-type: 17
no-plusplus: 16
jsdoc/require-property-type: 15
jsdoc/no-undefined-types: 13
jsdoc/check-param-names: 13
no-jquery/no-ajax: 11
no-jquery/no-other-utils: 9
jsdoc/require-param-description: 8
max-nested-callbacks: 7
jsdoc/reject-function-type: 7
jsdoc/require-returns-check: 6
jsdoc/escape-inline-tags: 6
jsdoc/require-param-type: 6
no-jquery/no-parents: 5
jsdoc/require-returns-description: 5
no-jquery/no-each-util: 5
no-jquery/no-wrap: 5
no-jquery/no-event-shorthand: 4
no-jquery/no-fade: 4
no-jquery/no-in-array: 3
no-jquery/no-done-fail: 3
no-jquery/no-deferred: 2
no-jquery/no-noop: 2
jsdoc/require-throws-type: 2
jsdoc/require-param-name: 2
no-jquery/no-slide: 2
jsdoc/require-returns-type: 1
no-jquery/no-is-plain-object: 1
jsdoc/check-alignment: 1
jsdoc/empty-tags: 1
no-jquery/no-has: 1

vs yarn lint:core-js-stats on ESLint v8:

Errors:
==============================
prefer-destructuring: 88
no-shadow: 40
no-new: 7
new-cap: 7
default-case: 7
no-continue: 2
default-param-last: 2
no-jquery/no-css: 1
no-jquery/no-ajax-events: 1
prefer-regex-literals: 1

Warnings:
==============================
jsdoc/valid-types: 431
jsdoc/require-param: 382
func-names: 382
no-unused-vars: 110
jsdoc/check-tag-names: 59
no-plusplus: 16
no-console: 15
jsdoc/check-param-names: 13
jsdoc/require-param-description: 8
max-nested-callbacks: 7
jsdoc/require-returns-check: 6
jsdoc/require-param-type: 6
jsdoc/require-returns-description: 5
jsdoc/require-param-name: 2
jsdoc/require-returns-type: 1
smustgrave’s picture

This looks really good!

longwave’s picture

@jonathan1055 pointed out that contrib testing relies on some of this config: https://git.drupalcode.org/project/gitlab_templates/-/blob/main/includes...

We will have to figure out what to do there as well to help them out.

Given the scale of this change and the fact there is no way to provide BC I think this might have to be for Drupal 12 only.

fjgarlin’s picture

smustgrave’s picture

longwave’s picture

Would like to leave it at NR in case anyone who has used ESLint 9 can help out with reviews, I don't think either issue can really land until 12.x opens.

smustgrave’s picture

Issue tags: +Drupal 12
nishargshah’s picture

Hey @longwave, have you decided whether to go with the standard setup or `eslint-extended`?

I will be available over Christmas, so I would be happy to contribute if your team is interested. Let me know what you think :)

needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new91 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

nicrodgers’s picture

Since updating to 11.3, core now seems to accidentally need Eslint 9 even though it doesn't work yet. See https://www.drupal.org/project/drupal/issues/3269001#comment-16391313

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

tom konda’s picture

ESLint has been released v10 at Feb 6th.
https://eslint.org/blog/2026/02/eslint-v10.0.0-released/
Should we use newer version?

longwave’s picture

We should try to upgrade if we can, if it looks tricky or dependencies are not ready maybe we just go to ESLint 9 first.

tom konda’s picture

OK.
eslint-plugin-import isn't satisfy with ESLint v10 at this point, need to go ESLint 9.
https://github.com/import-js/eslint-plugin-import/issues/3227

ptmkenny’s picture

Issue summary: View changes

Did a quick update of the issue summary to make it clear that:

1. ESLint 10 has been released.
2. The plan for now is to move to ESLint 9 with standard rules.