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

computesdk

v2.3.0

Published

A free and open-source toolkit for running other people's code in your applications.

Readme

computesdk

The gateway SDK for running code in remote sandboxes. Zero-config auto-detection with support for E2B, Modal, Railway, Daytona, Vercel, and more.

Installation

npm install computesdk

Quick Start

Zero-Config Mode (Recommended)

Set your provider credentials as environment variables and ComputeSDK automatically detects and configures everything:

export E2B_API_KEY=your_e2b_api_key
import { compute } from 'computesdk';

// Auto-detects E2B from environment
const sandbox = await compute.sandbox.create();

// Execute code
const result = await sandbox.runCode('print("Hello World!")');
console.log(result.output); // "Hello World!"

// Clean up
await sandbox.destroy();

Explicit Configuration

For more control, use setConfig() to explicitly configure the provider:

import { compute } from 'computesdk';

compute.setConfig({
  provider: 'your-provider',
  apiKey: process.env.COMPUTESDK_API_KEY,
  'your-provider': {
    apiKey: process.env.YOUR_PROVIDER_API_KEY
  }
});

const sandbox = await compute.sandbox.create();

Supported Providers

ComputeSDK automatically detects providers based on environment variables:

| Provider | Environment Variables | Use Cases | |----------|----------------------|-----------| | E2B | E2B_API_KEY | Data science, Python/Node.js, interactive terminals | | Modal | MODAL_TOKEN_ID, MODAL_TOKEN_SECRET | GPU computing, ML inference, Python workloads | | Railway | RAILWAY_TOKEN | Full-stack deployments, persistent storage | | Daytona | DAYTONA_API_KEY | Development workspaces, custom environments | | Runloop | RUNLOOP_API_KEY | Code execution, automation | | Vercel | VERCEL_TOKEN or VERCEL_OIDC_TOKEN | Serverless functions, web apps | | Cloudflare | CLOUDFLARE_API_TOKEN | Edge computing | | CodeSandbox | CODESANDBOX_TOKEN | Collaborative development |

Provider Detection Order

When using zero-config mode, ComputeSDK detects providers in this order:

E2B → Railway → Daytona → Modal → Runloop → Vercel → Cloudflare → CodeSandbox

You can force a specific provider:

export COMPUTESDK_PROVIDER=modal

API Reference

Configuration

compute.setConfig(config)

Configure the gateway with explicit provider settings.

compute.setConfig({
  provider: 'your-provider',
  apiKey: process.env.COMPUTESDK_API_KEY,
  'your-provider': {
    apiKey: process.env.YOUR_PROVIDER_API_KEY
  }
});

Provider-specific configs:

// E2B
compute.setConfig({
  provider: 'e2b',
  apiKey: process.env.COMPUTESDK_API_KEY,
  e2b: { 
    apiKey: 'e2b_xxx',
    templateId: 'optional_template' 
  }
});

// Modal
compute.setConfig({
  provider: 'modal',
  apiKey: process.env.COMPUTESDK_API_KEY,
  modal: { 
    tokenId: 'ak-xxx',
    tokenSecret: 'as-xxx'
  }
});

// Railway
compute.setConfig({
  provider: 'railway',
  apiKey: process.env.COMPUTESDK_API_KEY,
  railway: { 
    apiToken: 'your_token',
    projectId: 'project_id',
    environmentId: 'env_id'
  }
});

// Daytona
compute.setConfig({
  provider: 'daytona',
  apiKey: process.env.COMPUTESDK_API_KEY,
  daytona: { apiKey: 'your_api_key' }
});

// Vercel
compute.setConfig({
  provider: 'vercel',
  apiKey: process.env.COMPUTESDK_API_KEY,
  vercel: { 
    token: 'your_token',
    teamId: 'team_xxx',
    projectId: 'prj_xxx'
  }
});

Sandbox Management

compute.sandbox.create(options?)

Create a new sandbox.

const sandbox = await compute.sandbox.create();

// With options
const sandbox = await compute.sandbox.create({
  timeout: 300000, // 5 minutes
  metadata: { userId: '123' },
  namespace: 'my-org',
  name: 'my-sandbox',
});

