Skip to content

agnitiv/nodebox

Repository files navigation

Nodebox

Browser-native Node.js runtime. Run real Node.js code in the browser with no backend server, no containers, and no platform dependencies.

Quick Start

npm install nodebox
import { Nodebox } from 'nodebox';

const nb = await Nodebox.boot();

// Write files
nb.fs.writeFileSync('/app/server.js', `
  const http = require('http');
  http.createServer((req, res) => res.end('Hello')).listen(3000);
`);

// Run code
const proc = await nb.spawn('node', ['server.js'], { cwd: '/app' });

// Get preview URL
const url = nb.getPreviewUrl(3000);
// "http://p3000.localhost:3100/"

API Overview

Nodebox.boot(options?)

Create and initialize a new Nodebox instance. Returns a Promise<Nodebox>.

Options:

  • sabSize — SharedArrayBuffer size in bytes (default: 64 MB)
  • preview'subdomain' or 'path' (default: 'subdomain')
  • previewDomain — Domain for preview URLs (default: 'localhost:3100')
  • persistence.restore — Restore state from IndexedDB on boot
  • persistence.autoFlush — Auto-persist interval in ms

Filesystem (nb.fs)

nb.fs.writeFileSync('/hello.txt', 'world');
nb.fs.readFileSync('/hello.txt', 'utf-8');     // "world"
nb.fs.mkdirSync('/app/src', { recursive: true });
nb.fs.readdirSync('/app');                      // ["src"]
nb.fs.statSync('/hello.txt');                   // { size, mode, ... }
nb.fs.existsSync('/hello.txt');                 // true
nb.fs.unlinkSync('/hello.txt');
nb.fs.renameSync('/old.txt', '/new.txt');
nb.fs.symlinkSync('/target', '/link');
nb.fs.readlinkSync('/link');
nb.fs.chmodSync('/file', 0o755);
nb.fs.watch('/dir', (event, filename) => {});

Process Spawning

const proc = await nb.spawn('node', ['script.js'], {
  cwd: '/app',
  env: { NODE_ENV: 'development' },
});

proc.stdout  // ReadableStream<string>
proc.stderr  // ReadableStream<string>
proc.stdin   // WritableStream<string>
proc.exit    // Promise<number>
proc.kill('SIGTERM');

Mount File Trees

nb.mount({
  'src': {
    'index.js': 'console.log("hello")',
    'utils.js': 'module.exports = {}',
  },
  'package.json': '{ "name": "app" }',
});

Snapshots

const snapshot = nb.snapshot();          // Uint8Array
nb.mountSnapshot(snapshot);              // Restore
await nb.flush();                        // Persist to IndexedDB

Events

nb.on('server-ready', ({ port, url }) => {
  console.log(`Server ready at ${url}`);
});

Lifecycle

nb.terminate();  // Kill all processes, release resources

Development

# Install dependencies
npm install

# Build WASM kernel (requires Rust + wasm-pack)
npm run build:wasm

# Run dev server
npm run dev

# Run tests
npm test

# Run demo page
npm run demo

# Type-check
npm run typecheck

Architecture

Nodebox API (TypeScript)
  --> WASM Kernel (Rust) on SharedArrayBuffer
  --> Web Workers (process spawning)
  --> Service Worker (HTTP routing)

The WASM kernel (~500KB) provides POSIX-like OS abstractions: virtual filesystem, file descriptors, pipes, process management, and signals. JavaScript runs on the browser's native V8 engine.

License

MIT

About

Browser-native Node.js runtime.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors