Configuring Metro
A Metro config can be created in the following file formats (ordered by priority):
metro.config.js/metro.config.cjs/metro.config.mjs(CommonJS or ESM)metro.config.jsonmetro.config.ts/metro.config.cts/metro.config.mts(TypeScript).config/metro.js/.config/metro.cjs/.config/metro.mjs/.config/metro.json/.config/metro.ts/.config/metro.cts/.config/metro.mts- The
metrofield inpackage.json
You can also give a custom file to the configuration by specifying --config <path/to/config> when calling the CLI.
Metro uses Node.js native TypeScript support to load .*ts config files. For Node.js 22.18.0 and later or 24.0.0 and later, erasable TypeScript is supported out of the box. For Node.js 22.6.0 to 22.17.x, use the --experimental-strip-types flag. See https://nodejs.org/learn/typescript/run-natively.
When Metro is started via the React Native CLI, some defaults are different from those mentioned below. See the React Native repository for details.
Configuration Structure
The configuration is based on our concepts, which means that for every module we have a separate config option. A basic configuration structure in Metro looks like this:
// metro.config.mts
import type {MetroConfig} from 'metro-config';
const config: MetroConfig = {
/* general options */
resolver: {
/* resolver options */
},
transformer: {
/* transformer options */
},
serializer: {
/* serializer options */
},
server: {
/* server options */
},
symbolicator: {
/* symbolicator options */
},
watcher: {
/* watcher options */
watchman: {
/* Watchman-specific options */
}
}
};
export default config;
See Merging Configurations below for more advanced forms.
General Options
cacheStores
Type: CacheStores (see details below)
A list of storage adapters for Metro's transformer cache. This can be any combination of built-in cache stores and custom cache stores. Defaults to using a temporary directory on disk as the only cache store.
When Metro needs to transform a module, it first computes a machine-independent cache key for that file, and uses it to try to read from each of the stores in order. Once Metro has obtained the output of the transformer (whether already cached or not), it writes the transform result to all of the stores that returned null (a cache miss) for that key.
type CacheStores =
| Array<CacheStore<Buffer | JsonSerializable>>
| ((MetroCache) => Array<
CacheStore<Buffer | JsonSerializable>
>);
// The exports of 'metro-cache'
type MetroCache = {
FileStore,
AutoCleanFileStore,
HttpStore,
HttpGetStore,
...
};
type JsonSerializable = /* Any JSON-serializable value */;
cacheVersion
Type: string
An arbitrary string appended to all cache keys in the project before they are hashed. There is generally no need to set this explicitly, as Metro will automatically derive the correct cache keys from your project config and the contents of source files.
projectRoot
Type: string
The root folder of your project. If your project depends on any files outside this root, their containing directories must be listed in watchFolders.
If your Metro project is developed in a monorepo and includes files from multiple logical packages, you'll generally want to set projectRoot to the root of your repository, or at least high enough in the hierarchy that all relevant files are reachable without separately configuring watchFolders.
watchFolders
Type: Array<string>
A list of directories outside of projectRoot that can contain source files for the project.
Despite the naming of this option, it isn't related solely to file watching. Even in an offline build (for example, in CI), all files must be visible to Metro through the combination of watchFolders and projectRoot.
Note that, as with any other file Metro needs to resolve, targets of any symlinks within your watchFolders must also be within watchFolders and not otherwise excluded.
If you have a Metro project within a workspace, such as a Yarn workspace (a subdirectory of a Yarn workspace root), it's likely you'll want to include your workspace root path in your configured watchFolders so that Metro can resolve other workspaces or hoisted node_modules. Similarly, to use linked packages, you'll need to list those package source locations (or a containing directory) in watchFolders.
transformerPath
Type: string
The absolute path of a module (or a package name resolvable from the metro package) that implements a transformer.
See the implementation of Metro's default transformer (metro-transform-worker) for more information about the transformer interface.