npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@unikernelai/sandbox

v1.4.0

Published

TypeScript SDK for the Unikernel AI sandbox — isolated code execution with sub-second cold starts

Readme

@unikernelai/sandbox

TypeScript SDK for the Unikernel AI sandbox API. Run Python, Node.js, and shell code in isolated unikernel VMs with sub-second cold starts.

Install

npm install @unikernelai/sandbox

Quick Start

Fastest path: Create sandbox + run code in one call (recommended)

The combined create+execute API gets you a sandbox and the first execution result in a single network round trip — 56% faster than the traditional two-step approach.

import { UnikernelsClient } from "@unikernelai/sandbox";

const client = new UnikernelsClient({
  apiKey: "your-api-key",
});

// Create sandbox AND run initial code in 1 request (~350ms vs ~750ms)
const { sandbox, initialResult } = await client.createSandbox({
  initialCommand: "echo hello && node -v",
});

console.log(initialResult?.stdout); // "hello\nv20.20.2\n"

// Subsequent commands reuse the same sandbox
const result = await sandbox.execute({
  language: "nodejs",
  code: `console.log(JSON.stringify({ ts: Date.now() }))`,
});

await sandbox.delete();

One-shot execution (stateless, no sandbox)

For simple, single executions where you don't need persistent state:

import { UnikernelsClient } from "@unikernelai/sandbox";

const client = new UnikernelsClient({ apiKey: "your-api-key" });

// Run Node.js
const result = await client.execute({
  language: "nodejs",
  code: `console.log("Hello from a unikernel!")`,
  timeout_ms: 5000,
});
console.log(result.stdout); // "Hello from a unikernel!\n"

// Run Python
const py = await client.execute({
  language: "python",
  code: `print(sum(range(100)))`,
});
console.log(py.stdout); // "4950\n"

// Run shell commands
const sh = await client.command({
  command: `echo "OS: $(uname -s)" && date`,
});
console.log(sh.stdout);

Sandbox sessions (stateful)

Sandboxes maintain state across multiple executions — files, dependencies, and git repos persist for the session lifetime (default 15 minutes).

const { sandbox } = await client.createSandbox();

// Execute code in the sandbox
const result = await sandbox.execute({
  language: "python",
  code: `x = 42; print(x)`,
});

// Upload a file
await sandbox.uploadFile("data.txt", btoa("hello world"));

// List files
const files = await sandbox.listFiles();

// Install dependencies
await sandbox.installDependencies("python", [
  { name: "requests", version: "2.31.0" },
]);

// Clean up when done
await sandbox.delete();

Configuration

const client = new UnikernelsClient({
  // Default: https://sandbox.unikernel.ai (production)
  baseUrl: "https://sandbox.unikernel.ai",

  // API key authentication (recommended for execution)
  apiKey: "uk_live_...",

  // Or Bearer JWT auth (required for API key management)
  authToken: "your-jwt-token",

  // Default timeout for all execute/command calls (ms)
  // Per-call timeout_ms overrides this value
  defaultTimeoutMs: 5000,

  // Custom fetch implementation (useful for testing or Node.js <18)
  fetchImpl: customFetch,
});

Timeout Configuration

// Set a global default (applies to execute, command, executeInSandbox)
const client = new UnikernelsClient({
  apiKey: "uk_live_...",
  defaultTimeoutMs: 5000, // 5 seconds for all calls
});

// Override per-call when needed
const result = await client.execute({
  language: "python",
  code: "import time; time.sleep(7); print('done')",
  timeout_ms: 8000, // this call gets 8s, others still get 5s
});

API Reference

UnikernelsClient

| Method | Description | |--------|-------------| | execute(params) | One-shot stateless code execution | | command(params) | Run a shell command (stateless) | | getCapabilities() | Get supported runtimes and limits | | createSandbox(options?) | Create a sandbox session (optionally with initial command) | | getSandboxHandle(id) | Get a Sandbox handle by ID without an API call | | getSandbox(id) | Fetch sandbox details from server | | deleteSandbox(id) | Delete a sandbox | | createApiKey(input?) | Create an API key (requires Bearer auth) | | listApiKeys() | List your API keys (requires Bearer auth) | | revokeApiKey(id) | Revoke an API key (requires Bearer auth) |

createSandbox(options?)

The recommended way to create sandboxes. Pass an initial command to eliminate one network round trip:

// Option A: initial shell command (simplest)
const { sandbox, initialResult } = await client.createSandbox({
  initialCommand: "node -v && npm -v",
});

// Option B: initial code in a specific language
const { sandbox, initialResult } = await client.createSandbox({
  initialCode: "console.log(JSON.stringify({ ready: true }))",
  initialLanguage: "nodejs",
  initialTimeoutMs: 5000,
});

// Option C: plain create (no initial execution)
const { sandbox } = await client.createSandbox();

Returns: CreateSandboxResult

type CreateSandboxResult = {
  sandbox: Sandbox;
  initialResult?: ExecutionResult; // Present when initial command/code was provided
};

Sandbox

