ViteHub

Sandbox runtime API

Reference for Sandbox exports, definition options, execution options, result objects, and validation helpers.

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'

Vite config imports the plugin from @vitehub/sandbox/vite:

import { hubSandbox } from '@vitehub/sandbox/vite'

hubSandbox(options?) accepts the same integration options as vite.config.sandbox. When both are present, vite.config.sandbox takes precedence.

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:

ArgumentTypeDescription
payload`TPayloadundefined`
context`Record<string, unknown>undefined`

SandboxDefinitionOptions

These options are portable across providers:

OptionTypeDescription
timeoutnumberMaximum execution time in milliseconds where the provider supports it.
envRecord<string, string>Environment variables passed to the sandbox process.
runtime.commandstringOverride the command used to launch the bundled sandbox definition.
runtime.argsstring[]Extra arguments for the runtime command.
Definition options must be static JSON-serializable values. The build step extracts them only from a direct 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:

OptionTypeDescription
contextRecord<string, unknown>Request-scoped or caller-scoped data available as the second handler argument.
sandboxIdstringRequest 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 / FieldTypeDescription
isOk()() => booleanReturns true when execution succeeded.
isErr()() => booleanReturns true when execution failed.
valueTThe sandbox return value. Read only after isOk().
errorSandboxErrorError 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:

FieldDescription
messageHuman-readable failure message.
codeStable error code when available.
providerProvider that produced the error when available.
detailsProvider 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,
}
Copyright © 2026