> ## Documentation Index
> Fetch the complete documentation index at: https://docs.shelv.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox Adapters

> Hydrate shelf files into sandbox runtimes and snapshot provider state.

Use adapters when your agent runtime needs filesystem semantics in a sandbox. Keep your provider-native orchestration and replace custom bootstrapping with a hydrate call from Shelv.

For short jobs, hydrate and run. For repeated jobs, hydrate once and snapshot the runtime.

## Install adapter package

<CodeGroup>
  ```bash pnpm theme={"theme":{"light":"github-light","dark":"poimandres"}}
  pnpm add @shelv/adapters
  ```

  ```bash bun theme={"theme":{"light":"github-light","dark":"poimandres"}}
  bun add @shelv/adapters
  ```

  ```bash npm theme={"theme":{"light":"github-light","dark":"poimandres"}}
  npm install @shelv/adapters
  ```
</CodeGroup>

Runtime support:

* Official runtime support: Node.js 18+ (ESM)
* Bun is supported as a package manager for install
* Bun runtime execution is best-effort in v1 and not part of the official runtime guarantee

Licensing:

* `@shelv/adapters` is distributed under the Apache-2.0 license.
* Source code: [github.com/shelv-dev/shelv-adapters](https://github.com/shelv-dev/shelv-adapters)

## Hydrate and snapshot

Set your API key as an environment variable (`SHELV_API_KEY`), then hydrate a sandbox and snapshot it:

```typescript theme={"theme":{"light":"github-light","dark":"poimandres"}}
import { createShelvClient, createVercelAdapter } from "@shelv/adapters";

const client = createShelvClient({
  apiKey: process.env.SHELV_API_KEY!,
});

const adapter = createVercelAdapter();
await adapter.hydrate({
  client,
  sandbox,
  shelfPublicId,
  mode: "archive-first",
});

const snapshot = await adapter.snapshot({
  sandbox,
  name: `shelf-${shelfPublicId}`,
});
```

Default mode is `archive-first` with automatic fallback to `tree` when archive retrieval fails. Use `tree-only` for small shelves and `archive-only` for strictly snapshot-based workflows.

`createShelvClient` uses `https://api.shelv.dev` by default. Pass `apiBaseUrl` only when targeting a non-production Shelv API.

Checksum verification is built in for archive mode. If checksum or archive parsing fails, `archive-first` falls back to tree retrieval so your run can continue without custom recovery code.

## Provider coverage

| Adapter                      | `hydrate()` | `snapshot()` |
| ---------------------------- | :---------: | :----------: |
| `createVercelAdapter()`      |     Yes     |      Yes     |
| `createDaytonaAdapter()`     |     Yes     |      Yes     |
| `createE2BAdapter()`         |     Yes     |      Yes     |
| `createCodeSandboxAdapter()` |     Yes     |      No      |
| `createDenoAdapter()`        |     Yes     |      No      |
| `createJustBashAdapter()`    |     Yes     |      No      |

CodeSandbox, Deno, and Just-Bash adapters are hydrate-only — CodeSandbox uses git-backed persistence, Deno sandboxes are ephemeral, and Just-Bash runs in-memory, so none expose a `snapshot()` method.

## Just-Bash integration

[Just-Bash](https://justbash.dev/) is a sandboxed TypeScript bash interpreter with an in-memory virtual filesystem, designed for AI agents. Shelv provides three levels of integration depending on your use case.

### Adapter

Use the standard adapter when you already have a Just-Bash `Sandbox` instance:

```typescript theme={"theme":{"light":"github-light","dark":"poimandres"}}
import { createShelvClient, createJustBashAdapter } from "@shelv/adapters";
import { Bash } from "just-bash";

const client = createShelvClient({
  apiKey: process.env.SHELV_API_KEY!,
});

const sandbox = new Bash();
const adapter = createJustBashAdapter();

await adapter.hydrate({
  client,
  sandbox,
  shelfPublicId,
  mode: "tree-only",
});

// sandbox now has all shelf files — run commands against it
```

### Bash factory with lazy loading

Use `createShelvBash` when you want to pass files directly to the `Bash` constructor. This avoids creating a sandbox first and hydrating it separately.

**Eager mode** (default) fetches all file content upfront:

```typescript theme={"theme":{"light":"github-light","dark":"poimandres"}}
import { createShelvClient } from "@shelv/adapters";
import { createShelvBash } from "@shelv/adapters";
import { Bash } from "just-bash";

const client = createShelvClient({
  apiKey: process.env.SHELV_API_KEY!,
});

const result = await createShelvBash({
  client,
  shelfPublicId,
  mode: "tree-only",
});

const sandbox = new Bash({ files: result.files });
```

**Lazy mode** fetches only file paths upfront and loads content on first read. For a 200-file shelf where the agent reads 10, this means 1 listing call + 10 file calls instead of downloading all 200 files:

```typescript theme={"theme":{"light":"github-light","dark":"poimandres"}}
const result = await createShelvBash({
  client,
  shelfPublicId,
  lazy: true,
});

// files are () => Promise<string> — Just-Bash evaluates on first read
const sandbox = new Bash({ files: result.files });
```

### bash-tool helper

Use `createShelvBashTool` for the quickest integration with the AI SDK. It creates a bash-tool instance pre-loaded with shelf files:

```typescript theme={"theme":{"light":"github-light","dark":"poimandres"}}
import { createShelvClient, createShelvBashTool } from "@shelv/adapters";

const client = createShelvClient({
  apiKey: process.env.SHELV_API_KEY!,
});

const { tools, sandbox } = await createShelvBashTool({
  client,
  shelfPublicId,
  mode: "tree-only",
});

// Pass tools to your AI SDK generateText / streamText call
```

Requires `bash-tool` as a peer dependency:

```bash theme={"theme":{"light":"github-light","dark":"poimandres"}}
pnpm add bash-tool
```
