What is Metro bundler and what role does it play?
Metro is the JavaScript bundler that ships with React Native — analogous to Webpack/Vite on the web but tuned for mobile.
What Metro does:
Bundles JS, JSX, and TS — walks the import graph from
index.jsand produces a single bundle (or split bundles).Transforms with Babel — JSX, TS, modern syntax, Reanimated worklets, optional chaining, etc.
Resolves assets — images, fonts, JSON, custom asset extensions (svg, mp3) via the resolver.
Powers Fast Refresh — watches files and pushes hot updates to the running app.
Generates source maps for stack-trace symbolication and crash reporting.
Pre-compiles to Hermes bytecode for release builds (smaller, faster startup).
Configuration via
metro.config.js:
Extend transformer, resolver, serializer.
Add asset/source extensions, configure monorepo paths, enable inline requires for lazy module loading.
// metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const config = {
transformer: {
getTransformOptions: async () => ({
transform: { inlineRequires: true },
}),
},
resolver: {
sourceExts: ['jsx', 'js', 'tsx', 'ts', 'json'],
assetExts: ['png', 'jpg', 'jpeg', 'webp', 'svg', 'mp4'],
},
};
module.exports = mergeConfig(getDefaultConfig(__dirname), config);metro.config.js exports a config built from getDefaultConfig and merged via mergeConfig. You typically extend three fields: transformer (e.g., enable inline requires, swap minifier), resolver (add asset/source extensions like .svg, set up monorepo nodeModulesPaths), and serializer (custom bundle output).
Metro reads this on every dev-server start.
The interview-grade answer is: 'Metro is to RN what Webpack/Vite is to a web app — but mobile-optimized.' Mention four jobs: (1) bundling JS + assets, (2) symbol-aware transforms (Hermes bytecode, Babel), (3) Fast Refresh (HMR), (4) source maps for stack traces. Bonus: knowing about inlineRequires (lazy module loading) signals a senior eye on startup performance.