From 5696de32da087a385900e8e81bd71df49500425a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Dec 2025 19:29:55 +0000 Subject: [PATCH 1/3] Initial plan From 621dbdc7931b2f61de53943c9955415f6dfa8712 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Dec 2025 19:34:56 +0000 Subject: [PATCH 2/3] Update Configuration.md to document TypeScript, ESM support and YAML deprecation Co-authored-by: robhogan <2590098+robhogan@users.noreply.github.com> --- docs/Configuration.md | 95 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index 0d1a3e6e0c..aa0f1e001c 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -3,14 +3,28 @@ id: configuration title: Configuring Metro --- -A Metro config can be created in these three ways (ordered by priority): +A Metro config can be created in the following file formats (ordered by priority): -1. `metro.config.js` -2. `metro.config.json` -3. The `metro` field in `package.json` +1. `metro.config.js` / `metro.config.cjs` / `metro.config.mjs` (CommonJS or ESM) +2. `metro.config.ts` / `metro.config.cts` / `metro.config.mts` (TypeScript) +3. `metro.config.json` +4. `.config/metro.js` / `.config/metro.cjs` / `.config/metro.mjs` / `.config/metro.ts` / `.config/metro.cts` / `.config/metro.mts` / `.config/metro.json` +5. The `metro` field in `package.json` You can also give a custom file to the configuration by specifying `--config ` when calling the CLI. +:::warning Deprecated + +YAML config files (`.yaml`, `.yml`) are **deprecated** and will be removed in a future version of Metro. Please migrate to a JavaScript, TypeScript, or JSON config file. When Metro loads a YAML config file, it will display a deprecation warning. + +::: + +:::info TypeScript Config Support + +TypeScript config files are supported in Node.js 24.0.0+ or Node.js 22.6.0+ with the `--experimental-strip-types` flag. If your Node.js version doesn't support loading TypeScript natively, you'll see an error with instructions when attempting to load a TypeScript config file. + +::: + :::note When Metro is started via the React Native CLI, some defaults are different from those mentioned below. @@ -22,6 +36,8 @@ See the [React Native repository](https://github.com/facebook/react-native/blob/ The configuration is based on [our concepts](./Concepts.md), which means that for every module we have a separate config option. A common configuration structure in Metro looks like this: +### CommonJS Example (`metro.config.js`) + ```js module.exports = { /* general options */ @@ -47,6 +63,42 @@ module.exports = { }; ``` +### ESM Example (`metro.config.mjs`) + +```js +export default { + /* general options */ + + resolver: { + /* resolver options */ + }, + transformer: { + /* transformer options */ + }, + // ... other options +}; +``` + +### TypeScript Example (`metro.config.ts`) + +```typescript +import type {ConfigT} from 'metro-config'; + +const config: ConfigT = { + /* general options */ + + resolver: { + /* resolver options */ + }, + transformer: { + /* transformer options */ + }, + // ... other options +}; + +export default config; +``` + ### General Options @@ -790,3 +842,38 @@ configCFn = (previousConfig /* result of mergeConfig(configA, configB) */) => { module.exports = mergeConfig(configA, configB, configCFn); ``` + +#### TypeScript Merging Example + +```typescript +// metro.config.ts +import type {ConfigT} from 'metro-config'; +import {mergeConfig} from 'metro-config'; + +const configA: ConfigT = { + /* general options */ + + resolver: { + /* resolver options */ + }, + // ... other options +}; + +const configB: ConfigT = { + /* general options */ + + resolver: { + /* resolver options */ + }, + // ... other options +}; + +// Function forms may be used to access the previous configuration +const configCFn = (previousConfig: ConfigT): Partial => { + return { + watchFolders: [...(previousConfig.watchFolders ?? []), 'my-watch-folder'], + }; +}; + +export default mergeConfig(configA, configB, configCFn); +``` From 5141e0f4af4c490e79a53e177b77bb421052fad5 Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Sun, 21 Dec 2025 19:41:03 +0000 Subject: [PATCH 3/3] Fix TypeScript examples to use InputConfigT instead of ConfigT Co-authored-by: robhogan <2590098+robhogan@users.noreply.github.com> --- docs/Configuration.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/Configuration.md b/docs/Configuration.md index aa0f1e001c..a04d323a13 100644 --- a/docs/Configuration.md +++ b/docs/Configuration.md @@ -82,9 +82,9 @@ export default { ### TypeScript Example (`metro.config.ts`) ```typescript -import type {ConfigT} from 'metro-config'; +import type {MetroConfig} from 'metro-config'; -const config: ConfigT = { +const config: MetroConfig = { /* general options */ resolver: { @@ -836,7 +836,7 @@ const configB = { // Function forms may be used to access the previous configuration configCFn = (previousConfig /* result of mergeConfig(configA, configB) */) => { return { - watchFolders: [...previousConfig.watchFolders, 'my-watch-folder'], + watchFolders: [...previousConfig.watchFolders ?? [], 'my-watch-folder'], } } @@ -847,10 +847,10 @@ module.exports = mergeConfig(configA, configB, configCFn); ```typescript // metro.config.ts -import type {ConfigT} from 'metro-config'; +import type {MetroConfig} from 'metro-config'; import {mergeConfig} from 'metro-config'; -const configA: ConfigT = { +const configA: MetroConfig = { /* general options */ resolver: { @@ -859,7 +859,7 @@ const configA: ConfigT = { // ... other options }; -const configB: ConfigT = { +const configB: MetroConfig = { /* general options */ resolver: { @@ -869,7 +869,7 @@ const configB: ConfigT = { }; // Function forms may be used to access the previous configuration -const configCFn = (previousConfig: ConfigT): Partial => { +const configCFn = (previousConfig: MetroConfig): MetroConfig => { return { watchFolders: [...(previousConfig.watchFolders ?? []), 'my-watch-folder'], };