@scalebox/sdk
v3.8.0
Published
A JavaScript SDK for executing multi-language code in controlled sandboxes, supporting both synchronous and asynchronous modes, as well as multi-language kernels (Python, R, Node.js, Deno/TypeScript, Java/IJAVA, Bash)
Maintainers
Readme
Scalebox JavaScript SDK
A JavaScript SDK for executing multi-language code in controlled sandboxes, supporting both synchronous and asynchronous modes, as well as multi-language kernels (Python, R, Node.js, Deno/TypeScript, Java/IJAVA, Bash). Comprehensive real-world test cases and scripts are provided.
Features
🚀 High-Level API (New!)
- Session API: One-line code execution with automatic lifecycle management
- Smart Caching: 10-100x faster with session reuse and dependency caching
- Auto Renewal: Automatic session timeout management
- Progress Tracking: Real-time execution progress and performance insights
- Type Safe: Full TypeScript support with zero
any
📖 Session API Documentation | 📖 中文文档
💪 Core Features
- Multi-language kernels: Python, R, Node.js, Deno/TypeScript, Java/IJAVA, Bash
- Synchronous
Sandboxand asynchronousAsyncSandboxexecution - Persistent context: Retain variables/state across multiple executions
- Callback subscriptions: stdout, stderr, results, and errors
- Rich result formats: text, html, markdown, svg, png, jpeg, pdf, latex, json, javascript, chart, data, and more
- Real-world testing: Comprehensive coverage with synchronous/asynchronous and multi-language examples
Requirements
- Node.js 18+
- Access to Scalebox environment or local service
Installation
# Using npm
npm install @scalebox/sdk
# Using yarn
yarn add @scalebox/sdk
# Using pnpm
pnpm add @scalebox/sdkConfiguration
Environment Variables
The SDK supports reading configuration from environment variables or .env file:
| Variable | Required | Description | Default |
|----------|----------|-------------|---------|
| SCALEBOX_API_KEY | Yes* | API key for authentication | - |
| SCALEBOX_ACCESS_TOKEN | Yes* | Access token (alternative to API key) | - |
| SCALEBOX_API_URL | No | API endpoint URL | https://api.scalebox.dev |
| SCALEBOX_DOMAIN | No | Custom domain for sandboxes | - |
*Either SCALEBOX_API_KEY or SCALEBOX_ACCESS_TOKEN must be provided.
Example Configuration
Using environment variables:
export SCALEBOX_API_KEY=your_api_key_here
export SCALEBOX_API_URL=https://api.scalebox.dev # optionalUsing .env file:
# .env
SCALEBOX_API_KEY=your_api_key_here
SCALEBOX_API_URL=https://api.scalebox.dev # optionalUsing code configuration:
import { Sandbox } from '@scalebox/sdk'
const sandbox = await Sandbox.create('code-interpreter', {
apiKey: 'your_api_key_here',
apiUrl: 'https://api.scalebox.dev' // optional
})Quick Start
🚀 Session API (Recommended)
The simplest way to execute code - everything is handled automatically!
import { Session } from '@scalebox/sdk'
// Simple execution
const result = await Session.run({
code: 'print("Hello, Scalebox!")',
language: 'python'
})
console.log(result.text) // Hello, Scalebox!Multi-step workflow with session reuse (10-100x faster):
// Step 1: Initialize with packages
const step1 = await Session.run({
code: 'import pandas as pd; import numpy as np',
packages: ['pandas', 'numpy'],
keepAlive: true // Keep session for reuse
})
// Step 2: Upload and process data (reuses session, packages already installed!)
const step2 = await Session.run({
code: 'df = pd.read_csv("data.csv"); print(df.head())',
sessionId: step1.sessionId,
files: { 'data.csv': csvData }
})
// Step 3: Continue analysis
const step3 = await Session.run({
code: 'print(df.describe())',
sessionId: step1.sessionId
})
// Close when done
await Session.close(step1.sessionId!)Pause/Resume for cost optimization:
// Create session and process data
const result = await Session.run({
code: 'import pandas as pd; df = pd.read_csv("data.csv")',
files: { 'data.csv': csvData },
packages: ['pandas'],
keepAlive: true
})
// Pause to save resources during long wait for external data
await Session.pause(result.sessionId!)
// Later: automatically resumed when reusing
const result2 = await Session.run({
code: 'print(df.describe())',
sessionId: result.sessionId // ✅ Automatically resumes
})
// Close when done
await Session.close(result.sessionId!)Real-time progress tracking:
const result = await Session.run({
code: pythonCode,
packages: ['pandas', 'matplotlib'],
onProgress: (progress) => {
console.log(`[${progress.stage}] ${progress.percent}% - ${progress.message}`)
}
})
// Check performance insights
console.log('Timing:', result.timing)
console.log('Bottleneck:', result.insights.bottleneck)
console.log('Suggestions:', result.insights.suggestions)Object storage mount (S3-compatible):
// Create session with object storage mounted
const result = await Session.run({
code: `
import os
# Object storage is mounted at the specified mount point
files = os.listdir('/mnt/oss')
print(f'Files in OSS: {files}')
`,
objectStorage: {
uri: 's3://my-bucket/data/',
mountPoint: '/mnt/oss',
accessKey: 'YOUR_ACCESS_KEY',
secretKey: 'YOUR_SECRET_KEY',
region: 'ap-east-1',
endpoint: 'https://s3.ap-east-1.amazonaws.com'
}
})📖 Complete Session API Guide | 📖 完整中文指南 | 📁 More Examples
💪 Low-Level API (Advanced)
For fine-grained control over sandbox lifecycle:
import { Sandbox } from '@scalebox/sdk'
const sandbox = await Sandbox.create('code-interpreter', {
timeoutMs: 300000, // 5 minutes
metadata: { test: 'example' }
})
// Check sandbox status
const isRunning = await sandbox.isRunning()
console.log('Sandbox is running:', isRunning)
// Get sandbox information
// ⚠️ Note: getInfo() returns public sandbox metadata
// Internal properties like envdAccessToken and sandboxDomain are excluded for security
// Use sandbox.sandboxId, sandbox.sandboxDomain directly if needed
const info = await sandbox.getInfo()
console.log('Sandbox info:', info)
// Filesystem operations
const files = await sandbox.files.list("/")
console.log('Files:', files)
// Command execution
const result = await sandbox.commands.run('echo "Hello World"')
console.log('Command output:', result.stdout)
// Cleanup
await sandbox.kill()Quick Start (Code Interpreter)
import { CodeInterpreter } from '@scalebox/sdk'
async function main() {
// ✅ Recommended: Use CodeInterpreter.create() static method
const interpreter = await CodeInterpreter.create({
templateId: 'code-interpreter'
})
const exec = await interpreter.runCode("print('hello from interpreter')", { language: "python" })
console.log(exec.logs.stdout)
await interpreter.close()
}
main()API Examples
Sandbox Management
import { Sandbox } from '@scalebox/sdk'
// Create sandbox
const sandbox = await Sandbox.create('code-interpreter', {
timeoutMs: 300000,
metadata: { project: 'my-app' },
envs: { NODE_ENV: 'production' }
})
// Create sandbox with object storage mount
const sandboxWithOSS = await Sandbox.create('code-interpreter', {
timeoutMs: 300000,
objectStorage: {
uri: 's3://my-bucket/data/',
mountPoint: '/mnt/oss',
accessKey: 'YOUR_ACCESS_KEY',
secretKey: 'YOUR_SECRET_KEY',
region: 'ap-east-1',
endpoint: 'https://s3.ap-east-1.amazonaws.com'
}
})
// Object storage is now mounted at /mnt/oss
// Connect to existing sandbox
const connectedSandbox = await Sandbox.connect('sandbox-id')
// List all sandboxes
const paginator = Sandbox.list()
while (paginator.hasNext) {
const sandboxes = await paginator.nextItems()
console.log(sandboxes)
}
// Sandbox operations
await sandbox.setTimeout(600000) // 10 minutes
await sandbox.betaPause() // Pause sandbox
await sandbox.kill() // Close sandboxPause and Resume Operations
Pause sandboxes to save compute resources while preserving filesystem state. Paused sandboxes don't consume CPU or memory, only storage.
// Pause a running sandbox
await sandbox.betaPause()
console.log('Sandbox paused - no compute costs')
// Resume paused sandbox using connect (unified endpoint)
// connect() automatically resumes if paused, or connects if running
await sandbox.connect()
console.log('Sandbox resumed and ready')
// Resume with new timeout
await sandbox.connect({ timeoutMs: 900000 }) // 15 minutes
// Check sandbox status
const info = await sandbox.getInfo()
console.log('Status:', info.status) // 'running' | 'paused' | 'stopped'
// Static connect method (auto-resumes if paused)
const connectedSandbox = await Sandbox.connect(sandboxId)Benefits:
- Cost optimization: Paused sandboxes only charge for storage, not CPU/RAM
- State preservation: Files, installed packages, and filesystem state are preserved
- Automatic resume: Use
connect()to automatically resume paused sandboxes - Timeout management: Update timeout when resuming
Use cases:
- Long idle periods between executions
- Batch processing with gaps
- Cost optimization for infrequently used sandboxes
Filesystem Operations
// Read file
const content = await sandbox.files.read('/path/to/file.txt')
// Write file
await sandbox.files.write('/path/to/file.txt', 'Hello World')
// List directory
const files = await sandbox.files.list('/home/user')
// Create directory
await sandbox.files.makeDir('/home/user/newdir')
// Move file
await sandbox.files.move('/old/path', '/new/path')
// Remove file
await sandbox.files.remove('/path/to/file.txt')Command Execution
// Execute command synchronously
const result = await sandbox.commands.run('ls -la')
console.log(result.stdout)
console.log(result.stderr)
console.log(result.exitCode)
// Execute command in background
const handle = await sandbox.commands.run('long-running-command', {
background: true
})
// Wait for command to complete
const finalResult = await handle.wait()
// Kill command
await handle.kill()Pseudo-Terminal Operations
// Start pseudo-terminal
const pty = await sandbox.pty.start({
cwd: '/home/user',
envs: { PATH: '/usr/bin:/bin' }
})
// Send data
await pty.send('echo "Hello from PTY"')
// Wait for output
await pty.wait()Multi-Language Examples
- Python:
language: "python" - R:
language: "r" - Node.js:
language: "nodejs" - Deno/TypeScript:
language: "typescript" - Java (IJAVA/pure Java):
language: "ijava"orlanguage: "java" - Bash:
language: "bash"
Example (Node.js):
import { Sandbox } from '@scalebox/sdk'
const sbx = await Sandbox.create()
const code = `
console.log("Hello from Node.js!");
const x = 1 + 2; console.log(\`x=\${x}\`);
`
const result = await sbx.runCode(code, { language: "nodejs" })
console.log(result.logs.stdout)Example (R):
import { Sandbox } from '@scalebox/sdk'
const sbx = await Sandbox.create()
const code = `
print("Hello from R!")
x <- mean(c(1,2,3,4,5))
print(paste("mean:", x))
`
const res = await sbx.runCode(code, { language: "r" })
console.log(res.logs.stdout)Example (Deno/TypeScript):
import { Sandbox } from '@scalebox/sdk'
const sbx = await Sandbox.create()
const ts = `
console.log("Hello from Deno/TypeScript!")
const nums: number[] = [1,2,3]
console.log(nums.reduce((a,b)=>a+b, 0))
`
const res = await sbx.runCode(ts, { language: "typescript" })
console.log(res.logs.stdout)Example (Java/IJAVA):
import { Sandbox } from '@scalebox/sdk'
const sbx = await Sandbox.create()
const code = `
System.out.println("Hello from IJAVA!");
int a = 10, b = 20; System.out.println(a + b);
`
const res = await sbx.runCode(code, { language: "java" })
console.log(res.logs.stdout)Example (Bash):
import { Sandbox } from '@scalebox/sdk'
const sbx = await Sandbox.create()
const res = await sbx.runCode("echo 'Hello from Bash'", { language: "bash" })
console.log(res.logs.stdout)Context Management
Context allows reusing variables/state across multiple executions using real gRPC service:
import { CodeInterpreter } from '@scalebox/sdk'
// ✅ Recommended: Use static create method
const interpreter = await CodeInterpreter.create()
// Create context (using gRPC)
const ctx = await interpreter.createCodeContext({ language: "python", cwd: "/tmp" })
await interpreter.runCode("counter = 0", { language: "python", context: ctx })
await interpreter.runCode("counter += 1; print(counter)", { language: "python", context: ctx })
// Destroy context (using gRPC)
await interpreter.destroyContext(ctx)
// Manage multiple contexts
const pythonCtx = await interpreter.createCodeContext({ language: "python" })
const jsCtx = await interpreter.createCodeContext({ language: "nodejs" })
console.log('Active contexts:', interpreter.getContexts().length)Callbacks (Optional)
import { Sandbox } from '@scalebox/sdk'
const sbx = await Sandbox.create()
function onStdout(msg) {
console.log("STDOUT:", msg.content)
}
function onStderr(msg) {
console.log("STDERR:", msg.content)
}
function onResult(res) {
console.log("RESULT formats:", Object.keys(res.formats))
}
function onError(err) {
console.log("ERROR:", err.name, err.value)
}
await sbx.runCode(
"print('with callbacks')",
{
language: "python",
onStdout,
onStderr,
onResult,
onError
}
)Result Formats
Result may contain the following data fields:
text,html,markdown,svg,png,jpeg,pdf,latexjsonData,javascript,data,chartexecutionCount,isMainResult,extra
You can view available formats via Object.keys(result.formats).
Running Tests
The test/ directory contains comprehensive real-world use cases covering:
- Synchronous and asynchronous comprehensive use cases
- Multi-language kernels (Python, R, Node.js, Deno/TypeScript, Java/IJAVA, Bash)
- Context management, callbacks, and result formats
# Run all tests
npm test
# Run specific tests
npm run test:integrationTroubleshooting
- Import/dependency errors: Ensure dependencies are properly installed
- External kernels unavailable: Ensure environment has corresponding language runtime (R/Node/Deno/JDK) installed and backend has enabled the kernel
- Timeout/network: Check network and backend service reachability, increase
timeout/requestTimeoutif necessary
Tech Stack
Platform Support
Automated Release Process
This project uses semantic-release for fully automated version management and releases.
📝 Commit Conventions
Use Conventional Commits specification:
# New feature (automatically publish minor version)
git commit -m "feat: add new authentication method"
# Bug fix (automatically publish patch version)
git commit -m "fix: resolve timeout issue in sandbox"
# Breaking change (automatically publish major version)
git commit -m "feat!: breaking change in API"
# Documentation update (does not trigger release)
git commit -m "docs: update installation guide"
# Performance optimization (automatically publish patch version)
git commit -m "perf: optimize memory usage"🚀 Release Process
- Commit code using standardized commit message
- Push to main branch
- CI automatically handles:
- ✅ Analyze commit messages to determine version type
- ✅ Automatically update version number
- ✅ Generate CHANGELOG.md
- ✅ Create Git tag
- ✅ Publish to npm
- ✅ Create GitHub Release
📋 Version Rules
| Commit Type | Version Increment | Example |
|------------|---------|------|
| feat: | minor (0.1.0) | New feature |
| fix: | patch (0.0.1) | Bug fix |
| perf: | patch (0.0.1) | Performance optimization |
| feat!: | major (1.0.0) | Breaking change |
| docs: | - | Documentation update |
| chore: | - | Build/tools |
| test: | - | Testing related |
License
This project is licensed under the MIT License.
