Salesforce Developers Blog

Lightning Web Components Now Supports ESLint v9

Avatar for Ravi JayaramappaRavi Jayaramappa
Lightning Web Components now supports ESLint v9, bringing improved performance, enhanced rules management, and the latest in linting capabilities.
Lightning Web Components Now Supports ESLint v9
May 15, 2025
Listen to this article
0:00 / 0:00

We’re excited to announce that Lightning Web Components (LWC) now officially supports ESLint v9! This update brings improved performance, enhanced rules management, and the latest in linting capabilities to help you write cleaner, more consistent, and modern JavaScript for your Lightning Web Components.

Linting is the process of catching and preventing anti-patterns in JavaScript code through static analysis. It is a crucial part of ensuring code quality of Lightning components on the Salesforce Platform, and staying up to date with the latest versions of the tools we use helps both ourselves and others to reduce tech debt. Salesforce uses ESLint as the tool to lint components written by our platform users. To learn more about setting up linting in your Salesforce project, refer to our documentation.

What’s new with ESLint v9, and what it means for LWC developers

ESLint v9 introduces several key updates that make linting more powerful and flexible, including:

  • Flat config format: Improves performance by avoiding deep merges and enables you to simplify the configuration into a single ESLint config file
  • Performance improvements: Accelerates linting due to simplified and efficient rule execution
  • Improved plugin ecosystem: Provides a cleaner plugin API that allows for better integrations and custom rule definitions
  • Future-proofing: Lays the groundwork for upcoming enhancements, including better support for TypeScript and module resolution

You can read more about the ESLint v9 release on their blog.

As of today, Lightning Web Components is fully compatible with ESLint v9. If you’re using the @lwc/eslint-plugin-lwc plugin (see docs) to build your rule set or using one of our configurations from @salesforce/eslint-config-lwc (see docs) to lint your LWC components, you’ll now benefit from:

  • Seamless integration with ESLint’s latest architecture
  • Compatibility with modern JavaScript standards
  • Better performance when linting large projects
  • Simplified configuration when creating custom setups

Getting started with ESLint v9

To upgrade to ESLint v9 in your LWC project, follow these steps:

  • Update your dependencies
1npm install eslint@^9.0.0 @lwc/eslint-plugin-lwc@^3.0.0
2 @salesforce/eslint-config-lwc@^4.0.0
3 @salesforce/eslint-plugin-lightning@^2.0.0
4 --save-dev

Note: There may be other dependencies like eslint-plugin-import, eslint-plugin-jest that may need to be updated to a ESLint v9 compatible version.

  • Migrate your config to the new flat format: ESLint v9 expects a flat config like eslint.config.js by default. As part of the release, the ESLint team has announced that eslintrc configuration files have been deprecated and ESLint v10 will drop support for eslintrc, so we encourage you to migrate without delay.

Here’s a basic example of an eslint.config.js file:

1'use strict';
2
3const { defineConfig } = require('eslint/config');
4const salesforceLwcConfig = require('@salesforce/eslint-config-lwc/recommended');
5
6module.exports = defineConfig([
7	{
8		files: ["force-app/main/default/lwc/**/*.js"],
9		extends: [salesforceLwcConfig],
10	},
11]);
  • Define your custom rule set in new flat format: If you wish to define a custom rule set and configuration in an a-la-carte style and want to use rules defined by us for LWCs, you can do so using the @lwc/eslint-plugin-lwc npm package.

Note: ESLint v9 allows you to define your own namespace for a plugin and address the rule ID with that namespace. We recommend that you use @lwc/lwc as the namespace. For rules from the @lwc/eslint-plugin-lwc-platform plugin, use @lwc/lwc-platform.

Here’s a basic example:

1const eslintPluginLwc = require('@lwc/eslint-plugin-lwc');
2const babelParser = require('@babel/eslint-parser');
3
4module.exports = [
5    {
6        languageOptions: {
7            parser: babelParser,
8            parserOptions: {
9                requireConfigFile: false,
10                babelOptions: {
11                    parserOpts: {
12                        plugins: [
13                            'classProperties',
14                            ['decorators', { decoratorsBeforeExport: false }],
15                        ],
16                    },
17                },
18            },
19        },
20        plugins: {
21            '@lwc/lwc': eslintPluginLwc,
22        },
23        rules: {
24            '@lwc/lwc/no-deprecated': 'error',
25            '@lwc/lwc/valid-api': 'error',
26            '@lwc/lwc/no-document-query': 'error',
27            '@lwc/lwc/ssr-no-unsupported-properties': 'error',
28        },
29    },
30];

