English | 中文
A TypeScript/JavaScript SDK for low-level interaction with OpenSandbox. It provides the ability to create, manage, and interact with secure sandbox environments, including executing shell commands, managing files, and reading resource metrics.
npm install @alibaba-group/opensandboxpnpm add @alibaba-group/opensandboxyarn add @alibaba-group/opensandboxThe following example shows how to create a sandbox and execute a shell command.
Note: Before running this example, ensure the OpenSandbox service is running. See the root README.md for startup instructions.
import { ConnectionConfig, Sandbox, SandboxException } from "@alibaba-group/opensandbox";
const config = new ConnectionConfig({
domain: "api.opensandbox.io",
apiKey: "your-api-key",
// protocol: "https",
// requestTimeoutSeconds: 60,
});
try {
const sandbox = await Sandbox.create({
connectionConfig: config,
image: "ubuntu",
timeoutSeconds: 10 * 60,
});
const execution = await sandbox.commands.run("echo 'Hello Sandbox!'");
console.log(execution.logs.stdout[0]?.text);
// Optional but recommended: terminate the remote instance when you are done.
await sandbox.kill();
await sandbox.close();
} catch (err) {
if (err instanceof SandboxException) {
console.error(
`Sandbox Error: [${err.error.code}] ${err.error.message ?? ""}`,
);
} else {
console.error(err);
}
}Manage the sandbox lifecycle, including renewal, pausing, and resuming.
const info = await sandbox.getInfo();
console.log("State:", info.status.state);
console.log("Created:", info.createdAt);
console.log("Expires:", info.expiresAt);
await sandbox.pause();
// Resume returns a fresh, connected Sandbox instance.
const resumed = await sandbox.resume();
// Renew: expiresAt = now + timeoutSeconds
await resumed.renew(30 * 60);Define custom logic to determine whether the sandbox is ready/healthy. This overrides the default ping check used during readiness checks.
const sandbox = await Sandbox.create({
connectionConfig: config,
image: "nginx:latest",
healthCheck: async (sbx) => {
// Example: consider the sandbox healthy when port 80 endpoint becomes available
const ep = await sbx.getEndpoint(80);
return !!ep.endpoint;
},
});Execute commands and handle output streams in real-time.
import type { ExecutionHandlers } from "@alibaba-group/opensandbox";
const handlers: ExecutionHandlers = {
onStdout: (m) => console.log("STDOUT:", m.text),
onStderr: (m) => console.error("STDERR:", m.text),
onExecutionComplete: (c) =>
console.log("Finished in", c.executionTimeMs, "ms"),
};
await sandbox.commands.run(
'for i in 1 2 3; do echo "Count $i"; sleep 0.2; done',
undefined,
handlers,
);Manage files and directories, including read, write, list/search, and delete.
await sandbox.files.createDirectories([{ path: "/tmp/demo", mode: 755 }]);
await sandbox.files.writeFiles([
{ path: "/tmp/demo/hello.txt", data: "Hello World", mode: 644 },
]);
const content = await sandbox.files.readFile("/tmp/demo/hello.txt");
console.log("Content:", content);
const files = await sandbox.files.search({
path: "/tmp/demo",
pattern: "*.txt",
});
console.log(files.map((f) => f.path));
await sandbox.files.deleteDirectories(["/tmp/demo"]);getEndpoint() returns an endpoint without a scheme (for example "localhost:44772"). Use getEndpointUrl() if you want a ready-to-use absolute URL (for example "http://localhost:44772").
const { endpoint } = await sandbox.getEndpoint(44772);
const url = await sandbox.getEndpointUrl(44772);Use SandboxManager for administrative tasks and finding existing sandboxes.
import { SandboxManager } from "@alibaba-group/opensandbox";
const manager = SandboxManager.create({ connectionConfig: config });
const list = await manager.listSandboxInfos({
states: ["Running"],
pageSize: 10,
});
console.log(list.items.map((s) => s.id));
await manager.close();The ConnectionConfig class manages API server connection settings.
Runtime notes:
- In browsers, the SDK uses the global
fetchimplementation. - In Node.js, every
SandboxandSandboxManagerclones the baseConnectionConfigviawithTransportIfMissing(), so each instance gets an isolatedundicikeep-alive pool. Callsandbox.close()ormanager.close()when you are done so the SDK can release the associated agent.
| Parameter | Description | Default | Environment Variable |
|---|---|---|---|
apiKey |
API key for authentication | Optional | OPEN_SANDBOX_API_KEY |
domain |
Sandbox service domain (host[:port]) |
localhost:8080 |
OPEN_SANDBOX_DOMAIN |
protocol |
HTTP protocol (http/https) |
http |
- |
requestTimeoutSeconds |
Request timeout applied to SDK HTTP calls | 30 |
- |
debug |
Enable basic HTTP debug logging | false |
- |
headers |
Extra headers applied to every request | {} |
- |
useServerProxy |
Use sandbox server as proxy for execd/endpoint requests (e.g. when client cannot reach the sandbox directly) | false |
- |
import { ConnectionConfig } from "@alibaba-group/opensandbox";
// 1. Basic configuration
const config = new ConnectionConfig({
domain: "api.opensandbox.io",
apiKey: "your-key",
requestTimeoutSeconds: 60,
});
// 2. Advanced: custom headers
const config2 = new ConnectionConfig({
domain: "api.opensandbox.io",
apiKey: "your-key",
headers: { "X-Custom-Header": "value" },
});Sandbox.create() allows configuring the sandbox environment.
| Parameter | Description | Default |
|---|---|---|
image |
Docker image to use | Required |
timeoutSeconds |
Automatic termination timeout (server-side TTL) | 10 minutes |
entrypoint |
Container entrypoint command | ["tail","-f","/dev/null"] |
resource |
CPU and memory limits (string map) | {"cpu":"1","memory":"2Gi"} |
env |
Environment variables | {} |
metadata |
Custom metadata tags | {} |
networkPolicy |
Optional outbound network policy (egress) | - |
extensions |
Extra server-defined fields | {} |
skipHealthCheck |
Skip readiness checks (Running + health check) |
false |
healthCheck |
Custom readiness check | - |
readyTimeoutSeconds |
Max time to wait for readiness | 30 seconds |
healthCheckPollingInterval |
Poll interval while waiting (milliseconds) | 200 ms |
const sandbox = await Sandbox.create({
connectionConfig: config,
image: "python:3.11",
networkPolicy: {
defaultAction: "deny",
egress: [{ action: "allow", target: "pypi.org" }],
},
});Both Sandbox and SandboxManager own a scoped HTTP agent when running on Node.js
so you can safely reuse the same ConnectionConfig. Once you are finished interacting
with the sandbox or administration APIs, call sandbox.close() / manager.close() to
release the underlying agent.
- The SDK can run in browsers, but streaming file uploads are Node-only.
- If you pass
ReadableStreamorAsyncIterableforwriteFiles, the browser will fall back to buffering in memory before upload. - Reason: browsers do not support streaming
multipart/form-databodies with custom boundaries (required by the execd upload API).