Flue Sandbox Types: Virtual, Local, and Container (Daytona) Explained
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, 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:
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:
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 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
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. The Daytona connector in 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
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-bashandInMemoryFs, 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
SandboxFactoryinterface, offering full Linux environments for complex tooling requirements. - The
sandboxoption ininit()accepts'local', a virtual sandbox factory, or a custom connector implementing theSandboxFactoryinterface defined inpackages/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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →