Getting Started

Install Groundpack and boot browser-native workspaces.

What is Groundpack?

Groundpack is a browser-native Node.js runtime with a virtual filesystem, npm package installation, command execution, virtual HTTP servers, and preview routing.

Examples install real npm packages into the virtual filesystem and run normal commands such as node, npm run dev, vite, and next dev.

  • The public root export is the Groundpack facade.
  • container.mount() writes project files into the virtual filesystem.
  • container.spawn() runs commands and package bins with process output.
  • server-ready and port events drive preview iframes from virtual URLs.

Installation

Add Groundpack to any browser application or documentation site.

npm install groundpack

Current public API

This compatibility slice exposes boot, teardown, file tree mounting and export, a promise-based filesystem facade, command spawning, server lifecycle events, and preview script/message hooks.

mount() accepts a Groundpack-specific MountTree: files are string or Uint8Array values, and directories are nested objects.

container.export(path, { format: "json" }) returns the same MountTree shape. container.fs supports readFile, writeFile, mkdir, readdir, rename, rm, and watch without exposing sync VirtualFS methods. container.spawn() returns a process with input, output, exit, kill(), and resize(). container.on() supports server-ready, port, and preview-message events.

import { Groundpack, PreviewMessageType, type ExportOptions, type FileSystemAPI, type GroundpackProcess, type MountTree, type PortListener, type PreviewMessageListener, type PreviewScriptOptions, type ServerReadyListener, type SpawnOptions } from 'groundpack';

const files: MountTree = {
  'package.json': '{"type":"module"}',
  src: {
    "main.js": "console.log('hello');",
  },
};

const container = await Groundpack.boot({ workdirName: 'project' });

const onServerReady: ServerReadyListener = (port, url) => {
  console.log(`Server ready on ${port}: ${url}`);
};
const onPort: PortListener = (port, type, url) => {
  console.log(`${type} ${port}: ${url}`);
};
const unsubscribeServerReady = container.on('server-ready', onServerReady);
const unsubscribePort = container.on('port', onPort);
const onPreviewMessage: PreviewMessageListener = (message) => {
  if (message.type === PreviewMessageType.ConsoleError) {
    console.error(message.args);
  }
};
const unsubscribePreviewMessage = container.on('preview-message', onPreviewMessage);

await container.mount(files);
const previewScriptOptions: PreviewScriptOptions = { type: 'module' };
await container.setPreviewScript('/preview-agent.js', previewScriptOptions);


const fs: FileSystemAPI = container.fs;
const source = await fs.readFile('/src/main.js', 'utf8');
await fs.writeFile('/src/copy.js', source);
console.log(await fs.readdir('/src'));

const exportOptions: ExportOptions = { format: 'json' };
console.log(await container.export('/src', exportOptions));

const spawnOptions: SpawnOptions = { cwd: '/' };
const spawned: GroundpackProcess = await container.spawn('node', ['src/main.js'], spawnOptions);
spawned.output.pipeTo(new WritableStream({ write: console.log }));
console.log(await spawned.exit);

console.log(container.workdir);
console.log(container.path);

unsubscribeServerReady();
unsubscribePort();
unsubscribePreviewMessage();
container.teardown();

Where to go next

Open the templates workspace to see package installation, command-backed dev servers, Node HTTP servers, and framework previews running through the standard runtime path.

  • Use /templates/basic for a built-in Node.js HTTP server and HTML preview.
  • Use /templates/vite for the vanilla JavaScript Vite starter.
  • Use /templates/react, /templates/vue, /templates/svelte, /templates/angular, or /templates/solid for installed Vite-backed framework previews.
  • Use /templates/express-sqlite for an Express API backed by a SQLite database file.
  • Use /templates/next for a native Next.js App Router dev server and /templates/vitest for test execution.
  • Use /questions/flatten, /questions/promise-all, or /questions/use-counter for GreatFrontEnd-style question workspaces.