Skip to main content
The Podflare TypeScript SDK is an ESM-only package that exposes a Sandbox class with a static async factory. Every method returns a Promise (or AsyncGenerator for streaming), so you can use it naturally with async/await and for await. The package ships TypeScript declarations for all public types — no @types/ package needed.

Installation

Install the package from npm. Node 20 or later is required.
npm install podflare

Configuration

1

Set the host

By default Sandbox.create() reads PODFLARE_HOST from process.env and falls back to http://127.0.0.1:7070. Pass options to Sandbox.create() to override, or share a Client instance across many sandboxes.
import { Sandbox, Client } from "podflare";

// Reads PODFLARE_HOST env var, falls back to http://127.0.0.1:7070
const sbx = await Sandbox.create();

// Explicit host
const sbx = await Sandbox.create({ host: "https://api.podflare.dev" });

// Shared Client — one underlying connection for many sandboxes
const client = new Client({ host: "https://api.podflare.dev" });
const a = await Sandbox.create({ client });
const b = await Sandbox.create({ client });
2

Set the API key

Pass your key as apiKey in the options object or export PODFLARE_API_KEY so every Sandbox.create() call picks it up automatically.
import { Sandbox } from "podflare";

// Explicit
const sbx = await Sandbox.create({ apiKey: "pk_your_key_here" });

// Or via environment variable: PODFLARE_API_KEY=pk_...
const sbx2 = await Sandbox.create();
For local development without an API key, the SDK falls back to http://127.0.0.1:7070 automatically. See Authentication for details.

Core methods

Sandbox.create

static create(options?: { host?: string; apiKey?: string; client?: Client }): Promise<Sandbox>
The only way to construct a Sandbox. Returns a fully initialized instance ready to accept calls. Always await it.
const sbx = await Sandbox.create({ host: "https://api.podflare.dev" });

runCode

runCode(code: string, language?: Language): Promise<ExecResult>
Runs code inside the sandbox and resolves with an ExecResult once the process exits.
const r = await sbx.runCode("print(sum(range(10)))");
console.log(r.stdout, r.exitCode);

runCodeStream

runCodeStream(code: string, language?: Language): AsyncGenerator<Event>
Returns an async generator that yields Event objects as they arrive. Use this to display output token-by-token without waiting for the run to finish.
for await (const ev of sbx.runCodeStream("for i in range(3): print(i)")) {
  if (ev.type === "stdout") process.stdout.write(ev.data + "\n");
}

fork

fork(n?: number): Promise<Sandbox[]>
Snapshots the running sandbox and resolves with an array of n independent children, each inheriting the parent’s current memory and filesystem state. Children boot in parallel, so spawning 5 costs roughly the same wall-clock time as spawning 1.
const children = await parent.fork(5);
See the Fork concept page for full semantics, timing benchmarks, and the tree-search pattern.

diff

diff(other: Sandbox, paths?: string[]): Promise<{ added: string[]; removed: string[]; modified: string[] }>
Returns a filesystem diff between this sandbox and other. Defaults to comparing /root and /tmp; pass paths to restrict the scan.
const d = await a.diff(b);
// { added: [...], removed: [...], modified: [...] }

mergeInto

mergeInto(winner: Sandbox): Promise<void>
Commits winner’s filesystem and memory state as the new state of the parent. After this call, the parent’s ID remains valid and drives winner’s VM. Calling winner.close() becomes a no-op.
await parent.mergeInto(winner);

upload and download

upload(data: Uint8Array, remotePath: string): Promise<void>
download(remotePath: string): Promise<Uint8Array>
Transfer small files to and from the sandbox filesystem. Best suited for files up to a few MB.
await sbx.upload(new TextEncoder().encode("hello"), "/root/hello.txt");
const bytes = await sbx.download("/root/hello.txt");
console.log(new TextDecoder().decode(bytes)); // "hello"

close

close(): Promise<void>
Destroys the sandbox and releases its resources. Always call close() in a finally block so the sandbox is cleaned up even when an error is thrown.
const sbx = await Sandbox.create();
try {
  const r = await sbx.runCode("print('hello')");
  console.log(r.stdout);
} finally {
  await sbx.close();
}

Full example — fork, evaluate, merge

The following example loads a dataset once, forks five children to run different queries in parallel, selects the winner, and merges its state back into the parent.
import { Sandbox } from "podflare";

function pickBestIndex(results: { exitCode: number }[]): number {
  return results.findIndex((r) => r.exitCode === 0);
}

const parent = await Sandbox.create();
try {
  await parent.runCode(`
    import pandas as pd
    df = pd.read_csv('/data/medium.csv')
  `);

  const plans = [
    "print(df['col_a'].mean())",
    "print(df['col_b'].mean())",
    "print(df[df.col_a > 0].shape)",
    "print(df.describe().loc['mean'])",
    "print(df.corr().iloc[0])",
  ];

  const children = await parent.fork(plans.length);
  try {
    const results = await Promise.all(
      children.map((c, i) => c.runCode(plans[i]))
    );
    const winner = children[pickBestIndex(results)];
    await parent.mergeInto(winner);
  } finally {
    for (const c of children) await c.close();
  }
} finally {
  await parent.close();
}

Vercel AI SDK adapter

Use the "podflare/ai-sdk" subpath import to get a pre-built tool definition compatible with the Vercel AI SDK’s generateText and streamText APIs.
import { tool } from "ai";
import { z } from "zod";
import { generateText } from "ai";
import { anthropic } from "@ai-sdk/anthropic";
import { podflareRunCode } from "podflare/ai-sdk";

const pf = podflareRunCode();

const { text } = await generateText({
  model: anthropic("claude-opus-4-7"),
  tools: {
    runCode: tool({
      description: pf.description,
      parameters: z.object({
        code: z.string(),
        language: z.enum(["python", "bash"]).optional(),
      }),
      execute: pf.execute,
    }),
  },
  prompt: "Use runCode to compute sqrt(12345)",
});

await pf.close();
See Vercel AI SDK for the full integration guide.

Types

All public types are exported from the top-level module. Import them with import type to keep your bundle size unchanged.
import type { Sandbox, Event, ExecResult, Language } from "podflare";
ExecResult
interface
Resolved by runCode. Fields: stdout: string, stderr: string, exitCode: number.
Event
interface
Yielded by runCodeStream. Fields: type: "stdout" | "stderr" | "exit", data: string.
Language
type
"python" | "bash" — accepted by runCode and runCodeStream.