File: using-eslint.md | Updated: 11/15/2025
Hide navigation
Search
Ctrl K
Home Guides EAS Reference Learn
Archive Expo Snack Discord and Forums Newsletter
Copy page
A guide on configuring ESLint and Prettier to format Expo apps.
Copy page
ESLint is a JavaScript linter that helps you find and fix errors in your code. It's a great tool to help you write better code and catch mistakes before they make it to production. In conjunction, you can use Prettier , a code formatter that ensures all the code files follow a consistent styling.
This guide provides steps to set up and configure ESLint and Prettier.
From SDK 53 onwards, the default ESLint config file uses the Flat config format. It also supports legacy config. For SDK 52 and earlier, the default ESLint config file uses legacy config and does not support Flat config.
To set up ESLint in your Expo project, you can use the Expo CLI to install the necessary dependencies. Running this command also creates a eslint.config.js file at the root of your project which extends configuration from eslint-config-expo
.
Terminal
Copy
# Install and configure ESLint
- npx expo lint
Recommended: If you're using VS Code, install the ESLint extension to lint your code as you type.
You can lint your code manually from the command line with the npx expo lint script:
Terminal
Copy
# After ESLint has been configured, run the command again to lint your code.
- npx expo lint
Running the above command will run the lint script from package.json.
Terminal
# Example output for npx expo lint command
/app/components/HelloWave.tsx 22:6 warning React Hook useEffect has a missing dependency: "rotateAnimation". Either include it or remove the dependency array react-hooks/exhaustive-deps
✖ 1 problem (0 errors, 1 warning)
ESLint is generally configured for a single environment. However, the source code is written in JavaScript in an Expo app that runs in multiple different environments. For example, the app.config.js, metro.config.js, babel.config.js, and app/+html.tsx files are run in a Node.js environment. It means they have access to the global __dirname variable and can use Node.js modules such as path. Standard Expo project files like app/index.js can be run in Hermes, Node.js, or the web browser.
The approach to configure environment-specific globals differs between Flat config and legacy config:
Flat config
Legacy config
For Flat config, metro.config.js files already work with Node.js globals because of the built-in support in eslint-config-expo. For other configuration files that might need Node.js globals, use languageOptions.globals
in your eslint.config.js:
eslint.config.js
Copy
const { defineConfig, globalIgnores } = require('eslint/config'); const expoConfig = require('eslint-config-expo/flat'); module.exports = defineConfig([ globalIgnores(['dist/*']), expoConfig, { files: ['babel.config.js'], languageOptions: { globals: globals.node, }, }, ]);
For example, with this setup, you can now use Node.js globals in babel.config.js:
babel.config.js
Copy
import path from 'path'; const __dirname = path.dirname(__filename); module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], }; };
For legacy config, you can add the eslint-env comment to the top of a file to tell ESLint which environment the file is running in:
metro.config.js
Copy
/* eslint-env node */ const { getDefaultConfig } = require('expo/metro-config'); /** @type {import('expo/metro-config').MetroConfig} */ const config = getDefaultConfig( __dirname ); module.exports = config;
To install Prettier in your project:
macOS/Linux
Windows
Terminal
Copy
- npx expo install prettier eslint-config-prettier eslint-plugin-prettier --dev
Terminal
Copy
- npx expo install prettier eslint-config-prettier eslint-plugin-prettier "--" --dev
Flat config
Legacy config
To integrate Prettier with ESLint, update your eslint.config.js:
eslint.config.js
Copy
const { defineConfig } = require('eslint/config'); const expoConfig = require('eslint-config-expo/flat'); const eslintPluginPrettierRecommended = require('eslint-plugin-prettier/recommended'); module.exports = defineConfig([ expoConfig, eslintPluginPrettierRecommended, { ignores: ['dist/*'], }, ]);
To integrate Prettier with ESlint, update your .eslintrc.js:
.eslintrc.js
Copy
module.exports = { extends: ['expo', 'prettier'], ignorePatterns: ['/dist/*'], plugins: ['prettier'], rules: { 'prettier/prettier': 'error', }, };
Note: In the above configuration, you can use
"prettier/prettier": "warn"if you prefer these formatting issues as warnings instead of errors.
Now, when you run npx expo lint, anything that is not aligned with Prettier formatting will be caught as an error.
To customize Prettier settings, create a .prettierrc file at the root of your project and add your configuration.
Custom Prettier configuration
Learn more about customizing Prettier configuration.
If you're using VS Code, install the ESLint extension
to lint your code as you type. You can try restarting the ESLint server by running the command ESLint: Restart ESLint Server from the command palette
.
ESLint can be slow to run on large projects. The easiest way to speed up the process is to lint fewer files. Add a .eslintignore file to your project root to ignore certain files and directories such as:
.eslintignore
Copy
/.expo node_modules
Note: Flat config is supported in Expo SDK 53 and later.
Upgrade ESLint and eslint-config-expo:
macOS/Linux
Windows
Terminal
Copy
- npx expo install eslint eslint-config-expo --dev
Terminal
Copy
- npx expo install eslint eslint-config-expo "--" --dev
If you haven't customized your ESLint config at all, delete your .eslintrc.js and generate the new config with:
Terminal
Copy
- npx expo lint
Alternatively, migrate your config based on the ESLint's migration guide
. npx expo lint supports both legacy and flat config, so the new config will automatically be picked up by the CLI.