Options:

  • timeout?: number - Timeout in milliseconds
  • metadata?: Record<string, any> - Custom metadata
  • envs?: Record<string, string> - Environment variables
  • namespace?: string - Namespace for organizing sandboxes
  • name?: string - Name for the sandbox (enables findOrCreate)
  • overlays?: SetupOverlayConfig[] - Template overlays to apply
  • servers?: ServerStartOptions[] - Servers to start automatically

compute.sandbox.getById(sandboxId)

Get an existing sandbox by ID.

const sandbox = await compute.sandbox.getById('sandbox-id');

compute.sandbox.findOrCreate(options)

Find an existing sandbox by namespace and name, or create a new one.

const sandbox = await compute.sandbox.findOrCreate({
  namespace: 'my-org',
  name: 'my-project',
});

compute.sandbox.find(options)

Find an existing sandbox by namespace and name (returns null if not found).

const sandbox = await compute.sandbox.find({
  namespace: 'my-org',
  name: 'my-project',
});

Sandbox Operations

sandbox.runCode(code, language?)

Execute code in the sandbox.

const result = await sandbox.runCode('print("Hello")', 'python');
console.log(result.output); // "Hello"
console.log(result.exitCode);

sandbox.runCommand(command, options?)

Run a shell command.

const result = await sandbox.runCommand('npm install express');
console.log(result.stdout);
console.log(result.exitCode);

// With options
const result = await sandbox.runCommand('npm install', {
  cwd: '/app',
  env: { NODE_ENV: 'production' },
  background: true,
});

sandbox.destroy()

Destroy the sandbox and clean up resources.

await sandbox.destroy();

Filesystem Operations

The sandbox provides full filesystem access:

sandbox.filesystem.writeFile(path, content)

Write a file to the sandbox.

await sandbox.filesystem.writeFile('/tmp/hello.py', 'print("Hello World")');

sandbox.filesystem.readFile(path)

Read a file from the sandbox.

const content = await sandbox.filesystem.readFile('/tmp/hello.py');
console.log(content); // 'print("Hello World")'

sandbox.filesystem.mkdir(path)

Create a directory.

await sandbox.filesystem.mkdir('/tmp/mydir');

sandbox.filesystem.readdir(path)

List directory contents.

const files = await sandbox.filesystem.readdir('/tmp');
console.log(files); // [{ name: 'hello.py', type: 'file', size: 123 }, ...]

sandbox.filesystem.exists(path)

Check if a file or directory exists.

const exists = await sandbox.filesystem.exists('/tmp/hello.py');
console.log(exists); // true

sandbox.filesystem.remove(path)

Remove a file or directory.

await sandbox.filesystem.remove('/tmp/hello.py');

Terminal Operations

The sandbox provides terminal access in two modes: PTY mode (interactive shell) and Exec mode (command tracking).

sandbox.terminal.create(options?)

Create a new terminal session.

// PTY mode - Interactive shell
const pty = await sandbox.terminal.create({ pty: true, shell: '/bin/bash' });

// Exec mode - Command tracking (default)
const exec = await sandbox.terminal.create({ pty: false });

Options:

  • pty?: boolean - Terminal mode: true = PTY (interactive), false = exec (command tracking). Default: false
  • shell?: string - Shell to use (e.g., '/bin/bash'). PTY mode only
  • encoding?: 'raw' | 'base64' - Output encoding. Default: 'raw'

Returns: TerminalInstance

sandbox.terminal.list()

List all active terminals.

const terminals = await sandbox.terminal.list();
console.log(terminals); // [{ id: 'term-1', pty: true, status: 'running', ... }]

sandbox.terminal.retrieve(id)

Retrieve a specific terminal by ID.

const terminal = await sandbox.terminal.retrieve('term-123');
console.log(terminal.id, terminal.status);

sandbox.terminal.destroy(id)

Destroy a terminal by ID.

await sandbox.terminal.destroy('term-123');

PTY Mode (Interactive Shell)

