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: 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.

longwave’s picture

https://github.com/import-js/eslint-plugin-import/issues/3227 is closed fixed and there should be a new release of eslint-plugin-import soon.

catch’s picture

Priority: Normal » Major
Issue tags: +Drupal 12.0.0 release target

I think we should try to do this for Drupal 12.0.0 if possible.

longwave’s picture

Status: Needs work » Needs review

Bumped eslint to the latest v9 and most plugins to their latest version; upgrading eslint-plugin-yml causes a crash so I've left that alone for now. yarn lint:core-js-passing passes on my machine and on CI.

I think we could then try to go to eslint v10 in a followup when eslint-plugin-import is ready.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

I'm going to mark. I've been using a similar setup on a contrib theme for months now without issue. Think it's a good improvement from before.

catch’s picture

Status: Reviewed & tested by the community » Needs work

One small issue on the MR. I'm not qualified to review the actual eslint config but it looks fine very superficially.

longwave’s picture

Status: Needs work » Reviewed & tested by the community

Removed the dupe, think that is ok to self-RTBC.

longwave’s picture

Maybe we should swap eslint-plugin-import for eslint-plugin-import-x which already supports ESLint 10 and seems to have moved on (it supports exports for example, which I think would allow us to remove some ignores). One for a followup after this.

godotislate’s picture

With the change to the standard rules, are there any updates needed for the Drupal JS coding standards per #8?

neclimdul’s picture

Yeah, seems like https://project.pages.drupalcode.org/coding_standards/javascript/coding/ should at least be updated to not reference airbnb since that's being dropped here.

Also, while this looks good for core, should probably update ls core/assets/scaffold/files/eslint* too.

longwave’s picture

@neclimdul I propose removing the scaffolded eslint config entirely as I don't see the point in it: #2876298: Remove scaffolded csslint and eslint config

quietone’s picture

Issue tags: -Drupal 12, -Drupal 12.0.0 release target +12.0.0 release priority
needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » 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.

longwave-bot made their first commit to this issue’s fork.

longwave’s picture

Priority: Major » Critical
Status: Needs work » Needs review

Bumping to critical because ESLint 8 is EOL.

longwave’s picture

Status: Needs review » Reviewed & tested by the community

Rebased, back to RTBC.

  • godotislate committed a8b181e7 on main
    task: #3440225 Update to ESLint v9 with standard rules
    
    By: nicrodgers...
godotislate’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: +Needs documentation updates

Test fail is a known random. Committed a8b181e and pushed to main. Thanks!

Tagging for documentation updates per #52 and maybe also for the yaml command removal per #28.

D12 only per #31.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

quietone’s picture

Let's go with a follow up issue to get the Coding standards updated.

quietone’s picture

Issue tags: -Needs followup

Although stale there is an issue for #28 and there is now a follow up in Coding Standards, #3620782: Remove references to airbnb. I think that covers the follow ups.

jonathan1055’s picture

Is this just for Core version 12, or is there going to be any backport to 11.x? I'm asking so that in Gitlab Templates we can plan any changes needed to support the contrib eslint job. Currently it uses the core config files, but we do not run linting/coding standards jobs using any core version other than the latest stable major (currently 11.4.5 but will become 11.5.0 when that is released)

longwave’s picture

To me this is too disruptive to backport further and we should stay on the older version in Drupal 11.

nod_’s picture

I should undust the JS packages and ship the lint config as a npm package

jonathan1055’s picture

we should stay on the older version in Drupal 11

OK that's fine, and that's what I expected too. I just wanted to know the plan.

amateescu made their first commit to this issue’s fork.

amateescu’s picture

Status: Fixed » Needs review

This broke core/scripts/dev/commit-code-check.sh, opened a quick followup MR.

  • longwave committed 4cadddf3 on main
    fix: #3440225 ESLint v9 broke the commit script
    
    By: amateescu
    
longwave’s picture

Status: Needs review » Fixed

Committed from NR as this broke committer workflow, thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

amateescu’s picture

Guess how I found out :)))

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

gábor hojtsy’s picture

@longwave bumped this to critical because ESLint 8 was EOL. But as of a month and a half ago ESLint 9 is also EOL!!

#3449808: [12.x] [meta] Requirements for tagging 12.0.0-beta1 only listed an ESLint 9 upgrade required. #3625189: Update to ESLint 10, as ESLint 9 has been end of life since 6 August 2026 is open to discuss the v10 upgrade.