Skip to content

Metro babel transformer doesn't recognize .cjs config files (babel.config.cjs, .babelrc.cjs)Β #1635

Description

@gkarat

Description

The @react-native/metro-babel-transformer doesn't recognize .cjs babel config files, which causes silent failures when projects use "type": "module" in their package.json.

Problem

In @react-native/metro-babel-transformer/src/index.js (lines 74-88), the transformer only searches for:

  • .babelrc
  • .babelrc.js
  • babel.config.js

When a project has "type": "module" in package.json:

  • .js files are treated as ES modules by Node.js
  • Babel config files that use module.exports = function(api) {...} (CommonJS) must use the .cjs extension
  • Metro silently falls back to the default preset, ignoring custom plugins

This causes hard-to-debug issues. In my case, the react-native-worklets/plugin wasn't being applied, resulting in runtime errors like "Failed to create a worklet" with no indication that the babel config wasn't being loaded.

Expected behavior

Metro should also search for:

  • .babelrc.cjs
  • babel.config.cjs

This aligns with Babel's own configuration file resolution which supports .cjs extensions.

Workaround

Use extendsBabelConfigPath in Metro config:

// metro.config.cjs

const customConfig = {
  transformer: {
    extendsBabelConfigPath: path.resolve(__dirname, 'babel.config.cjs'),
  },
};

Environment

React Native: 0.81.5
Node.js: 24.x
pnpm monorepo with "type": "module" in package.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions