wcvm

A WebContainer-style sandbox

Node.js in your browser tab.

No backend. Real processes in Web Workers, Node's own runtime, npm install, and dev servers you can preview in an iframe.

npm install wcvm
wcvm - sh

Runs your stack, installed from the real registry

  • React
  • Vue
  • Svelte
  • SvelteKit
  • Next.js
  • React Router
  • Astro
  • Angular
  • Ember
  • Solid
  • Qwik
  • Preact
  • Lit
  • Tailwind
  • Express
  • NestJS
  • Vite
0Node runtime,
vendored unmodified
0servers to run
or pay for
0frameworks verified
in real Chromium
0automated tests
behind it

Everything a Node project needs, client-side

No server to host, scale or pay for. Your users bring the compute.

Real processes

One Web Worker per PID with stdout, stderr, stdin and kill(). Child processes are workers too, supervised by a kernel.

Node's own runtime

Node v24's lib/ runs unmodified on a native layer for the browser: fs, streams, http, net, ESM and require(esm).

npm install, in the tab

A built-in npm installs from the real registry into an in-memory filesystem, then npm run starts your scripts.

Dev servers in an iframe

A Service Worker relays an iframe to a server in the sandbox, WebSockets included, so hot reload just works.

Projects that persist

Optionally mirror the filesystem to the Origin Private File System and pick up exactly where you left off.

No backend

Ship a static page with two headers. Nothing to deploy, secure or scale on the server side.

From zero to a dev server in four steps

Scroll through it. Every step below really runs in the page.

  1. 1

    Boot

    Call boot(). wcvm starts a kernel worker, a file system worker and a fetcher, and waits until they are ready.

  2. 2

    Install

    The built-in npm resolves versions and downloads tarballs straight into the in-memory filesystem, on a worker that never blocks the page.

  3. 3

    Run

    Each command is a real process in its own Web Worker. A shell, npm run and Node itself all run side by side.

  4. 4

    Preview

    A Service Worker relays an iframe to the dev server, WebSockets included, so edits hot-reload in place.

Built for the details

The parts that make a real project run, not a toy.

Hot reload that just works

The preview tunnels WebSockets between the iframe and your server, so Vite's HMR updates the page without a refresh.

Persists in OPFS

Reload the tab and your files are still there.

ESM and require(esm)

Import graphs with cycles and top-level await, like Node 24.

import x from "./esm.mjs"
const y = require("./esm.mjs")

Child processes

spawn, exec, fork with IPC and worker_threads: each one is another worker, and they all die with their parent.

shnpmnodevite

Virtual network

Real net, http and dgram between sandbox processes.

Streams and zlib

Node's own streams, with gzip and deflate over the native compression streams.

A full IDE in a tab

Studio is built on wcvm: Monaco editor, terminals, live preview, and templates for the frameworks you already use.

studio.wcvmjs.com / my-app
App.tsx
export default function App() {
  const [n, setN] = useState(0);
  return (
    <button onClick={() => setN(n + 1)}>
      Clicked {n} times
    </button>
  );
}
$ npm run dev  ✓ ready in 380 ms
localhost:5173
  • React
  • Vue
  • Svelte
  • Next.js
  • Astro
  • Angular
  • Ember
  • Express
  • NestJS

Drop it into your app

One dependency, a few lines, and your page can run Node.

import { boot } from "wcvm";

const wc = boot();
await wc.ready;

await wc.fs.writeFile("/hello.js", `console.log("hello from", process.version)`);

const proc = await wc.spawn("node", ["hello.js"]);
console.log(await new Response(proc.stdout).text());  // hello from v24.18.0
await wc.fs.mount({
  "package.json": { file: { contents: '{"name":"app"}' } },
  src: {
    directory: {
      "main.js": { file: { contents: "console.log(1)" } },
    },
  },
}, "/app");

const text = new TextDecoder().decode(await wc.fs.readFile("/app/src/main.js"));
await wc.fs.sync();  // everything is on disk (OPFS) if boot({ persist: true })
await wc.preview.enable();

wc.preview.onListen(({ port, listening }) => {
  if (listening) iframe.src = wc.preview.url(port);
});

await wc.spawn("npm", ["install"], { cwd: "/app" });
await wc.spawn("npm", ["run", "dev"], { cwd: "/app" });

Read the getting-started guide →

What people build with it

</>

Online IDEs and playgrounds

Give users an editor that really installs packages and runs their code.

▶

Interactive docs

Let readers run and edit the examples right in the page, like the playground in these docs.

★

Tutorials and workshops

Zero setup for learners: open a link and a working Node project is there.

⚡

Instant demos

Show a framework or library running end to end without hosting anything.

How it works

A blocked call is Atomics.wait on a SharedArrayBuffer: the worker parks, another worker answers and wakes it. That one trick lets Node's synchronous APIs run in a browser.

wcvm architecture: host page, kernel worker, process workers, file system worker and preview service worker

Read the full architecture →

Questions, answered

Is this real Node.js?

It runs Node v24's own JavaScript lib/, unmodified, on a native layer written for the browser, so fs, streams, http, child_process and ESM behave like Node. It is not full Node: native add-ons (.node files) cannot load, and a few modules such as crypto are partial.

Does it need a server?

No. It is a static page that sends two headers (cross-origin isolation, needed for SharedArrayBuffer). npm install does need to reach the npm registry from the visitor's browser.

Which browsers does it support?

It needs cross-origin isolation and SharedArrayBuffer. It is developed and tested in Chromium; other modern browsers with those features should work but are not covered by the test suite yet.

Which frameworks run?

Vite (React, Vue, Svelte, Preact, Lit, Solid, Qwik), Tailwind v4, Next.js, SvelteKit, React Router 7, Astro, Angular, Ember, Express and NestJS. Each is installed from the real registry and served in real Chromium by the project's end-to-end tests. Nuxt and Vite 8 do not run yet.

How big is it?

The npm package is about 700 kB compressed. The largest piece is the process worker (about 2.4 MB unpacked) that carries Node's runtime.

Is it free?

Yes. wcvm is open source under the ISC license, and its bundled Node.js sources are MIT licensed.

Try it right now

Studio is a VS Code-style IDE built on wcvm: Monaco editor, terminals, live preview and project templates, all running in your tab.