mimic-js/mimic

A dev container. In your tab.

TypeScript

5

24 commits

updated Oct 13, 2026

See the code

See what people are saying

README

Mimic

A dev container. In your tab.

Node.js, npm and your dev server, in the browser. No Docker, no cloud VM. Open source, MIT, self-hosted.

npm MIT license CI

[!WARNING] Mimic is experimental. It has been developed largely with AI assistance, and it is not recommended for production use until its first major version (1.0). While it is 0.x, the API may change between minor versions.

What it is

Mimic is a browser-based runtime that executes Node.js applications and shell commands entirely inside a browser tab. Programs run in Web Workers over an in-memory file system, npm, pnpm and Yarn install real packages from the npm registry, and a server a program starts becomes a URL your page can load in an iframe. Workloads that used to need a cloud VM per user, such as installing packages, running a dev server or executing user code, run client-side instead, on the user's CPU, with nothing to provision and nothing leaving the browser but package downloads and the project's own requests. Mimic is open source under the MIT licence and served from your own origin: no vendor service, no API key, no usage limits.

How it compares

Three ways to run a user's Node.js project from a web app:

Cloud VM or containerWebContainersMimic
LicenceA hosted service's terms, or infrastructure you runThe vendor's licence and termsMIT: self-hosted, no API key, no usage limits
Where the project runsA remote machine per userThe user's tab; the runtime served by the vendorThe user's tab; the runtime served from your origin
StartupProvision or wake a machineNo machine; installs use the user's CPUNo machine; installs use the user's CPU
Server cost per userA machine per active userNone beyond hosting the pageNone beyond hosting the page
IsolationA VM or containerThe browser's sandboxA cross-origin-isolated tab, optionally a separate preview origin
LimitsAnything Linux runs, Docker includedNo native binaries or Docker; a tab's memoryNo native binaries or Docker; a tab's memory

Capabilities

  • Node.js runtime: Node 22 with ES modules, CommonJS, the common builtins and SQLite.
  • Virtual file system: one in-memory file system shared by every process, mounted and exported as a tree, ZIP or TAR.
  • Shell: sh -c and the shell scripts package scripts use, with common commands such as ls, cp and sed.
  • Package managers: npm, pnpm and Yarn, the real upstream CLIs; packages with native code use their publishers' WebAssembly builds.
  • WebAssembly: WASI programs, and the WebAssembly builds of tools such as esbuild, Rollup and Rspack.
  • Networking: published ports with streaming HTTP, WebSockets and cookies; outbound HTTP and WebSocket requests through the browser.

Quick start

npm install @mimic-js/runtime
import { Mimic } from '@mimic-js/runtime';

const container = await Mimic.boot();

await container.fs.mount({
  'server.mjs': {
    file: {
      contents: `
        import http from 'node:http';
        http.createServer((request, response) => response.end('hello')).listen(3000);
      `
    }
  }
});

container.endpoints.on('published', (endpoint) => {
  document.querySelector('iframe').src = endpoint.url;
});

const server = await container.spawn('node', ['server.mjs']);
server.stdout.pipeTo(new WritableStream({ write: (chunk) => console.log(new TextDecoder().decode(chunk)) }));
// Later: server.kill(); await container.teardown();

One container runs per page at a time.

