@fissionplane/sdk package connects your TypeScript and Node.js applications to a self-hosted FissionPlane installation. You can create and control isolated Firecracker microVM sandboxes, run commands, stream process output, manage files, expose ports, and build templates — all from a fully typed client.
Requirements
Before you install the SDK, make sure you have:- Node.js 20 or later
- A running FissionPlane control plane and its URL
- An API key or OIDC bearer token
- A template alias or template artifact ID to use when creating sandboxes
Installation
Configuration
Set your control plane URL and API key as environment variables so the client can pick them up automatically:accessToken instead of apiKey when authenticating with an OIDC bearer token. When you supply both, apiKey takes precedence. The constructor rejects an empty credential or one that contains whitespace.
Client Options
string
The URL of your FissionPlane control plane. Reads from the
FISSIONPLANE_API_URL environment variable when not provided.string
Your API key. Reads from the
FISSIONPLANE_API_KEY environment variable when not provided. Takes precedence over accessToken.string
An OIDC bearer token. Used when
apiKey is not set.number
default:"60000"
Milliseconds before a request is aborted. Set to
0 to disable timeouts entirely.number
default:"2"
Number of additional attempts after a failed request. The SDK spaces retries using exponential backoff with full jitter, starting at 250 ms. Set to
0 to disable retries. sandboxes.create() is retried only when you pass an idempotencyKey.Logger
An object with optional
debug, info, warn, and error methods. Receives messages about retries, capability token re-mints, and pagination. Passing console works as-is. The default logger discards all output.User-Agent: fissionplane-typescript/<version>. The SDK exports this string as userAgent if you need it in your own logging or tracing.
Per-Call Overrides
Every method acceptsrequestTimeoutMs, signal, and headers alongside its own parameters. A per-call requestTimeoutMs replaces the client default for that call only.
On
commands.attach() and files.watch(), requestTimeoutMs bounds the WebSocket handshake rather than the lifetime of the stream. Pass signal to close the stream itself. Your own headers win over the SDK’s defaults.Create a Sandbox and Run a Command
Sandbox creation returns after a node acknowledges the sandbox. Usecommands.run() when you need the command’s full output after it finishes.
commands.run() waits for the process to exit and returns its exit code, standard output, standard error, and an optional truncation flag. Use sandbox.commands.listProcesses() to list supervised processes, and sandbox.commands.kill(pid, 'SIGTERM') to send a signal to one.
Background Processes and PTY
When you need to follow output in real time or keep stdin open, start a background process withcommands.start(). Pass a pty option to allocate a pseudo-terminal.
Filesystem Operations
Filesystem calls go directly to the sandbox data plane. You can create directories, upload content, list entries, and watch for changes.Sandbox Lifecycle
A sandbox moves through four visible states:running, paused, terminated, and failed.
pause() snapshots the sandbox and releases the underlying node capacity. resume() restores the snapshot on a node and gives the sandbox a new epoch.
Capability tokens are scoped to a single sandbox epoch. After
resume(), the SDK automatically replaces the token on the handle. Handles returned by sandboxes.get() or sandboxes.iterate() carry no token — call sandbox.mintToken() before issuing commands on them. When the data plane rejects an expired token, the SDK mints a replacement and replays the request once automatically. Streams opened by commands.attach() and files.watch() require a valid token up front because a rejected WebSocket handshake is opaque to the SDK.idempotencyKey to sandboxes.create() so that retries return the same sandbox instead of creating a duplicate.
Port Exposure
Every sandbox port is private by default, accessible only with a capability token. Make a port public only when anonymous access is required.unexpose() removes the exposure record and returns the port to private access.
Build and Use a Template
Template builds run asynchronously on your FissionPlane installation. Start a build, wait for it to finish, then reference the template by alias.build.logs(offset). Pass nextOffset from each response into the next call to avoid re-reading lines. Use client.templates.getBuild(buildId) to reconnect to a build started in a previous process.
List Sandboxes
Read a single page of sandboxes filtered by state or metadata:iterate() to walk every page automatically. The SDK fetches the next page only when the previous one is exhausted, and it follows each page’s nextCursor until the collection ends.
iterate() accepts the same filters as list() except cursor. Break out of the loop to stop early.
Error Handling
All SDK errors inherit fromFissionPlaneError. HTTP errors carry status, code, retryable, and requestId when the server provides them.
Control Plane and Data Plane
The control plane manages sandboxes, ports, tokens, and templates. The sandbox data plane runs commands, streams process I/O, and accesses files. The SDK sends your API key or OIDC token to the control plane. It sends a short-lived capability token to the sandbox data plane, stored on the sandbox handle. The data-plane agent uses port50000 by default. Set agentPort in the client options only when your installation uses a different port. You can also supply a custom fetch implementation in the client options.
client.api exposes the generated, fully typed HTTP client for operations not wrapped by the SDK. Those calls carry your credentials, the SDK User-Agent, and the request timeout, but not the retry loop.
@fissionplane/sdk is version 0.0.1. The public API is unstable and may change without notice until the project publishes a stable release.