| title | SDK Overview |
|---|---|
| description | Guided tour of the secure-exec API surface. |
| icon | compass |
bun add secure-execpnpm add secure-execyarn add secure-execEvery sandbox has two layers:
- System driver provides host capabilities: filesystem, network, child processes, and permissions.
- The execution environment runs code in a V8 isolate (Node) or Web Worker (browser).
All host capabilities are deny-by-default. You opt in to what sandboxed code can access.
```ts import { NodeRuntime, createNodeDriver, createNodeRuntimeDriverFactory, } from "secure-exec";const runtime = new NodeRuntime({
systemDriver: createNodeDriver(),
runtimeDriverFactory: createNodeRuntimeDriverFactory(),
});
```
const runtime = new NodeRuntime({
systemDriver: await createBrowserDriver({ filesystem: "memory" }),
runtimeDriverFactory: createBrowserRuntimeDriverFactory(),
});
```
Two methods for running sandboxed code:
// exec() — process-style execution with stdout/stderr observation
const execResult = await runtime.exec("console.log('hello')");
console.log(execResult.code); // 0
// run() — export-based evaluation, returns computed values
const runResult = await runtime.run<{ default: number }>(
"export default 2 + 2"
);
console.log(runResult.exports?.default); // 4Use exec() for automation loops, CLI-style output capture, and per-call environment overrides. Use run() when the sandbox should return a value via export. See exec vs run for the full comparison.
Console output is not buffered by default. Use the onStdio hook to capture it:
const logs: string[] = [];
await runtime.exec("console.log('hello'); console.error('oops')", {
onStdio: (event) => logs.push(`[${event.channel}] ${event.message}`),
});
// logs: ["[stdout] hello", "[stderr] oops"]You can also set a default hook on the runtime:
const runtime = new NodeRuntime({
systemDriver: createNodeDriver(),
runtimeDriverFactory: createNodeRuntimeDriverFactory(),
onStdio: (event) => console.log(event.message),
});See Output Capture for more patterns.
Optional companion package for sandboxed type checking and compilation:
pnpm add @secure-exec/typescriptimport { createTypeScriptTools } from "@secure-exec/typescript";
const ts = createTypeScriptTools({
systemDriver: createNodeDriver(),
runtimeDriverFactory: createNodeRuntimeDriverFactory(),
});console.log(result.success); // false
console.log(result.diagnostics[0].message);
// "Type 'string' is not assignable to type 'number'."
```
for (const d of result.diagnostics) {
console.log(`${d.filePath}:${d.line} ${d.message}`);
}
```
console.log(result.outputText);
// "const x = 42; export default x;"
```
console.log(result.emittedFiles); // ["/app/dist/index.js", ...]
console.log(result.success); // true
```
See TypeScript.
All capabilities are blocked unless you opt in:
import { createNodeDriver, allowAll, allowAllFs } from "secure-exec";
// Allow everything
const driver = createNodeDriver({ permissions: allowAll });
// Allow only filesystem
const fsOnly = createNodeDriver({ permissions: { fs: allowAllFs } });
// Custom check
const filtered = createNodeDriver({
permissions: {
network: (req) => req.hostname !== "internal.corp",
},
});See Permissions for the full API.
Prevent runaway execution with CPU and memory bounds:
const runtime = new NodeRuntime({
systemDriver: createNodeDriver(),
runtimeDriverFactory: createNodeRuntimeDriverFactory(),
memoryLimit: 64, // MB
cpuTimeLimitMs: 5000,
});See Resource Limits for payload limits and per-execution overrides.
import { createNodeDriver, allowAllFs } from "secure-exec";
const driver = createNodeDriver({
permissions: { fs: allowAllFs },
});Three filesystem backends are available: Node.js host fs, in-memory, and OPFS (browser). See Filesystem.
import { createNodeDriver, allowAllNetwork } from "secure-exec";
const driver = createNodeDriver({
useDefaultNetwork: true,
permissions: { network: allowAllNetwork },
});See Networking.
runtime.dispose();