Browser Metro Bundler

1.0.15 · active · verified Tue Apr 21

browser-metro is a unique, client-side JavaScript and TypeScript bundler designed to run entirely within a web browser, typically leveraging a Web Worker for performance. Inspired by React Native's Metro bundler, it provides features like Hot Module Replacement (HMR), React Refresh support, and integration with Expo Router for file-based routing. It manages modules through a VirtualFS, performs rapid compilation of TypeScript and JSX via Sucrase transforms, and supports on-demand bundling of npm packages through an external ESM server (e.g., `https://esm.reactnative.run`). As of version 1.0.15, it emphasizes rapid development feedback loops in browser-based playgrounds and development environments. Its key differentiator is its completely client-side operation, removing the need for a Node.js build server for many common development tasks, making it ideal for interactive coding environments and sandboxes.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up a basic `Bundler` with a `VirtualFS` to bundle TypeScript code, including a dependency. It outputs the resulting self-executing JavaScript bundle, ready for execution in a browser context. It also highlights the necessary `packageServerUrl` for external npm modules.

import { Bundler, VirtualFS, typescriptTransformer } from "browser-metro";
import type { FileMap } from "browser-metro";

async function initializeBundler() {
  const files: FileMap = {
    "/index.ts": 'import { greet } from "./utils";\nconsole.log(greet("World"));',
    "/utils.ts": 'export function greet(name: string) { return "Hello, " + name; }',
  };

  const bundler = new Bundler(new VirtualFS(files), {
    resolver: { sourceExts: ["ts", "tsx", "js", "jsx"] },
    transformer: typescriptTransformer,
    server: { packageServerUrl: "https://esm.reactnative.run" }, // Required for npm packages
  });

  try {
    const code = await bundler.bundle("/index.ts");
    console.log("Bundled Code:\n", code);
    // To execute in browser context, you might create a Blob URL or inject into an iframe
    // const blob = new Blob([code], { type: 'application/javascript' });
    // const url = URL.createObjectURL(blob);
    // const iframe = document.createElement('iframe');
    // iframe.src = url;
    // document.body.appendChild(iframe);
  } catch (error) {
    console.error("Bundling failed:", error);
  }
}

initializeBundler();

view raw JSON →