PTY mode creates an interactive shell session with real-time input/output over WebSocket.

terminal.write(input)

Send input to the terminal shell.

const pty = await sandbox.terminal.create({ pty: true });
pty.on('output', (data) => console.log(data));
pty.write('ls -la\n');
pty.write('pwd\n');
await pty.destroy();

terminal.resize(cols, rows)

Resize the terminal window.

pty.resize(120, 40);

terminal.on(event, handler)

Register an event handler. Events: 'output', 'error', 'destroyed'.

pty.on('output', (data) => console.log('Output:', data));
pty.on('error', (error) => console.error('Error:', error));
pty.on('destroyed', () => console.log('Terminal destroyed'));

terminal.off(event, handler)

Unregister an event handler.

const handler = (data) => console.log(data);
pty.on('output', handler);
pty.off('output', handler);

Terminal Properties

console.log(pty.id);       // Terminal ID
console.log(pty.status);   // 'running' | 'stopped' | 'active' | 'ready'
console.log(pty.channel);  // WebSocket channel (PTY only)
console.log(pty.pty);      // true for PTY mode

Exec Mode (Command Tracking)

Exec mode executes commands with structured result tracking, suitable for automation.

terminal.command.run(command, options?)

Execute a command in the terminal.

const exec = await sandbox.terminal.create({ pty: false });

// Foreground execution (waits for completion)
const cmd = await exec.command.run('npm test');
console.log(cmd.stdout);
console.log(cmd.stderr);
console.log(cmd.exitCode);

// Background execution (returns immediately)
const bgCmd = await exec.command.run('npm install', { background: true });
console.log(bgCmd.status); // 'running'
await bgCmd.wait(); // Wait for completion
console.log(bgCmd.exitCode);

Parameters:

  • command: string - The command to execute
  • options?: { background?: boolean } - Execution options

Returns: Command object

terminal.command.list()

List all commands executed in this terminal.

const commands = await exec.command.list();
commands.forEach(cmd => {
  console.log(cmd.id, cmd.command, cmd.status, cmd.exitCode);
});

terminal.command.retrieve(cmdId)

Retrieve a specific command by ID.

const cmd = await exec.command.retrieve('cmd-123');
console.log(cmd.stdout);

Command Object

The Command object represents a command execution result.

Command Properties

console.log(cmd.id);          // Command ID
console.log(cmd.terminalId);  // Parent terminal ID
console.log(cmd.command);     // Executed command
console.log(cmd.status);      // 'running' | 'completed' | 'failed'
console.log(cmd.stdout);      // Standard output
console.log(cmd.stderr);      // Standard error
console.log(cmd.exitCode);    // Exit code (undefined if running)
console.log(cmd.durationMs);  // Execution time in milliseconds
console.log(cmd.startedAt);   // Start timestamp
console.log(cmd.finishedAt);  // Finish timestamp (undefined if running)

command.wait(timeout?)

Wait for a background command to complete.

const cmd = await exec.command.run('sleep 5', { background: true });
await cmd.wait(); // Waits up to default timeout
console.log(cmd.exitCode);

// With custom timeout (in seconds, 0 = no timeout)
await cmd.wait(10);

command.refresh()

Refresh the command status from the server.

const cmd = await exec.command.run('npm build', { background: true });
// ... later ...
await cmd.refresh();
console.log(cmd.status, cmd.exitCode);

terminal.destroy()

Destroy the terminal and clean up resources.

await exec.destroy();

Examples

Multi-Step Build Process

import { compute } from 'computesdk';

const sandbox = await compute.sandbox.create();

// Create project structure
await sandbox.filesystem.mkdir('/app');
await sandbox.filesystem.mkdir('/app/src');

// Write package.json
await sandbox.filesystem.writeFile('/app/package.json', JSON.stringify({
  name: 'my-app',
  version: '1.0.0',
  dependencies: {
    'express': '^4.18.0'
  }
}, null, 2));

// Write source code
await sandbox.filesystem.writeFile('/app/src/index.js', `
const express = require('express');
const app = express();

app.get('/', (req, res) => {
  res.json({ message: 'Hello World!' });
});

console.log('Server ready!');
`);

