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-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.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →