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

@brimble/sandbox

v0.1.5

Published

TypeScript SDK for the Brimble Sandbox API

Downloads

868

Readme

@brimble/sandbox

TypeScript SDK for the Brimble Sandbox API.

Install

npm install @brimble/sandbox

Testing

# Unit tests (mocked transport, no API key required)
npm run test

# Live integration test (creates a sandbox, runs a command, then destroys it)
BRIMBLE_SANDBOX_KEY=your_key_here npm run test:integration

# Run both
BRIMBLE_SANDBOX_KEY=your_key_here npm run test:all

Quickstart

import { CodeLanguage, Sandbox } from '@brimble/sandbox';

const client = new Sandbox();

const sandbox = await client.sandboxes.createReady({
  template: 'node-22',
  persistent: true,
  persistentDiskGB: 20,
  mountPath: '/workspace',
});

await sandbox.exec({ cmd: 'node -v', env: { NODE_ENV: 'production' } });

await sandbox.putFile('tmp/notes.txt', Buffer.from('hello sandbox'));
await sandbox.putFiles([
  { path: '/tmp/hello.txt', body: 'hello from batch' },
  { path: '/tmp/config.json', body: JSON.stringify({ mode: 'dev' }) },
]);
const stream = await sandbox.getFile('tmp/notes.txt');

await sandbox.runCode({
  language: CodeLanguage.Node,
  code: 'console.log(1 + 1)',
  env: { FEATURE_FLAG: 'on' },
});

// Handle-first lifecycle on existing sandboxes.
const existingSandbox = await client.sandboxes.get(sandbox.id);
await existingSandbox.destroy();

Set BRIMBLE_SANDBOX_KEY in your environment.
If needed, pass apiKey explicitly in the constructor; explicit value wins over env.

Ergonomic helpers

// 1) Create + wait in one call
const created = await client.sandboxes.createReady({ template: 'node-22' });

// 2) Get + wait in one call
const loaded = await client.sandboxes.getReady(created.id);

// 3) Create a volume + attach in one call
const withVolume = await client.sandboxes.withVolume({
  sandbox: { template: 'node-22', mountPath: '/var/www/html' },
  volume: { name: 'workspace-disk', sizeGB: 20 },
});

// 4) Auto-wait at runtime call sites
await withVolume.exec({ cmd: 'npm -v' }, { waitUntilReady: true });

// Streaming SSE output (stream: true returns ReadableStream<Uint8Array>)
const sse = await withVolume.exec({ cmd: 'for i in 1 2 3; do echo $i; done', stream: true });

// 5) List templates/regions
const templates = await client.sandboxes.listTemplates();
const nodeTemplate = await client.sandboxes.getTemplate('node-22');
const { regions } = await client.sandboxes.listRegions();

// 6) Async iterators for pagination
for await (const sandbox of client.sandboxes.iterate({ teamId: '<team>' })) {
  console.log(sandbox.id, sandbox.status);
}

Handle composition

const sandbox = await client.sandboxes.get('<sandbox-id>');

await sandbox.snapshots.create({ name: 'before-migration' });

Volume attachment is create-time only.
Use client.sandboxes.create({ ..., volumeId }) or client.sandboxes.withVolume(...).

Retry, timeouts, and idempotency

const client = new Sandbox({
  timeoutMs: 30_000,
  retry: {
    maxAttempts: 3,
    baseDelayMs: 250,
    maxDelayMs: 2_000,
  },
});

await client.sandboxes.create(
  { template: 'node-22' },
  { idempotencyKey: 'create-sandbox-123' },
);

If region is omitted, the SDK resolves the first available sandbox region automatically.

Resources

  • client.sandboxes
    • create, createReady, withVolume, list, iterate, get, getReady, listRegions, listTemplates, getTemplate, destroy, pause, resume, quickstartNode, quickstartPython, use
  • sandbox handle (returned from create/get/list)
    • waitUntilReady, refresh, destroy, pause, resume, exec, runCode, putFile, putFiles, getFile, stats, createSnapshot, listSnapshots, snapshots.create, snapshots.list
  • client.sandboxes.use(id)
    • destroy, exec, runCode, putFile, putFiles, getFile, stats, createSnapshot, listSnapshots
  • client.snapshots
    • listAll, iterateAll, delete
  • client.volumes
    • list, iterate, create, get, delete

Errors

HTTP errors throw typed errors:

  • AuthError
  • ValidationError
  • NotFoundError
  • RateLimitError
  • SandboxApiError

All include:

  • status
  • message
  • endpoint
  • responseBody
  • requestId