# Flue Sandbox Types: Virtual, Local, and Container (Daytona) Explained

> Explore Flue sandbox types: Virtual, Local, and Container (Daytona). Understand their distinct isolation levels for secure execution in your projects. Learn more today.

- Repository: [Astro/flue](https://github.com/withastro/flue)
- Tags: deep-dive
- Published: 2026-05-11

---

**Flue provides three sandbox implementations—Virtual (in-process on Cloudflare Workers), Local (direct host access on Node.js), and Container (remote Linux via Daytona)—each offering distinct isolation levels from lightweight in-memory filesystems to full OS containers.**

The withastro/flue SDK abstracts code execution environments through a unified `SandboxFactory` interface. Understanding the differences between **virtual**, **local**, and **container (Daytona)** sandboxes is critical for selecting the right isolation model for your AI agents' runtime requirements.

## Virtual Sandbox: In-Process Isolation for Cloudflare Workers

The **virtual sandbox** runs entirely within Cloudflare Workers using in-process isolation. It provides a POSIX-compliant environment without container overhead by leveraging the `just-bash` library.

### How Virtual Sandboxes Work

In [`packages/sdk/src/cloudflare/virtual-sandbox.ts`](https://github.com/withastro/flue/blob/main/packages/sdk/src/cloudflare/virtual-sandbox.ts), the `getVirtualSandbox` function returns a factory that creates a fresh `Bash` instance for each session. When no R2 bucket is supplied (lines 94-101), the implementation creates an `InMemoryFs` and initializes `new Bash({ fs, network: { dangerouslyAllowFullInternetAccess: true } })`. 

If you provide an R2 bucket (lines 118-124), the sandbox mounts a `WorkspaceFileSystem` backed by Cloudflare KV and SQLite under `/workspace`. All file operations and shell commands execute within the Worker process, never leaving the JavaScript runtime.

### Code Example: Using a Virtual Sandbox

For a stateless agent using the default empty virtual sandbox:

```typescript
import { init } from '@flue/sdk/client';

const harness = await init({
  model: 'anthropic/claude-sonnet-4-6',
}); // Automatically uses virtual sandbox on Cloudflare Workers

```

To enable persistence via Cloudflare R2:

```typescript
import { init } from '@flue/sdk/client';
import { getVirtualSandbox } from '@flue/sdk/cloudflare/virtual-sandbox';

const sandboxFactory = await getVirtualSandbox(bucket, { prefix: 'my-agent' });

const harness = await init({
  sandbox: sandboxFactory,
  model: 'anthropic/claude-sonnet-4-6',
});

```

### When to Use Virtual Sandboxes

Choose this option when deploying to Cloudflare Workers for **serverless agents** that require minimal filesystem state. It starts instantly with zero container billing, making it ideal for stateless or lightweight stateful operations where persistence via R2 is sufficient.

## Local Sandbox: Direct Host Access for Node.js

The **local sandbox** provides no isolation—it delegates directly to the host operating system's filesystem and process execution capabilities. This mode is only available when running Flue on Node.js targets.

### How Local Sandboxes Work

The implementation in [`packages/sdk/src/node/local-env.ts`](https://github.com/withastro/flue/blob/main/packages/sdk/src/node/local-env.ts) exports `createLocalSessionEnv`, which constructs a `SessionEnv` object. All methods—including `exec`, `readFile`, `writeFile`, and `stat`—forward to native Node.js APIs (`child_process.exec` and `fs.promises`).

The `exec` implementation (lines 38-51) respects a configurable `timeout` option and merges it with an `AbortSignal` for graceful cancellation. Working directory resolution occurs at line 28 using `path.resolve`, ensuring all operations respect the configured `cwd`.

### Code Example: Configuring a Local Sandbox

```typescript
import { init } from '@flue/sdk/client';

const harness = await init({
  sandbox: 'local',      // Enables direct host access
  cwd: '/tmp/my-agent', // Optional working directory
  model: 'anthropic/claude-opus-4-20250514',
});

```

### When to Use Local Sandboxes

Use **local** mode when Flue runs inside an external sandbox—such as a CI container, existing Daytona environment, or any infrastructure that already provides process isolation. This avoids the overhead of nested sandboxing while allowing direct manipulation of the host filesystem.

## Container Sandbox (Daytona): Full OS Isolation

The **container sandbox** connects Flue to remote container providers like Daytona, E2B, or Modal through a connector pattern. This provides full Linux environments with package managers, compilers, and persistent volumes.

### How Container Sandboxes Work

Container support relies on the `SandboxFactory` interface defined in [`packages/sdk/src/sandbox.ts`](https://github.com/withastro/flue/blob/main/packages/sdk/src/sandbox.ts). The Daytona connector in [`examples/hello-world/.flue/connectors/daytona.ts`](https://github.com/withastro/flue/blob/main/examples/hello-world/.flue/connectors/daytona.ts) implements `SandboxApi` by wrapping the `@daytona/sdk` client.

The `daytona()` function (lines 12-19) returns a factory whose `createSessionEnv` method builds a `SessionEnv` via `createSandboxSessionEnv(api, cwd)`. The wrapper class (starting line 28) translates Flue's method calls to Daytona's SDK—`exec` (lines 84-99) calls `sandbox.process.executeCommand`, while filesystem operations use `sandbox.fs.downloadFile` and equivalent methods.

### Code Example: Integrating Daytona

```typescript
import { init } from '@flue/sdk/client';
import { Daytona } from '@daytona/sdk';
import { daytona } from './connectors/daytona.ts';

const client = new Daytona({ apiKey: env.DAYTONA_API_KEY });
const sandbox = await client.create({ image: 'ubuntu:22.04' });

const harness = await init({
  sandbox: daytona(sandbox), // Container sandbox
  model: 'anthropic/claude-sonnet-4-6',
});

```

### When to Use Container Sandboxes

Select this option when agents require **full OS isolation**, custom Docker images, specific Linux distributions, or complex toolchains like compilers and databases. The container runs on the provider's infrastructure; Flue communicates via API, making this suitable for resource-intensive or security-sensitive workloads.

## Comparing Flue Sandbox Types

| Feature | Virtual (Cloudflare) | Local (Node) | Container (Daytona) |
|---------|-------------------|--------------|---------------------|
| **Isolation Level** | In-process, no OS container | None (direct host access) | Full OS container |
| **Filesystem** | In-memory or R2-backed | Native host filesystem (`fs.promises`) | Remote container filesystem via provider SDK |
| **Shell Execution** | `just-bash` POSIX emulation | `child_process.exec` (host shell) | Provider's `process.executeCommand` |
| **Target Platform** | Cloudflare Workers only | Node.js only | Any (via connector) |
| **Setup Requirements** | Zero (worker runtime) | Zero (Node environment) | Provider account and API key |
| **Startup Latency** | Instant | Instant | Depends on provider (seconds) |

**Virtual** sandboxes excel for lightweight, serverless deployments where isolation is handled by the Workers runtime. **Local** sandboxes suit controlled environments where Flue itself is already containerized. **Container** sandboxes provide maximum flexibility for complex agent workflows requiring specific system dependencies.

## Summary

- **Virtual sandboxes** run in-process on Cloudflare Workers using `just-bash` and `InMemoryFs`, ideal for fast, serverless agents with minimal state.
- **Local sandboxes** delegate to Node.js native APIs (`child_process.exec`, `fs.promises`) with no isolation, suitable when Flue runs inside existing containerized infrastructure.
- **Container sandboxes** connect to remote providers like Daytona through the `SandboxFactory` interface, offering full Linux environments for complex tooling requirements.
- The `sandbox` option in `init()` accepts `'local'`, a virtual sandbox factory, or a custom connector implementing the `SandboxFactory` interface defined in [`packages/sdk/src/types.ts`](https://github.com/withastro/flue/blob/main/packages/sdk/src/types.ts).

## Frequently Asked Questions

### Which Flue sandbox type should I choose for production AI agents?

**Choose virtual** for Cloudflare-deployed agents handling simple, stateless tasks or R2-persisted state. **Choose container** when agents require specific Linux distributions, package installations, or compiled languages. **Choose local** exclusively when Flue runs inside an already-isolated environment like a CI/CD container or external sandbox where additional isolation would add unnecessary overhead.

### Can I use a local sandbox when deploying to Cloudflare Workers?

No. The **local sandbox** requires Node.js APIs (`node:fs/promises`, `child_process`) only available in Node.js environments. Cloudflare Workers run the **virtual sandbox** by default, utilizing `just-bash` and in-memory or R2-backed filesystems instead of host system calls.

### How does the Daytona connector implement Flue's required interfaces?

The Daytona connector in [`examples/hello-world/.flue/connectors/daytona.ts`](https://github.com/withastro/flue/blob/main/examples/hello-world/.flue/connectors/daytona.ts) implements the `SandboxApi` interface by wrapping the `@daytona/sdk` client. It translates Flue's `SessionEnv` methods to Daytona SDK calls—`sandbox.process.executeCommand` for shell execution and `sandbox.fs.*` methods for file operations. The `daytona()` function returns a `SandboxFactory` compatible with Flue's `init()` configuration.

### What are the security implications of each sandbox type?

**Virtual sandboxes** provide process isolation within the Workers runtime but share the same JavaScript context—suitable for untrusted code only within Cloudflare's security model. **Local sandboxes** offer no isolation and execute with full host permissions, requiring complete trust in the agent code. **Container sandboxes** provide genuine OS-level isolation through Daytona or similar providers, making them appropriate for executing untrusted or third-party code with restricted network and filesystem access.