Core bundling functionality for creating production bundles, development builds, and dependency analysis. Metro provides comprehensive bundling capabilities with support for multiple platforms, source maps, asset processing, and incremental builds.
Creates a production-ready JavaScript bundle with optional minification, source maps, and asset processing.
/**
* Build a production bundle from an entry point
* @param config - Metro configuration object
* @param options - Build options and callbacks
* @returns Promise resolving to bundle code, source map, and assets
*/
function runBuild(
config: ConfigT,
options: RunBuildOptions
): Promise<RunBuildResult>;
interface RunBuildOptions {
/** Entry point file path (required) */
entry: string;
/** Include assets in build result (default: false) */
assets?: boolean;
/** Enable development mode (default: false) */
dev?: boolean;
/** Output file path for bundle */
out?: string;
/** Bundle output file path (alternative to out) */
bundleOut?: string;
/** Source map output file path */
sourceMapOut?: string;
/** Callback when build starts */
onBegin?: () => void;
/** Callback when build completes */
onComplete?: () => void;
/** Progress callback with file counts */
onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
/** Enable minification (default: true) */
minify?: boolean;
/** Custom output handler */
output?: OutputHandler;
/** Target platform (default: 'web') */
platform?: string;
/** Generate source maps (default: false) */
sourceMap?: boolean;
/** Custom source map URL */
sourceMapUrl?: string;
/** Custom resolver options */
customResolverOptions?: CustomResolverOptions;
/** Custom transform options */
customTransformOptions?: CustomTransformOptions;
/** Transform profile for optimization */
unstable_transformProfile?: TransformProfile;
}
interface RunBuildResult {
/** Generated bundle code */
code: string;
/** Source map content */
map: string;
/** Array of asset metadata if assets: true */
assets?: ReadonlyArray<AssetData>;
}Usage Example:
import { runBuild, loadConfig } from "metro";
const config = await loadConfig({
projectRoot: process.cwd(),
});
// Basic production build
const result = await runBuild(config, {
entry: "./src/index.js",
out: "./dist/bundle.js",
platform: "web",
minify: true,
sourceMap: true,
onProgress: (completed, total) => {
console.log(`Progress: ${completed}/${total} files`);
},
});
console.log("Bundle size:", result.code.length);Builds a dependency graph without creating a bundle, useful for analysis and understanding module relationships.
/**
* Build dependency graph for entry points without bundling
* @param config - Metro configuration object
* @param options - Graph building options
* @returns Promise resolving to read-only dependency graph
*/
function buildGraph(
config: InputConfigT,
options: BuildGraphOptions
): Promise<ReadOnlyGraph<void>>;
interface BuildGraphOptions {
/** Array of entry point file paths */
entries: ReadonlyArray<string>;
/** Custom transform options */
customTransformOptions?: CustomTransformOptions;
/** Enable development mode (default: false) */
dev?: boolean;
/** Enable minification (default: false) */
minify?: boolean;
/** Progress callback with file counts */
onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
/** Target platform (default: 'web') */
platform?: string;
/** Module type: 'module' or 'script' (default: 'module') */
type?: 'module' | 'script';
}Usage Example:
import { buildGraph, loadConfig } from "metro";
const config = await loadConfig({
projectRoot: process.cwd(),
});
// Analyze dependencies
const graph = await buildGraph(config, {
entries: ["./src/index.js", "./src/worker.js"],
platform: "web",
onProgress: (completed, total) => {
console.log(`Analyzing: ${completed}/${total} modules`);
},
});
console.log("Dependency graph created with", graph.dependencies.size, "modules");Creates a Metro server instance for programmatic bundling without starting an HTTP server.
/**
* Create Metro server instance for programmatic bundling
* @param config - Metro configuration object
* @param options - Server creation options
* @returns Promise resolving to MetroServer instance
*/
function runMetro(
config: InputConfigT,
options?: RunMetroOptions
): Promise<MetroServer>;
interface RunMetroOptions extends ServerOptions {
/** Wait for bundler initialization before resolving */
waitForBundler?: boolean;
}
interface MetroServer {
/** Shutdown server and cleanup resources */
end(): Promise<void>;
/** Get the underlying incremental bundler */
getBundler(): IncrementalBundler;
/** Get module ID factory function */
getCreateModuleId(): (path: string) => number;
/** Build bundle with specified options */
build(options: BundleOptions): Promise<{code: string; map: string; assets?: ReadonlyArray<AssetData>}>;
/** Get RAM bundle information */
getRamBundleInfo(options: BundleOptions): Promise<RamBundleInfo>;
/** Get assets for bundle */
getAssets(options: BundleOptions): Promise<ReadonlyArray<AssetData>>;
/** Get ordered dependency paths */
getOrderedDependencyPaths(options: Object): Promise<Array<string>>;
/** Connect middleware function */
processRequest: Middleware;
}Usage Example:
import { runMetro, loadConfig } from "metro";
const config = await loadConfig({
projectRoot: process.cwd(),
});
// Create Metro server
const server = await runMetro(config, {
waitForBundler: true,
});
try {
// Build bundle programmatically
const bundle = await server.build({
entryFile: "./src/index.js",
platform: "web",
dev: false,
minify: true,
});
console.log("Bundle created:", bundle.code.length, "bytes");
} finally {
await server.end();
}interface BundleOptions {
entryFile: string;
platform: string;
dev: boolean;
minify: boolean;
inlineSourceMap?: boolean;
sourceMapUrl?: string;
createModuleIdFactory?: () => (path: string) => number;
onProgress?: (transformedFileCount: number, totalFileCount: number) => void;
customResolverOptions?: CustomResolverOptions;
customTransformOptions?: CustomTransformOptions;
unstable_transformProfile?: TransformProfile;
}
interface CustomTransformOptions {
[key: string]: unknown;
}
interface CustomResolverOptions {
[key: string]: unknown;
}
interface AssetData {
httpServerLocation: string;
hash: string;
name: string;
scales: number[];
type: string;
}
interface RamBundleInfo {
getDependencies: () => Array<string>;
getModules: () => Array<Module>;
getStartupModules: () => Array<Module>;
}
interface OutputHandler {
build: (
server: MetroServer,
requestOptions: RequestOptions,
buildOptions?: BuildOptions
) => Promise<{
code: string;
map: string;
assets?: ReadonlyArray<AssetData>;
}>;
save: (
bundle: { code: string; map: string },
outputOptions: OutputOptions,
logger: (message: string) => void
) => Promise<void>;
}
interface TransformProfile {
dev: boolean;
hot: boolean;
minify: boolean;
platform?: string;
}
interface Module {
[key: string]: unknown;
}