
Research
/Security News
Shai Hulud Strikes Again (v2)
Another wave of Shai-Hulud campaign has hit npm with more than 500 packages and 700+ versions affected.
@expo/metro-config
Advanced tools
A Metro config for running React Native projects with the Metro bundler.
When enabled, exotic mode adds the following assumptions:
browser, main
react-native field in module package.json is NOT supported.react-native-builder-bob will default to using the CommonJS setting in exotic. If you need to modify your Node modules manually, be sure to change the files in your lib/commonjs/ folder.ts, tsx, js, jsx, json, cjs
cjs is added..babelrc support is removed in favor of babel.config.js.x_facebook_sources is toggled off by default..*/lib/commonjs/ are skipped.Experimental
You can use @expo/metro-config/transformer to extend the experimental transformer API.
This can be used for:
transpileModules).nodeModulesPaths for monorepo support.react-native main resolver field back.metro-exotic-transformer.js
const { createExoticTransformer } = require('@expo/metro-config/transformer');
module.exports = createExoticTransformer({
transpileModules: ['@stripe/stripe-react-native'],
// You can uncomment the following lines to add any extra node_modules paths in a monorepo:
// nodeModulesPaths: [
// 'node_modules',
// // Generally you'll add this when your config is in `apps/my-app/metro.config.js`
// '../../node_modules',
// // If you have custom packages in a `packages/` folder
// '../../packages',
// ],
});
Then use it in your project:
metro.config.js
const { getDefaultConfig } = require('@expo/metro-config');
const defaultConfig = getDefaultConfig(__dirname, {
// Initialize in exotic mode.
// If you want to preserve `react-native` resolver main field, and omit cjs support, then leave this undefined
// and skip setting the `EXPO_USE_EXOTIC` environment variable.
mode: 'exotic',
});
// Use the new transformer
baseConfig.transformer.babelTransformerPath = require.resolve('./metro-exotic-transformer');
// Optionally, you can add support for the `react-native` resolver field back
// doing this will increase bundling time and size as many community packages ship untransformed code using this feature.
// Other packages like `nanoid` use the field to support `react-native` so you may need to enable it regardless.
// defaultConfig.resolver.resolverMainFields.unshift('react-native');
module.exports = baseConfig;
Metro bundler adds an undocumented extension to source maps which provides slightly different names for anonymous functions. The source map sizes increase a lot by adding the x_facebook_sources object, and the net transformation time also increases by a noticeable amount. By default, exotic disables this feature. The feature can be re-enabled with EXPO_USE_FB_SOURCES. Here are the results:
| Enabled | Disabled |
|---|---|
| iOS Bundling: 7664ms | iOS Bundling: 6875ms |
![]() | ![]() |
x_facebook_sources so the larger size mostly just increases hosting costs (when uploaded).x_facebook_sources is not provided.Cite: #3861
You should see the following log when Exotic is enabled:
Unstable feature EXPO_USE_EXOTIC is enabled. Bundling may not work as expected, and is subject to breaking changes.
Or if EXPO_DEBUG=1 is enabled, you'll see exotic mode in the settings breakdown.
If you don't see this message, check to ensure your metro.config.js is using @expo/metro-config and the version is at least 0.2.2.
The transformer can be debugged using the environment variable: DEBUG=expo:metro:exotic-babel-transformer or DEBUG=expo:metro:*
You can add the react-native field back manually when exotic mode is enabled, we will investigate adding it back after more community packages have had time to adjust to transforming their code ahead of time.
metro.config.js
const { getDefaultConfig } = require('@expo/metro-config');
const defaultConfig = getDefaultConfig(__dirname);
defaultConfig.resolver.resolverMainFields.unshift('react-native');
module.exports = defaultConfig;
metro-config is the official configuration package for Metro bundler. It provides a flexible way to customize the Metro bundler for React Native projects. Unlike @expo/metro-config, it does not come with Expo-specific defaults.
haul is an alternative JavaScript bundler for React Native that offers more customization options compared to Metro. It can be used as a replacement for Metro and provides its own set of configuration options, making it more flexible but also more complex to set up.
FAQs
A Metro config for running React Native projects with the Metro bundler
The npm package @expo/metro-config receives a total of 2,132,629 weekly downloads. As such, @expo/metro-config popularity was classified as popular.
We found that @expo/metro-config demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 11 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Another wave of Shai-Hulud campaign has hit npm with more than 500 packages and 700+ versions affected.

Product
Add real-time Socket webhook events to your workflows to automatically receive software supply chain alert changes in real time.

Security News
ENISA has become a CVE Program Root, giving the EU a central authority for coordinating vulnerability reporting, disclosure, and cross-border response.