# Migrate from the CodeSandbox SDK to Sandboxer

> Swap @codesandbox/sdk for sandboxer-sdk. sdk.sandboxes.create() becomes sandboxer.create(), commands.run() becomes exec(), fs.writeTextFile() becomes files.write(), and hibernate and resume become stop and resume, which keep memory on a matching CPU type. Forks copy the disk only, and templates become a setup script plus a named snapshot.

Source: https://sandboxer.com/migrate/codesandbox-sdk. Updated 2026-10-27.

**Short answer:** Swap @codesandbox/sdk for sandboxer-sdk. sdk.sandboxes.create() becomes sandboxer.create(), commands.run() becomes exec(), fs.writeTextFile() becomes files.write(), and hibernate and resume become stop and resume, which keep memory on a matching CPU type. Forks copy the disk only, and templates become a setup script plus a named snapshot.

CodeSandbox is a Together AI company, and Together now lists this SDK as its legacy code sandbox offering ([Together docs](https://docs.together.ai/docs/together-code-sandbox-legacy)). The npm package is still `@codesandbox/sdk`. This page covers that SDK. For Together's newer `together-sandbox` SDK, see [Sandboxer vs Together Code Sandbox](/compare/together-code-sandbox).

## Concept map

| CodeSandbox SDK | Sandboxer |
| - | - |
| Sandbox, backed by a Firecracker VM ([CodeSandbox docs](https://codesandbox.io/docs/sdk/create)) | Sandbox, a microVM with its own kernel, root, systemd and Docker ([Machines](/docs/machines)) |
| Template built with `npx @codesandbox/sdk build`, a memory and disk snapshot ([Templates](https://codesandbox.io/docs/sdk/templates)) | Setup script (`--setup-file`) saved as a named snapshot, started with `--from` ([Snapshots](/docs/snapshots#named-snapshots-templates)) |
| `.codesandbox/tasks.json`: `setupTasks` and `runAtStart` tasks | Setup script for installs; enabled systemd services for long-running processes |
| Hibernate, a memory and disk snapshot ([Hibernate](https://codesandbox.io/docs/sdk/hibernate)) | Stop, which saves memory and disk ([Snapshots](/docs/snapshots#stop)) |
| Resume, with `bootupType` `RESUME` or `CLEAN` | Resume, with `memoryRestored` `true`, or `false` plus `resumeReason` |
| Shutdown (no snapshot, files in `/project/workspace` kept) | Stop with memory, or `delete` |
| Fork: `create({ id: 'some-sandbox-id' })`; a live fork shares memory with its parent | Fork: a copy of the live disk that boots fresh ([Snapshots](/docs/snapshots#fork)) |
| `hibernationTimeoutSeconds`, `automaticWakeupConfig` | Idle auto-pause (`idleStopMinutes`) and wake on use ([Long-running tasks](/docs/long-running#idle-auto-pause-and-wake-on-use)) |
| VM tiers, Pico to XLarge, `updateTier` on a running sandbox ([VM Specs](https://codesandbox.io/docs/sdk/specs)) | Four sizes, `small` to `xlarge`; grow on resume or fork into a bigger copy; moving to a smaller size isn't supported yet ([Machines](/docs/machines#sizes)) |
| Workspace in `/project/workspace`, persisted with git | Home directory `/home/user`; the whole disk persists |
| Ports at `https://<sandbox-id>-<port>.csb.app` ([Ports](https://codesandbox.io/docs/sdk/ports)) | Hosted ports at `https://<subdomain>-<port>.box.sandboxer.com` ([Hosting](/docs/hosting)) |
| Privacy `public`, `private`, `public-hosts`, and host tokens ([Hosts](https://codesandbox.io/docs/sdk/hosts)) | Each hosted port is private with a `_token` link, or `--public` |
| `CSB_API_KEY` | `SANDBOXER_API_KEY` ([API keys](/docs/api-keys)) |

## API and SDK mapping

CodeSandbox calls come from its [SDK docs](https://codesandbox.io/docs/sdk), read on 2026-10-27. Ours come from the [TypeScript SDK](/docs/sdk-typescript) docs. In the CodeSandbox SDK you call `sandbox.connect()` to get a client for commands and files. Sandboxer has no separate client: you call methods on the sandbox.

| CodeSandbox SDK | Sandboxer SDK | `sbx` CLI |
| - | - | - |
| `new CodeSandbox()` (reads `CSB_API_KEY`) | `new Sandboxer()` (reads `SANDBOXER_API_KEY`) | |
| `sdk.sandboxes.create()` then `sandbox.connect()` | `sandboxer.create({ type: "small" })` | `sbx new --type small` |
| `sdk.sandboxes.create({ id: 'template-id' })` | `sandboxer.create({ from: "web-stack" })` | `sbx new --from web-stack` |
| `create({ vmTier: VMTier.Micro })` | `create({ type: "default" })` | `sbx new --type default` |
| `client.commands.run("npm install")` | `sandbox.exec("npm install")` | `sbx exec <id> "npm install"` |
| `client.commands.runBackground(cmd)` | `sandbox.start(cmd)` | `sbx exec <id> --detach "cmd"` |
| `command.kill()` | `sandbox.kill(pid)` | |
| `client.fs.writeTextFile(path, text)` | `sandbox.files.write(path, text)` | `sbx scp ./file <id>:/home/user/` |
| `client.fs.readTextFile(path)` | `sandbox.files.read(path)` | |
| `client.fs.download("./")` (a zip URL) | `sandbox.files.download(path)` (up to 50 MiB) | `sbx scp -r <id>:/home/user/dir .` |
| `sdk.sandboxes.hibernate(id)` | `sandbox.stop()` | `sbx stop <id>` |
| `sdk.sandboxes.resume(id)` | `(await sandboxer.get(id)).resume()` | `sbx resume <id>` |
| `create({ id: 'some-sandbox-id' })` (fork) | `sandbox.fork()` | `sbx fork <id>` |
| `sandbox.updateTier(VMTier.Small)` | `sandbox.resume({ type: "large" })` (cold boot) | `sbx resume <id> --type large` |
| `client.hosts.getUrl(5173)` | `sandbox.host(5173)` | `sbx host <id> 5173` |
| `sdk.sandboxes.delete(id)` | `sandbox.delete()` | `sbx delete <id> --yes` |

## Before and after

From CodeSandbox's docs: [https://codesandbox.io/docs/sdk](https://codesandbox.io/docs/sdk) (quickstart), with the `writeTextFile` line from [File System](https://codesandbox.io/docs/sdk/filesystem) and the last two lines from [Hibernate](https://codesandbox.io/docs/sdk/hibernate) and [Resume](https://codesandbox.io/docs/sdk/resume):

```typescript
import { CodeSandbox } from "@codesandbox/sdk";

const sdk = new CodeSandbox();
const sandbox = await sdk.sandboxes.create();
const client = await sandbox.connect();

const output = await client.commands.run("echo 'Hello World'");
console.log(output) // Hello World

await client.fs.writeTextFile("./hello.txt", "Hello, world!");

await sdk.sandboxes.hibernate('sandbox-id');
const resumed = await sdk.sandboxes.resume('sandbox-id');
```

The same steps with `sandboxer-sdk` 0.1.1. We ran this on prod on 2026-10-27. It also starts a counter whose state lives only in memory, so you can see what survives the stop:

```bash
npm i sandboxer-sdk
export SANDBOXER_API_KEY=sbx_live_…
```

```typescript
import { Sandboxer } from "sandboxer-sdk";

const sandboxer = new Sandboxer(); // reads SANDBOXER_API_KEY
const sandbox = await sandboxer.create({ type: "small", ttlSeconds: 1800, name: "aeo-migrate-csb-1" });

console.log((await sandbox.exec("echo 'Hello World'")).stdout);
await sandbox.files.write("hello.txt", "Hello, world!");
console.log(await sandbox.files.read("hello.txt"));

// A process whose state lives only in memory
await sandbox.files.write("counter.py", "import time\nn = 0\nwhile True:\n    n += 1\n    print(n, flush=True)\n    time.sleep(1)\n");
await sandbox.start("python3 counter.py > /tmp/count.log");
await new Promise((r) => setTimeout(r, 5000));

await sandbox.stop();   // like hibernate: saves memory and disk, stops the meter
await sandbox.resume(); // like resume: same processes, same PIDs
console.log((await sandbox.exec("pgrep -f counter.py; tail -n 1 /tmp/count.log")).stdout);
```

```text
Hello World

Hello, world!
552
554
575
7
```

The whole script took 11.5 seconds, including the create, the stop and the resume. `create` and `resume` wait until the sandbox is ready, and `stop` waits until it is archived. Paths are relative to `/home/user`. The counter reached 7 after the resume. A cold boot would have lost the process. (`pgrep -f` also lists the shell running it, which is the third PID.)

### Stop and resume, with the CLI

The same sandbox, a second cycle with clearer output. `sandbox.stop()` returns when the sandbox is archived. `sbx stop` returns at once, so we polled `sbx info` until the state was `archived`:

```bash
sbx exec sb_v8zia5ilza "ps -o pid,etime,cmd -C python3; tail -n 1 /tmp/count.log"
#     PID     ELAPSED CMD
#     554       00:27 python3 counter.py
# 28
sbx stop sb_v8zia5ilza
# {"ok":true,"type":"sandbox.stopping",…,"status":"archiving",…}
sbx resume sb_v8zia5ilza
# {"event":"ready","id":"sb_v8zia5ilza","state":"ready",…,"memoryRestored":true,…}
sbx exec sb_v8zia5ilza "ps -o pid,etime,cmd -C python3; tail -n 1 /tmp/count.log"
```

```text
    PID     ELAPSED CMD
    554       00:32 python3 counter.py
30
```

`sbx resume` took 1.3 seconds. The process kept PID 554 and its count. This is the CodeSandbox `RESUME` boot. Sandboxer restores memory only on a machine with the same CPU type as the one the sandbox stopped on. If none is free within 2 minutes, the resume boots from disk, the way a CodeSandbox `CLEAN` boot does. Files stay, hand-started processes don't, and the sandbox shows `memoryRestored: false` with `resumeReason: "cpu_mismatch"`. Pass `--require-memory` (`requireMemory: true`) to wait instead.

### Ports, forks and templates

```bash
sbx exec sb_v8zia5ilza --detach "python3 -m http.server 3000"
sbx host sb_v8zia5ilza 3000 --public
# {"ok":true,"type":"port.hosted",…,"url":"https://amber-fern-summit-3000.box.sandboxer.com","access":"public",…}
curl https://amber-fern-summit-3000.box.sandboxer.com/hello.txt    # Hello, world!

sbx fork sb_v8zia5ilza --ttl 900 --wait      # 3.4 s; new id sb_0lprwv18i9
sbx exec sb_0lprwv18i9 "ls; pgrep -f counter.py || echo 'counter.py not running'"
# counter.py
# hello.txt
# 556

sbx snapshot sb_v8zia5ilza aeo-migrate-csb-tpl     # 2.1 s; "status":"ready"
sbx snapshot rm aeo-migrate-csb-tpl
sbx delete sb_0lprwv18i9 --yes
sbx delete sb_v8zia5ilza --yes
```

The fork has the files, but the counter isn't running in it. The one PID is `pgrep`'s own shell. The source kept running throughout. On CodeSandbox, a sandbox created from a template continues the template's memory state, and a live fork shares memory with its parent. A Sandboxer fork is a fresh boot from a copy of the disk.

## Move your data and environment

**Files.** Sandboxes don't move between providers. CodeSandbox's `client.fs.download("./")` gives you a zip URL of the workspace, valid for 5 minutes. Download it, unzip it, and upload the folder with `sbx scp -r ./workspace <id>:/home/user/`. You can also use `files.write` (up to 5 MiB a file through the API). Your git history is in the zip too. If you pushed the workspace to your own remote, `git clone` it in the sandbox instead.

**Templates.** Move `setupTasks` from `.codesandbox/tasks.json` into a setup script, create a sandbox with `sbx new --setup-file ./setup.sh`, and save it with `sbx snapshot <id> <name>`. Start new sandboxes with `sbx new --from <name>`, or `create({ from: "<name>" })` in the SDK. A CodeSandbox template captures memory, so a dev server started by a `runAtStart` task is already running in each new sandbox. A Sandboxer named snapshot holds the disk only. Run each long-lived task as a systemd service and enable it (`systemctl enable`), so it starts on every boot, fork and named-snapshot start.

**Dockerfiles.** A CodeSandbox `.codesandbox/Dockerfile` defines the environment the sandbox runs in. On Sandboxer, the environment is an Ubuntu 24.04 VM with Docker, BuildKit and Compose preinstalled. Either put the Dockerfile's install steps in the setup script, or build the image and run it with `docker` inside the sandbox.

**Env vars and secrets.** Pass per-sandbox variables with `env` on create (`-e KEY=value` on the CLI). For values every sandbox should get, set them once in an environment: `sbx env set-var base KEY=value`, and `sbx env set-file base path --from ./file` for secret files ([Environments](/docs/environments)).

**Ports and preview URLs.** `https://<sandbox-id>-<port>.csb.app` becomes `https://<subdomain>-<port>.box.sandboxer.com`. CodeSandbox opens every port automatically. On Sandboxer you host each port with `sbx host` or `sandbox.host(port)`, and it stays private with a `_token` link unless you pass `--public`. A sandbox that paused itself for being idle wakes on the next request to a hosted port, like CodeSandbox's automatic HTTP wakeup. A sandbox you stopped stays stopped until you resume it.

## What's different

What you gain:

- **A full Linux machine.** Root, systemd, Docker and `/dev/kvm` for nested VMs come preinstalled ([Machines](/docs/machines)). The whole disk persists, not only one workspace folder.
- **Per-second billing.** CodeSandbox bills VM credits by the minute, rounded up ([CodeSandbox pricing docs](https://codesandbox.io/docs/sdk/pricing)). Sandboxer bills per second while a sandbox runs.
- **Coding agents.** Claude Code, Codex and others are installed in every sandbox and driven through `sandbox.prompt()` ([Agents](/docs/agents)).
- **A Python SDK and a CLI.** `pip install sandboxer-sdk` gives the same calls in snake_case, and `sbx` covers the same lifecycle from a shell.

What you lose or must change:

- **Memory in forks and templates.** A CodeSandbox template is a memory and disk snapshot, so sandboxes made from it start with its processes running. On Sandboxer only stop and resume keep memory. Forks and named snapshots copy the disk and boot fresh.
- **Live resizing.** CodeSandbox's `updateTier` resizes a running sandbox without a reboot. Sandboxer grows a sandbox on resume, and a resized resume cold-boots from disk. Moving to a smaller size isn't supported yet: create a new sandbox of that size and copy your files.
- **Larger sizes.** CodeSandbox tiers go up to 64 cores and 128 GB. Sandboxer's largest size, `xlarge`, has 16 vCPU and 32 GB.
- **Browser sessions.** CodeSandbox has a browser client (`@codesandbox/sdk/browser`, `createBrowserSession`) and its web editor. Sandboxer has no browser SDK. Proxy calls through your server, or give users a hosted port, SSH ([SSH](/docs/ssh)) or the desktop ([Desktop](/docs/desktop)).
- **Free tier.** CodeSandbox's Build plan is free with 10 concurrent VMs. Sandboxer's trial needs a card.
- **Region.** Sandboxer has two regions, us-east (Ashburn, Virginia) and eu-central (Helsinki, Finland); see [regions](/docs/regions). New sandboxes go to the nearest one unless you set `region`.

## Pricing

CodeSandbox's prices are from its [SDK pricing docs](https://codesandbox.io/docs/sdk/pricing), checked 2026-10-27: $0.01486 per VM credit, billed per minute. Ours are from [/pricing](/pricing), billed per second.

| | CodeSandbox SDK | Sandboxer |
| - | - | - |
| 2 vCPU, 4 GB | Nano: 10 credits, $0.1486 per hour | `small` size: $0.018/hour |
| 4 vCPU, 8 GB | Micro: 20 credits, $0.2972 per hour | `default` size: $0.036/hour |
| 8 vCPU, 16 GB | Small: 40 credits, $0.5944 per hour | `large` size: $0.072/hour |
| Plans | Build (free); Scale $170 a month with 1,100 credits included | From $20 a month, all returned as machine time |
| Running at once | 10 on Build; Scale is listed as 250 in the plan table and as 100 in the same page's example | 2 on the trial, 100 on the $20 plan |
| Trial | Free plan, no trial needed | 7 days and 25 hours; needs a card |

Example: one 4 vCPU, 8 GB sandbox running 8 hours a day for 22 days is 176 hours. On CodeSandbox's Micro tier that is 3,520 credits, about $52.31. On Sandboxer, the `default` size costs 176 × $0.036 = $6.34, covered by the $20 plan's included time.

## FAQ

### Do I have to rewrite my CodeSandbox SDK code?

You change the import, the constructor and some method names, and you drop the `connect()` step. The flow stays the same: create, run commands, read and write files, hibernate, resume, fork and delete. The tables above map each call.

### Does `stop` keep running processes like hibernate does?

Yes, when the resume lands on a machine with the same CPU type. In our test a Python counter kept PID 554 and its count across a stop and resume that took 1.3 seconds. If no such machine is free within 2 minutes, the resume boots from disk and reports `memoryRestored: false`.

### Can I fork a running sandbox with its memory?

No. A Sandboxer fork copies the live disk and boots fresh with a new id. The source keeps running. If your product relies on forking a template with a dev server already running, start that server as an enabled systemd service so it starts on boot.

### What replaces `bootupType`?

Check `memoryRestored` and `resumeReason` on the sandbox after a resume. `memoryRestored: true` matches a `RESUME` boot. `false` matches a `CLEAN` boot: files are there, and enabled systemd services have started.

### What happens to my templates?

Rebuild them once. Put `setupTasks` in a setup script, run `sbx new --setup-file`, enable your long-running tasks as systemd services, then save the result with `sbx snapshot <id> <name>`. Start new sandboxes with `--from <name>`.

## Related

- [Sandboxer vs Together Code Sandbox](/compare/together-code-sandbox)
- [Quickstart](/docs/quickstart)
- [TypeScript SDK](/docs/sdk-typescript)
- [Snapshots](/docs/snapshots)
