Skip to content
LogoLogo

CreateOS Sandbox SDKs

Create, control, and clean up isolated Linux sandboxes from your application. Choose TypeScript, Go, or Python in any example, the selection stays in sync across the page.

LanguagePackageRequirements
TypeScript@nodeops-createos/sandboxNode.js 20+, Bun, Deno, edge runtimes, or a browser
Gogithub.com/NodeOps-app/createos-go-sdkGo 1.25+
Pythoncreateos-sandboxPython 3.10+

Every SDK reads CREATEOS_SANDBOX_API_KEY and CREATEOS_SANDBOX_BASE_URL from the environment.

Install the SDK

npm install @nodeops-createos/sandbox

Create a sandbox and run a command

The create call returns a connected sandbox that is ready to accept commands. Always destroy it when the work is complete.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-1vcpu-1gb",
  rootfs: "devbox:1",
});
 
try {
  const response = await sandbox.runCommand("echo", ["Hello from CreateOS"]);
  console.log(response.result.stdout);
} finally {
  await sandbox.destroy();
}

Stream command output

Receive output as it is produced instead of waiting for the command to finish. These snippets use the running sandbox created above.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-1vcpu-1gb",
  rootfs: "devbox:1",
});
 
try {
  const command = "for n in 1 2 3; do echo result-$n; sleep 1; done";
  for await (const event of sandbox.streamCommand("sh", ["-c", command])) {
    if (event.type === "stdout") process.stdout.write(event.data);
  }
} finally {
  await sandbox.destroy();
}

Upload files

Upload a file without shell escaping. These snippets assume the sandbox or instance from the previous example is still running.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-1vcpu-1gb",
  rootfs: "devbox:1",
});
 
try {
  await sandbox.files.upload("/workspace/hello.txt", "Hello from TypeScript");
  const file = await sandbox.files.download("/workspace/hello.txt");
  console.log(new TextDecoder().decode(file));
} finally {
  await sandbox.destroy();
}

Publish a live preview

Start a service and generate its public URL. Create the sandbox with ingress enabled before running this example.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-1vcpu-1gb",
  rootfs: "devbox:1",
  ingress_enabled: true,
});
 
try {
  await sandbox.processes.create({
    cmd: "python3",
    args: ["-m", "http.server", "8080", "--bind", "0.0.0.0"],
  });
  await sandbox.waitForPortReady(8080);
  console.log(sandbox.previewUrl(8080));
} finally {
  await sandbox.destroy();
}

Run managed processes

Keep a stable process ID, reconnect to output, send input, and wait for the entire process tree.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-1vcpu-1gb",
  rootfs: "devbox:1",
});
 
try {
  const process = await sandbox.processes.create({
    cmd: "sh",
    args: ["-c", "echo finished"],
  });
  const result = await sandbox.processes.wait(process.process_id, {
    scope: "tree",
  });
  console.log(result.exit_code);
} finally {
  await sandbox.destroy();
}

Spawn an interactive terminal

Create a PTY-backed shell, resize its terminal, send commands, and reconnect to its retained output after it exits.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-1vcpu-1gb",
  rootfs: "devbox:1",
});
 
try {
  const terminal = await sandbox.processes.create({
    cwd: "/workspace",
    pty: { rows: 24, cols: 80 },
  });
 
  await sandbox.processes.resize(terminal.process_id, {
    rows: 32,
    cols: 100,
  });
  await sandbox.processes.input(
    terminal.process_id,
    "echo 'CreateOS terminal ready'; uname -s; pwd; exit\n",
  );
 
  const result = await sandbox.processes.wait(terminal.process_id, {
    scope: "tree",
  });
  if (result.exit_code !== 0) {
    throw new Error(`Terminal exited with code ${result.exit_code}`);
  }
 
  for await (const event of sandbox.processes.connect(terminal.process_id)) {
    if (event.type === "data" && event.stream === "pty") {
      process.stdout.write(event.data);
    }
  }
} finally {
  await sandbox.destroy();
}

Automate a cloud desktop

Open the NodeOps website in a graphical cloud browser and capture a validated PNG screenshot. This example requires the desktop:1 image.

import { createClient } from "@nodeops-createos/sandbox";
 
const client = createClient();
const sandbox = await client.createSandbox({
  shape: "s-2vcpu-4gb",
  rootfs: "desktop:1",
});
 
try {
  let screen;
  for (let attempt = 0; attempt < 60; attempt++) {
    screen = await sandbox.computer.screen({ screenId: "screen-0" })
      .catch(() => undefined);
    if (screen) break;
    await new Promise((resolve) => setTimeout(resolve, 2_000));
  }
  if (!screen) throw new Error("Desktop did not become ready");
 
  const target = "https://createos.sh";
  await sandbox.computer.open(target, { screenId: "screen-0" });
  await new Promise((resolve) => setTimeout(resolve, 3_000));
 
  const screenshot = await sandbox.computer.screenshot({
    screenId: "screen-0",
    timeoutMs: 45_000,
  });
  const view = new DataView(screenshot);
  const width = view.getUint32(16, false);
  const height = view.getUint32(20, false);
  console.log(`Opened ${target} and captured a ${width}x${height} screenshot`);
} finally {
  await sandbox.destroy();
}

Source and API reference