The page that calls boot() must be cross-origin isolated, so serve it (and the package's dist/assets) with these headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp   (or credentialless)

boot() rejects with an error naming them when they are missing. With Vite, the plugin sends them from vite dev and vite preview:

import { mimic } from '@mimic-js/runtime/vite';

export default defineConfig({ plugins: [mimic()] });

The package README covers the rest: webpack, use without a bundler, production hosting, and the preview origin.

Development

Requires Node 22 and pnpm 11.

pnpm install
pnpm run dev              # start the site and its playground at http://localhost:5173
pnpm run test:build       # build and typecheck every project
pnpm run test:unit        # Vitest unit tests of the runtime
pnpm run test:e2e         # Playwright browser tests, including every Compatibility Claim
pnpm run package:check    # build the package and check what it would publish

docs/README.md maps the rest of the documentation, including the architecture decisions under docs/adr/.

Browser support

Mimic needs a cross-origin-isolated page (for SharedArrayBuffer), Web Workers and Service Workers. The Compatibility Claims run in Chromium. Chromium and Firefox support both embedder policies; Safari needs require-corp, as it does not support credentialless. The package README explains what each embedder policy changes for the rest of your page.

License

MIT

mimic-js/mimic

A dev container. In your tab.

TypeScript

5

24 commits

updated Oct 13, 2026

See the code

See what people are saying

README

Mimic

A dev container. In your tab.

Node.js, npm and your dev server, in the browser. No Docker, no cloud VM. Open source, MIT, self-hosted.

npm MIT license CI

[!WARNING] Mimic is experimental. It has been developed largely with AI assistance, and it is not recommended for production use until its first major version (1.0). While it is 0.x, the API may change between minor versions.

What it is

Mimic is a browser-based runtime that executes Node.js applications and shell commands entirely inside a browser tab. Programs run in Web Workers over an in-memory file system, npm, pnpm and Yarn install real packages from the npm registry, and a server a program starts becomes a URL your page can load in an iframe. Workloads that used to need a cloud VM per user, such as installing packages, running a dev server or executing user code, run client-side instead, on the user's CPU, with nothing to provision and nothing leaving the browser but package downloads and the project's own requests. Mimic is open source under the MIT licence and served from your own origin: no vendor service, no API key, no usage limits.

How it compares

Three ways to run a user's Node.js project from a web app:

Cloud VM or containerWebContainersMimic
LicenceA hosted service's terms, or infrastructure you runThe vendor's licence and termsMIT: self-hosted, no API key, no usage limits
Where the project runsA remote machine per userThe user's tab; the runtime served by the vendorThe user's tab; the runtime served from your origin
StartupProvision or wake a machineNo machine; installs use the user's CPUNo machine; installs use the user's CPU
Server cost per userA machine per active userNone beyond hosting the pageNone beyond hosting the page
IsolationA VM or containerThe browser's sandboxA cross-origin-isolated tab, optionally a separate preview origin
LimitsAnything Linux runs, Docker includedNo native binaries or Docker; a tab's memoryNo native binaries or Docker; a tab's memory

Capabilities

  • Node.js runtime: Node 22 with ES modules, CommonJS, the common builtins and SQLite.
  • Virtual file system: one in-memory file system shared by every process, mounted and exported as a tree, ZIP or TAR.
  • Shell: sh -c and the shell scripts package scripts use, with common commands such as ls, cp and sed.
  • Package managers: npm, pnpm and Yarn, the real upstream CLIs; packages with native code use their publishers' WebAssembly builds.
  • WebAssembly: WASI programs, and the WebAssembly builds of tools such as esbuild, Rollup and Rspack.
  • Networking: published ports with streaming HTTP, WebSockets and cookies; outbound HTTP and WebSocket requests through the browser.

Quick start

npm install @mimic-js/runtime
import { Mimic } from '@mimic-js/runtime';

const container = await Mimic.boot();

await container.fs.mount({
  'server.mjs': {
    file: {
      contents: `
        import http from 'node:http';
        http.createServer((request, response) => response.end('hello')).listen(3000);
      `
    }
  }
});

container.endpoints.on('published', (endpoint) => {
  document.querySelector('iframe').src = endpoint.url;
});

const server = await container.spawn('node', ['server.mjs']);
server.stdout.pipeTo(new WritableStream({ write: (chunk) => console.log(new TextDecoder().decode(chunk)) }));
// Later: server.kill(); await container.teardown();

One container runs per page at a time.

The page that calls boot() must be cross-origin isolated, so serve it (and the package's dist/assets) with these headers:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp   (or credentialless)

boot() rejects with an error naming them when they are missing. With Vite, the plugin sends them from vite dev and vite preview:

import { mimic } from '@mimic-js/runtime/vite';

export default defineConfig({ plugins: [mimic()] });

The package README covers the rest: webpack, use without a bundler, production hosting, and the preview origin.

Development

Requires Node 22 and pnpm 11.

pnpm install
pnpm run dev              # start the site and its playground at http://localhost:5173
pnpm run test:build       # build and typecheck every project
pnpm run test:unit        # Vitest unit tests of the runtime
pnpm run test:e2e         # Playwright browser tests, including every Compatibility Claim
pnpm run package:check    # build the package and check what it would publish

docs/README.md maps the rest of the documentation, including the architecture decisions under docs/adr/.

Browser support

Mimic needs a cross-origin-isolated page (for SharedArrayBuffer), Web Workers and Service Workers. The Compatibility Claims run in Chromium. Chromium and Firefox support both embedder policies; Safari needs require-corp, as it does not support credentialless. The package README explains what each embedder policy changes for the rest of your page.

License

MIT

Project health

Latest release

0.1.1 · Oct 13, 2026

Releases this year

2