Low-level SDK
Client
The browser-side API for creating and controlling an isolated Node.js runtime. Use it when you want full control over files, commands, processes, and previews.
npm i @node-sandbox/clientCreate a sandbox
Pass a public, origin-scoped API key and a project source to Sandbox.create(). Creation prepares the filesystem and installs dependencies, but does not start a web server.
import { Sandbox } from '@node-sandbox/client';
const sandbox = await Sandbox.create({
apiKey: import.meta.env.VITE_NODESANDBOX_API_KEY,
source: {
type: 'git',
url: 'https://github.com/vercel/sandbox-example-next.git',
},
});API keys are intentionally public and only authorize exact origins configured in your dashboard.
Run commands
Use runCommand() for a program and argument list. It keeps arguments separate across the transport. Reach for runShell() only when you intentionally need shell syntax.
const version = await sandbox.runCommand('node', ['--version']);
console.log(version.stdout); // v22.14.0
const files = await sandbox.runShell('find src -name "*.tsx" | sort');
console.log(files.stdout);runCommand(program, args)Direct, safely separated arguments.
runShell(command)Pipes, redirects, variables, and shell expansion.
runScript(name)Run a finite package.json script.
commands.session()Keep a working directory and environment between calls.
Long-running processes
Spawn a dev server, stream its output, and wait for the exact listener you expect. The process handle exits early if startup fails and can be terminated explicitly.
const process = await sandbox.spawn('npm', ['run', 'dev']);
const stopListening = process.onOutput((chunk) => {
console.log(chunk);
});
const preview = await sandbox.waitForPort(3000, { process });
console.log(preview.url, preview.port);
// Later:
stopListening();
process.kill('SIGTERM');For the common case, start() spawns npm run dev and discovers the first HTTP listener. Pass { port: 3000 } when your application requires an exact port.
Project sources
Initialize from in-memory files, a ZIP archive, or a shallow Git checkout.
const files = await Sandbox.create({
apiKey,
source: { type: 'files', files: { 'index.js': 'console.log("hi")' } },
});
const zip = await Sandbox.create({
apiKey,
source: { type: 'zip', url: 'https://example.com/project.zip' },
});
const git = await Sandbox.create({
apiKey,
source: {
type: 'git',
url: 'https://github.com/org/repo.git',
ref: 'main',
},
});
const project = await Sandbox.create({
apiKey,
source: { type: 'project', projectId: 'project-id' },
});Lifecycle
Provide a stable sessionId when a runtime needs to retain the same isolated origin. Always dispose the runtime when its owning screen or session ends.
const sandbox = await Sandbox.create({
apiKey,
sessionId: 'project-preview-42',
source: { type: 'files', files },
});
window.addEventListener('pagehide', () => sandbox.dispose(), { once: true });