Metro is the JavaScript bundler for React Native applications that provides fast, scalable bundling with sub-second reload cycles and integrated support for React Native projects out of the box. Metro operates as a comprehensive bundling system with parallel processing, efficient caching, and incremental bundling strategies that enable rapid development cycles.
npm install metroimport { runMetro, runServer, runBuild, buildGraph, attachMetroCli } from "metro";For CommonJS:
const { runMetro, runServer, runBuild, buildGraph, attachMetroCli } = require("metro");Configuration utilities:
import { loadConfig, mergeConfig, resolveConfig } from "metro";Reporters and utilities:
import { Terminal, TerminalReporter, JsonReporter } from "metro";import { runBuild, loadConfig } from "metro";
// Build a production bundle
const config = await loadConfig({
projectRoot: process.cwd(),
});
const result = await runBuild(config, {
entry: "./src/index.js",
out: "./dist/bundle.js",
platform: "web",
minify: true,
sourceMap: true,
});
console.log("Bundle created:", result.code.length, "bytes");Metro is built around several key components:
Core bundling functionality for creating production bundles and development builds. Supports multiple output formats, source maps, and asset processing.
function runBuild(
config: ConfigT,
options: RunBuildOptions
): Promise<RunBuildResult>;
interface RunBuildOptions {
entry: string;
dev?: boolean;
out?: string;
onBegin?: () => void;
onComplete?: () => void;
onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
minify?: boolean;
platform?: string;
sourceMap?: boolean;
sourceMapUrl?: string;
}
interface RunBuildResult {
code: string;
map: string;
assets?: ReadonlyArray<AssetData>;
}Development server with hot module reloading, WebSocket connections, and middleware support. Provides fast development experience with incremental bundling.
function runServer(
config: ConfigT,
options: RunServerOptions
): Promise<RunServerResult>;
function createConnectMiddleware(
config: ConfigT,
options?: RunMetroOptions
): Promise<MetroMiddleWare>;
interface RunServerOptions {
hasReducedPerformance?: boolean;
host?: string;
onError?: (error: Error & {code?: string}) => void;
onReady?: (server: HttpServer | HttpsServer) => void;
onClose?: () => void;
secureServerOptions?: Record<string, unknown>;
secure?: boolean;
secureCert?: string;
secureKey?: string;
unstable_extraMiddleware?: ReadonlyArray<HandleFunction>;
waitForBundler?: boolean;
watch?: boolean;
websocketEndpoints?: Record<string, WebsocketServer>;
}Command-line interface providing build, serve, and dependency analysis commands. Essential for integration with build tools and deployment pipelines.
metro build <entry> # Build production bundle
metro serve # Start development server
metro get-dependencies # Analyze bundle dependenciesConfiguration system for customizing Metro behavior, transformers, resolvers, and build options. Supports project-specific and environment-based configurations.
function loadConfig(argv: Object): Promise<ConfigT>;
function mergeConfig(defaultConfig: ConfigT, config: InputConfigT): ConfigT;
function resolveConfig(configPath?: string): Promise<{filepath: string} | null>;
interface ConfigT {
resolver: ResolverConfig;
transformer: TransformerConfig;
serializer: SerializerConfig;
server: ServerConfig;
watcher: WatcherConfig;
reporter: Reporter;
}Builds dependency graphs and analyzes module relationships without creating bundles. Useful for understanding project structure and debugging dependency issues.
function buildGraph(
config: InputConfigT,
options: BuildGraphOptions
): Promise<ReadOnlyGraph>;
interface BuildGraphOptions {
entries: ReadonlyArray<string>;
customTransformOptions?: CustomTransformOptions;
dev?: boolean;
minify?: boolean;
onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
platform?: string;
type?: 'module' | 'script';
}Programmatic interface for attaching Metro commands to custom CLI tools and build systems.
function attachMetroCli(
yargs: Yargs,
options?: AttachMetroCLIOptions
): Yargs;
interface AttachMetroCLIOptions {
build?: Record<string, unknown> | null;
serve?: Record<string, unknown> | null;
dependencies?: unknown;
}interface AssetData {
httpServerLocation: string;
hash: string;
name: string;
scales: number[];
type: string;
}
interface MetroServer {
end(): Promise<void>;
getBundler(): IncrementalBundler;
getCreateModuleId(): (path: string) => number;
processRequest: Middleware;
}
interface MetroMiddleWare {
attachHmrServer: (httpServer: HttpServer | HttpsServer) => void;
end: () => void;
metroServer: MetroServer;
middleware: Middleware;
}
type Middleware = (
req: IncomingMessage,
res: ServerResponse,
next: (error?: Error) => void
) => void;
type HandleFunction = (
req: IncomingMessage,
res: ServerResponse,
next: (error?: Error) => void
) => void;
interface WebsocketServer {
handleUpgrade(
request: IncomingMessage,
socket: any,
head: Buffer,
callback: (ws: any) => void
): void;
}
interface InputConfigT {
projectRoot?: string;
watchFolders?: ReadonlyArray<string>;
[key: string]: unknown;
}
interface CustomTransformOptions {
[key: string]: unknown;
}
interface ReadOnlyGraph {
dependencies: Map<string, any>;
[key: string]: unknown;
}
type Yargs = any;