// Install dependencies
const installResult = await sandbox.runCommand('npm install', { cwd: '/app' });
console.log('Install:', installResult.stdout);

// Run the app
const runResult = await sandbox.runCode(`
const { spawn } = require('child_process');
const proc = spawn('node', ['src/index.js'], { cwd: '/app' });
proc.stdout.on('data', (data) => console.log(data.toString()));
`);

console.log(runResult.output);

await sandbox.destroy();

Terminal Command Execution

import { compute } from 'computesdk';

const sandbox = await compute.sandbox.create();

// Create exec mode terminal for command tracking
const terminal = await sandbox.terminal.create({ pty: false });

// Run build commands with tracking
const install = await terminal.command.run('npm install');
console.log('Install exit code:', install.exitCode);

const build = await terminal.command.run('npm run build');
console.log('Build output:', build.stdout);

// Run tests in background
const tests = await terminal.command.run('npm test', { background: true });
console.log('Tests started:', tests.status);

// Wait for tests to complete
await tests.wait(60); // 60 second timeout
console.log('Tests completed:', tests.exitCode === 0 ? 'PASSED' : 'FAILED');
console.log('Test output:', tests.stdout);

// List all commands
const commands = await terminal.command.list();
console.log(`Executed ${commands.length} commands`);

await terminal.destroy();
await sandbox.destroy();

Interactive Terminal Session

import { compute } from 'computesdk';

const sandbox = await compute.sandbox.create();

// Create PTY terminal for interactive shell
const pty = await sandbox.terminal.create({ 
  pty: true, 
  shell: '/bin/bash' 
});

// Collect all output
let output = '';
pty.on('output', (data) => {
  output += data;
  console.log(data);
});

pty.on('error', (error) => {
  console.error('Terminal error:', error);
});

// Execute interactive commands
pty.write('echo "Starting project setup"\n');
pty.write('mkdir -p /workspace/myproject\n');
pty.write('cd /workspace/myproject\n');
pty.write('npm init -y\n');
pty.write('npm install express\n');
pty.write('echo "Setup complete"\n');

// Wait for operations to complete
await new Promise(resolve => setTimeout(resolve, 5000));

// Clean up
await pty.destroy();
await sandbox.destroy();

console.log('Complete output:', output);

Using Different Providers

import { compute } from 'computesdk';

// Use E2B for data science
compute.setConfig({
  provider: 'e2b',
  e2b: { apiKey: process.env.E2B_API_KEY }
});

const e2bSandbox = await compute.sandbox.create();
await e2bSandbox.runCode('import pandas as pd; print(pd.__version__)');
await e2bSandbox.destroy();

// Switch to Modal for GPU workloads
compute.setConfig({
  provider: 'modal',
  modal: { 
    tokenId: process.env.MODAL_TOKEN_ID,
    tokenSecret: process.env.MODAL_TOKEN_SECRET
  }
});

const modalSandbox = await compute.sandbox.create();
await modalSandbox.runCode('import torch; print(torch.cuda.is_available())');
await modalSandbox.destroy();

Error Handling

try {
  const sandbox = await compute.sandbox.create();
  const result = await sandbox.runCode('invalid python code');
} catch (error) {
  console.error('Execution failed:', error.message);
  
  // Check for specific error types
  if (error.message.includes('No provider detected')) {
    console.error('Set provider credentials in environment variables');
  }
}

Direct Mode (Advanced)

For advanced use cases where you want to bypass the gateway and use provider SDKs directly, see individual provider packages:

Example direct mode usage:

import { e2b } from '@computesdk/e2b';

const compute = e2b({ apiKey: 'your_api_key' });
const sandbox = await compute.sandbox.create();

Building Custom Providers

Want to add support for a new compute provider? See @computesdk/provider for the provider framework and documentation on building custom providers.

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import type { 
  Sandbox,
  SandboxInfo,
  CodeResult,
  CommandResult,
  CreateSandboxOptions
} from 'computesdk';

License

MIT