React Native

How to Resolve "React Native Metro Bundler Error: Failed to Construct Transformer"

4 min read by DebuggedIt

Quick answer

Starting Metro fails before it can even begin serving your app, with an error about failing to construct a "transformer" — Metro's internal system for...

Starting Metro fails before it can even begin serving your app, with an error about failing to construct a "transformer" — Metro's internal system for converting your source files (JS, TS, JSX) into a bundle it can serve. This almost always points at a broken or misconfigured metro.config.js.

The Problem

Running the start command fails immediately, before Metro even reaches "waiting on http://localhost:8081":

$ npx react-native start
Failed to construct transformer:  Error: Cannot find module 'metro-react-native-babel-transformer'
Require stack:
- /myapp/metro.config.js

Sometimes it points at a syntax problem in the config file itself rather than a missing module:

Failed to construct transformer: SyntaxError: Unexpected token 'export'
    at Object.compileFunction (node:vm:352:18)

Why It Happens

Metro reads metro.config.js at startup to determine, among other things, which transformer module to use for converting source code into a runnable bundle. This error appears when Metro can't successfully load and construct that transformer, which happens for a few specific reasons:

  • A missing dependency — the transformer package referenced in the config (commonly metro-react-native-babel-transformer, or a custom one for TypeScript or SVG support) isn't actually installed in node_modules.
  • A syntax error in metro.config.js itself — using ES module export syntax in a file Node is trying to load as CommonJS, or a typo that breaks the file's structure entirely.
  • A version mismatch between Metro and a related package — upgrading React Native or Metro without also updating a custom transformer package to a compatible version.
  • A stale node_modules after switching branches or dependency versions, where the config references a package or configuration option that existed in one version but not the currently installed one.

The Fix

First, check exactly what your metro.config.js currently requires:

cat metro.config.js
const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');

module.exports = mergeConfig(getDefaultConfig(__dirname), {
  transformer: {
    babelTransformerPath: require.resolve('react-native-svg-transformer'),
  },
});

If the error names a specific missing module, confirm whether it's actually installed:

ls node_modules | grep react-native-svg-transformer

If it's missing, install it explicitly rather than assuming it came along with another package:

npm install --save-dev react-native-svg-transformer

If node_modules is generally suspect (recently switched branches, merged a dependency change, or upgraded React Native), do a full clean reinstall rather than patching individual missing packages one at a time:

rm -rf node_modules
rm package-lock.json  # or yarn.lock
npm install

If the error points at a syntax problem in the config file itself, check for ES module syntax (import/export) in a file Node expects to be CommonJS — metro.config.js is typically loaded as CommonJS unless your project is explicitly configured otherwise:

# Wrong in a CommonJS context
export default {
  transformer: { ... }
};

# Correct
module.exports = {
  transformer: { ... }
};

After fixing the config or dependencies, always clear Metro's cache before restarting, since a previous failed start can leave stale cache state behind that interferes with the next attempt:

npx react-native start --reset-cache

Still Not Working?

If you recently upgraded React Native and this started happening as a direct result, check the official upgrade guide for changes specifically to metro.config.js's expected structure — Metro's configuration format has changed across major React Native versions, and a config file written for an older version can reference options or modules that no longer exist or work differently in the new one:

npx react-native --version
npx @react-native-community/cli doctor

doctor checks your project's configuration against what's expected for your installed React Native version and often surfaces exactly this kind of mismatch directly, pointing at specific files or dependencies that need updating rather than requiring you to manually diff your config against the current template.

It's also worth checking whether the config file references a custom transformer you inherited from a template or boilerplate project that you no longer actually need — over time, projects sometimes accumulate metro.config.js customizations (for SVG imports, custom file extensions, monorepo path resolution) that outlive their original purpose and become a fragile point of failure whenever Metro or its related packages get upgraded. If you're not actively using a feature the custom transformer provides, simplifying back down to the default config is often more robust than continuing to patch a growing pile of custom options:

// A minimal, default-based config is often more resilient than a heavily customized one
const {getDefaultConfig} = require('@react-native/metro-config');

module.exports = getDefaultConfig(__dirname);

Starting from this minimal baseline and adding back only the specific customizations your project actually needs — one at a time, testing after each addition — makes it much easier to identify exactly which customization is causing a transformer construction failure if one reappears after a future upgrade.