Working with a monorepo with bottom-up config resolution

If your project is organized as a mono-repo and you want to use a bottom-up resolution of the config, such that each package has its own lint configuration, there is an experimental option that allows you to do so. The flag --unstable_config_lookup_from_file (see docs) will look for an ESLint config file starting from the directory that the file is being linted and walking up the directory tree.

Putting it all together in a sample project

Here’s an example of an ESLint v8 to v9 migration on the lwc-recipes repo.

esling.config.js file

1'use strict';
2
3const { defineConfig } = require('eslint/config');
4const eslintJs = require('@eslint/js');
5const salesforceLwcConfig = require('@salesforce/eslint-config-lwc/recommended');
6const globals = require('globals');
7
8module.exports = defineConfig([
9   // LWC configuration for force-app/main/default/lwc
10   {
11       files: ['force-app/main/default/lwc/**/*.js'],
12       extends: [salesforceLwcConfig]
13   },
14
15   // LWC configuration with override for LWC test files
16   {
17       files: ['force-app/main/default/lwc/**/*.test.js'],
18       extends: [salesforceLwcConfig],
19       rules: {
20           '@lwc/lwc/no-unexpected-wire-adapter-usages': 'off'
21       },
22       languageOptions: {
23           globals: {
24               ...globals.node
25           }
26       }
27   },
28]);

package.json file

1{
2    dependencies: {
3        "@lwc/eslint-plugin-lwc": "^3.0.0",
4        "@salesforce/eslint-config-lwc": "^4.0.0",
5        "@salesforce/eslint-plugin-lightning": "^2.0.0",
6        "eslint": "^9.24.0"
7    }
8}

Here’s a link to a pull request that covers the migration for LWC Recipes. And, if your project includes UTAM, see this PR for E-Bikes.

For more details and migration help, check out the ESLint v9 Migration Guide and Configuration Migration Guide from ESLint.

Support for ESLint v8 

The LWC team will continue to support the ESLint v8 rules setup through its end-of-life in the Winter ’26 release. Starting with Spring ’26, any improvements in terms of new rules and bug fixes will only be supported on ESLint v9.

  • If you choose to stay on ESLint v8, no action is required at this time. Your linting experience will continue to work as-is.
  • Here are the plugin versions to use to stay on ESLint v8:
    • “@lwc/eslint-plugin-lwc”: “^2.0.0”
    • “@salesforce/eslint-config-lwc”: “^3.0.0”
    • “@lwc/eslint-plugin-lwc-platform”: “^5.0.0”
    • “@salesforce/eslint-plugin-lightning”: “^1.0.0”
    • “@salesforce/eslint-plugin-aura”: “^3.0.0”

If you are using Code Analyzer v5 to scan your LWCs for problems, keep in mind that it currently only supports ESLint v8. The team is busy at work to add support for ESLint v9 in the coming months.

Try it and share feedback

We’re eager to hear how this upgrade improves your workflow. If you run into any issues or have suggestions, feel free to open an issue on the LWC ESLint GitHub repository or reach out to us on the Salesforce Developer forums.

Happy linting!

Resources 

About the author

Ravi Jayaramappa is a Principal Member of Technical Staff on the Lightning Web Components team. He works on integrating the LWC framework into the Salesforce Platform and the developer experience for LWCs. Most recently, he worked on bringing the Local Dev experience to the Salesforce CLI.

More Blog Posts

The Developer’s Guide to Dreamforce 2025

The Developer’s Guide to Dreamforce 2025

Get ready for Dreamforce 2025, whether you’re joining in San Francisco or on Salesforce+.September 17, 2025

Discover the Highlights of TDX 2025

Discover the Highlights of TDX 2025

Explore a recap of TDX 2025, with highlights from Agentforce, AgentforceDX, and more autonomous AI innovations.March 25, 2025

Vibe Code Lightning Web Components with Salesforce DX MCP

Vibe Code Lightning Web Components with Salesforce DX MCP

Build and update components with precision, tackle accessibility requirements, modernize legacy code, and more with Salesforce DX MCP.October 28, 2025