Sandbox runtime API
Use this page when you need exact names, signatures, and option fields. For a guided setup, start with Quickstart.
Imports
Most application code imports from @vitehub/sandbox:
import {
defineSandbox,
readRequestPayload,
readValidatedPayload,
runSandbox,
} from '@vitehub/sandbox'
Nitro config registers the module by name:
export default defineNitroConfig({
modules: ['@vitehub/sandbox/nitro'],
})
Definition API
defineSandbox(handler, options?)
Default-export defineSandbox() from every discovered sandbox definition.
import { defineSandbox } from '@vitehub/sandbox'
export default defineSandbox(async (payload?: { notes?: string }) => {
return {
notes: payload?.notes || '',
}
}, {
timeout: 30_000,
env: {
NODE_ENV: 'production',
},
})
The handler receives:
| Argument | Type | Description |
|---|---|---|
payload | `TPayload | undefined` |
context | `Record<string, unknown> | undefined` |
SandboxDefinitionOptions
These options are portable across providers:
| Option | Type | Description |
|---|---|---|
timeout | number | Maximum execution time in milliseconds where the provider supports it. |
env | Record<string, string> | Environment variables passed to the sandbox process. |
runtime.command | string | Override the command used to launch the bundled sandbox definition. |
runtime.args | string[] | Extra arguments for the runtime command. |
export default defineSandbox(handler, options) call in the discovered sandbox file. These are non-identity Definition Options; the sandbox's Discovery Identity still comes from its file path.Execution API
runSandbox(name, payload?, options?)
Use runSandbox() to execute one named sandbox.
import { runSandbox } from '@vitehub/sandbox'
const result = await runSandbox('release-notes', {
notes: '- Added weekly digest',
})
if (result.isOk()) {
console.log(result.value.summary)
}
runSandbox() returns a result object instead of throwing for provider or runtime execution failures.
SandboxExecutionOptions
Pass these options as the third argument:
| Option | Type | Description |
|---|---|---|
context | Record<string, unknown> | Request-scoped or caller-scoped data available as the second handler argument. |
sandboxId | string | Request a stable sandbox identity when the provider supports reuse. |
const result = await runSandbox('release-notes', payload, {
context: {
requestId: event.context.requestId,
},
sandboxId: 'release-notes-writer',
})
Result API
SandboxRunResult<T>
runSandbox() returns SandboxRunResult<T>.
| Method / Field | Type | Description |
|---|---|---|
isOk() | () => boolean | Returns true when execution succeeded. |
isErr() | () => boolean | Returns true when execution failed. |
value | T | The sandbox return value. Read only after isOk(). |
error | SandboxError | Error details. Read only after isErr(). |
const result = await runSandbox('release-notes', payload)
if (result.isErr()) {
throw createError({ statusCode: 500, statusMessage: result.error.message })
}
return result.value
SandboxError
Provider and execution failures are normalized to SandboxError.
Useful fields include:
| Field | Description |
|---|---|
message | Human-readable failure message. |
code | Stable error code when available. |
provider | Provider that produced the error when available. |
details | Provider or execution diagnostics when available. |
Request helpers
readRequestPayload(event, fallback?)
Read a JSON request body once with a fallback value.
import { readRequestPayload } from '@vitehub/sandbox'
const payload = await readRequestPayload(event, { notes: '' })
Use it in H3 routes before calling runSandbox().
Validation helpers
readValidatedPayload(payload, validate, options?)
Validate an already-read value. The validator can be a Standard Schema compatible validator or a function.
import { readRequestPayload, readValidatedPayload } from '@vitehub/sandbox'
const body = await readRequestPayload(event, { notes: '' })
const payload = await readValidatedPayload(body, (value) => {
if (!value || typeof value !== 'object') return false
return {
notes: String((value as { notes?: unknown }).notes || ''),
}
})
Provider config
The top-level config key is sandbox.
sandbox: {
provider: 'cloudflare',
binding: 'SANDBOX',
sandboxId: 'shared-sandbox',
sleepAfter: '5m',
keepAlive: true,
normalizeId: true,
}
sandbox: {
provider: 'vercel',
runtime: 'node22',
timeout: 30_000,
cpu: 2,
ports: [3000],
token: process.env.VERCEL_TOKEN,
teamId: process.env.VERCEL_TEAM_ID,
projectId: process.env.VERCEL_PROJECT_ID,
}

