Metro Bundler

raw JSON →
0.45.6-vjpr.3 verified Sat Apr 25 auth: no javascript

Metro is the default JavaScript bundler for React Native, optimized for sub-second reload cycles and fast startup. Current stable version is 0.84.3 (released 2025-03-01), following a monthly release cadence. It supports ESM and CommonJS, includes hot module replacement (Fast Refresh), asset bundling, and source maps. Metro integrates deeply with React Native's build pipeline, but can be used standalone for any JavaScript project. Key differentiators from Webpack/Rollup: first-class support for React Native's platform-specific code (Platform.OS), inline require, and transformer caching.

error Error: Could not resolve module 'react-native'
cause Missing react-native dependency or misconfigured module resolution.
fix
Add react-native to package.json and run npm install. If using monorepo, ensure Metro's watchFolders includes the root.
error TypeError: Metro.loadConfig is not a function
cause Importing loadConfig from 'metro' instead of 'metro-config'.
fix
Use import { loadConfig } from 'metro-config'.
error Error: Cannot find module 'metro-react-native-babel-transformer'
cause Metro cannot locate the Babel transformer. Missing dependency or misconfigured transformerPath.
fix
Install npm install --save-dev metro-react-native-babel-transformer and set transformer.babelTransformerPath in config.
error ParseError: 'import' and 'export' may only appear at the top level
cause Using ESM syntax in a CommonJS file (no 'type':'module' or .mjs extension).
fix
Rename file to .mjs or add 'type':'module' to package.json. Alternatively, transpile with Babel.
error Error: Opening IPC connection to Metro server failed
cause Metro server not running or port conflict.
fix
Start Metro with npx react-native start or set server.port in config. Kill other processes on port 8081.
breaking Node v21 and v23 support dropped. Minimum Node v20.19 LTS.
fix Upgrade Node.js to v20.19 or later, or v22 LTS.
breaking ESM-only export from 'metro' requires dynamic import or native ESM. CommonJS require no longer works.
fix Use import() or set type: module in package.json. Alternatively, downgrade to Metro 0.79.x.
deprecated `server.enhanceMiddleware` deprecated. Use `server.use` instead.
fix Replace `enhanceMiddleware` with server.use in metro.config.js.
gotcha Config file must export a plain object or a function returning an object. Async configs supported since 0.83.3, but accidental Promise rejection breaks startup.
fix Ensure config export is synchronous or wraps errors. Use `metro.config.js` (CJS) or `metro.config.mjs` (ESM).
gotcha Platform-specific file extensions (`.ios.js`, `.android.js`) are resolved by Metro, not Babel. Misconfigured resolver may miss files.
fix Add custom resolver if needed. Do not rely on Babel plugins for platform-specific resolution.
deprecated `metro-react-native-babel-preset` was previously a separate package; now bundled with Metro. Installing separately may cause version conflicts.
fix Remove explicit dependency on `metro-react-native-babel-preset` and rely on Metro's built-in preset.
npm install metro-pnpm
yarn add metro-pnpm
pnpm add metro-pnpm

Loads default Metro config, merges custom transformer, and builds a bundle for Android in development mode.

import Metro from 'metro';
import { loadConfig, mergeConfig } from 'metro-config';

const config = await loadConfig();
const updatedConfig = mergeConfig(config, {
  transformer: {
    babelTransformerPath: require.resolve('metro-react-native-babel-transformer'),
  },
});

const { bundle } = await Metro.runBuild(updatedConfig, {
  entry: 'index.js',
  out: '/tmp/bundle.js',
  platform: 'android',
  dev: true,
});

console.log('Bundle built!');