| Method | Description | |--------|-------------| | execute(params) | Execute code in this sandbox | | refresh() | Refresh sandbox metadata from server | | delete() | Delete the sandbox and release resources | | uploadFile(path, contentBase64) | Upload a file | | downloadFile(path) | Download a file | | listFiles(path?) | List files in directory | | deleteFile(path) | Delete a file | | installDependencies(language, deps) | Install pip/npm packages | | listDependencies(language?) | List installed packages | | gitStatus() | Get git working tree status | | gitCommit(input) | Create a git commit | | gitBranches() | List branches | | gitCreateBranch(branch, from?) | Create a branch | | gitCheckout(branch) | Switch branches | | applySnapshot(snapshotId) | Apply a snapshot template |

The Sandbox object also exposes:

  • sandbox.id — the sandbox session ID
  • sandbox.initialResult — the result of the initial command (if provided at creation)

Types

type SupportedLanguage = "python" | "nodejs" | "shell";

type ExecutionResult = {
  status: "success" | "error" | "timeout";
  stdout: string;
  stderr: string;
  execution_time_ms: number;
};

type CreateSandboxOptions = {
  initialCommand?: string;        // Shell command to run immediately
  initialCode?: string;           // Code to execute (requires initialLanguage)
  initialLanguage?: SupportedLanguage;
  initialTimeoutMs?: number;      // Timeout for initial execution
};

type CreateSandboxResult = {
  sandbox: Sandbox;
  initialResult?: ExecutionResult;
};

type SandboxSession = {
  id: string;
  state: "active" | "deleted";
  createdAt: string;
  updatedAt: string;
  expiresAt: string;
  executionCount: number;
};

Supported Languages

| Language | Value | Runtime | |----------|-------|---------| | Python | "python" | Python 3.12 | | Node.js | "nodejs" | Node.js 20 | | Shell | "shell" | Bash |

Authentication

There are three authentication modes:

  1. Self-service provision — no auth needed, get a free-tier API key instantly
  2. API Key (x-api-key header) — for executing code and sandbox operations
  3. Bearer JWT (Authorization: Bearer <token>) — for API key management
// Easiest: provision a key with zero auth (rate-limited by IP)
const client = new UnikernelsClient();
const key = await client.provision("[email protected]");
// key.key = "uk_live_..." — use this for all future calls

// For execution (most users)
const authed = new UnikernelsClient({ apiKey: key.key });

// For API key management (requires JWT)
const admin = new UnikernelsClient({ authToken: "your-jwt-token" });
const newKey = await admin.createApiKey({ label: "my-agent" });

Agent Integration

Zero-to-executing in 3 lines

import { UnikernelsClient } from "@unikernelai/sandbox";

const client = new UnikernelsClient();
const key = await client.provision();
const authed = new UnikernelsClient({ apiKey: key.key });

const result = await authed.execute({
  language: "nodejs",
  code: `console.log("Agent is live!")`,
});

As an MCP Server (Claude, Cursor, etc.)

{
  "mcpServers": {
    "unikernel-sandbox": {
      "command": "npx",
      "args": ["-y", "@unikernelai/sandbox-cli", "mcp"]
    }
  }
}

CLI one-liner for agents

npm i -g @unikernelai/sandbox-cli && unik auth login --headless && unik sandbox run python "print('ready')"

Error Handling

import { UnikernelsApiError } from "@unikernelai/sandbox";

try {
  await client.execute({ language: "python", code: "print(1)" });
} catch (err) {
  if (err instanceof UnikernelsApiError) {
    console.error(err.statusCode, err.code, err.message);
    // 429 "rate_limited" "Rate limit exceeded for this identity."
  }
}

Common Error Codes

| Code | Status | Meaning | |------|--------|---------| | invalid_payload | 400 | Malformed request body | | unsupported_language | 422 | Language not supported | | disallowed_capability | 422 | Code uses blocked APIs (fs, net, etc.) | | code_too_large | 413 | Code exceeds 64KB limit | | timeout_exceeds_limit | 422 | Timeout > 8000ms | | sandbox_not_found | 404 | Sandbox doesn't exist | | sandbox_deleted | 409 | Sandbox already deleted or expired | | unauthorized | 401 | Missing/invalid credentials | | rate_limited | 429 | Per-minute rate limit hit | | daily_quota_exceeded | 429 | Daily quota exhausted |

Performance

Requests are automatically geo-routed to the nearest region via Cloudflare:

| Region | Sequential exec p50 | Parallel burst p50 | Sandbox TTI | |--------|---------------------|-------------------|-------------| | Frankfurt (FRA) | 35 ms | 85 ms | 50 ms | | San Francisco (SFO) | 56 ms | 74 ms | 46 ms | | Singapore (SIN) | 33 ms | 85 ms | 46 ms |

Measured from colocated Fly.io machines in each region (Jun 2025).

Geo-routing: The default endpoint https://sandbox.unikernel.ai routes to the nearest datacenter automatically:

  • Americas → SFO
  • Asia-Pacific → SIN
  • Europe / Africa / Middle East → FRA

You can override region selection with ?region=fra|sfo|sin or the X-Region header.

Tip: Always use createSandbox({ initialCommand: "..." }) instead of creating a sandbox and then running a command separately. It saves one full network round trip.

License

MIT