About the Author

V

Victor Mota

Co-founder

Topics

agents
open source
sandbox
code execution
developer tools
agents
open source
sandbox
code execution
developer tools
January 20, 2026

Localsandbox: A Lightweight Agent Sandbox

Today we're open sourcing Localsandbox, a lightweight library that gives agents a sandboxed filesystem with safe bash and code execution.

Victor Mota

Co-founder

Today we're open sourcing Localsandbox, a lightweight library that gives agents a sandboxed filesystem with safe bash and code execution. It's a Python SDK built atop the work of some incredible projects: Turso's AgentFS, Vercel's just-bash, and Pyodide.

Note: This project is experimental and relies on the security of the underlying projects—so use it with caution. If you need critical security guarantees, use a container sandbox from one of the providers (e.g., Modal).

Why this exists

Coding agents like Cursor and Claude Code get their power from a simple insight: instead of designing custom tools for every possible task, given a filesystem and the ability to run code, the agent can figure out the rest.

This works well when the agent runs locally on your machine — you're responsible for the risk. But if you're building agentic products on your own infrastructure, letting agents run arbitrary code on your servers isn't a great idea. They could access data they shouldn't, interfere with each other, or take destructive actions.

The standard solutions are container sandboxes from startup providers like Modal, Daytona, or E2B or the enterprise cloud providers like Azure Container Apps Dynamic Sessions, Google Cloud Run, and AWS AgentCore Code Interpreter. These offer strong isolation guarantees but come with operational overhead, cost, and latency.

Localsandbox is a lightweight alternative for local development, testing, or situations where you don't need full container isolation. Because it's backed by SQLite, it has the nice property of being portable making it perfect for durable execution environments that need to be able to be restored and resumed.

At CoPlane, we bring AI to critical backoffice operations of large enterprises, where there is an expectation that data will remain in customers' environments. Localsandbox is one of our experiments at supporting more powerful agentic capabilities given those constraints.

For a deeper look at why filesystem and code execution matter for agents beyond software development, see our companion post: Agent Sandboxes: How we got here.

Architecture

Localsandbox combines three components:

┌─────────────────────────────────────────┐
│             Your Agent                  │
├─────────────────────────────────────────┤
│           Localsandbox API              │
├──────────┬──────────┬───────────────────┤
│ just-bash│ Pyodide  │                   │
│  (bash)  │ (python) │                   │
├──────────┴──────────┤                   │
│      AgentFS        │    SQLite DB      │
│  (virtual filesystem)                   │
└─────────────────────────────────────────┘

AgentFS (from Turso) provides a virtual filesystem backed by SQLite. This makes sandboxes portable—you can snapshot, restore, and move them trivially.

just-bash (from Vercel) interprets a subset of bash over the virtual filesystem. Your agent can run grep, cat, ls, pipes, and redirects without touching your real filesystem.

Pyodide executes Python in a WASM sandbox with the AgentFS filesystem mounted. The agent can write and run Python scripts that read and write files, all isolated from your host system.

Quick Start

from localsandbox import LocalSandbox
 
# Basic usage with context manager (recommended)
with LocalSandbox() as sandbox:
    result = sandbox.bash('echo "Hello, World!"')
    print(result.stdout)  # Hello, World!
 
# Seed initial files (all paths use /data prefix)
files = {"/data/invoices.csv": Path("invoices.csv"), "/data/ids.csv": "123\n456\n789"}
with LocalSandbox(files=files) as sandbox:
    content = sandbox.execute_python("open('/data/invoices.csv').read()")
    print(content)
 
# Use file helpers
with LocalSandbox() as sandbox:
    sandbox.write_file("/data/config.json", '{"key": "value"}')
    content = sandbox.read_file("/data/config.json")
    exists = sandbox.exists("/data/config.json")
    files = sandbox.list_files("/data")
 
# Snapshot & resume
with LocalSandbox() as sandbox:
    sandbox.bash('echo "state" > /data/file.txt')
    snapshot = sandbox.export_snapshot()
 
# Later, restore from snapshot
with LocalSandbox(snapshot=snapshot) as sandbox:
    result = sandbox.bash('cat /data/file.txt')
    print(result.stdout)  # state

Wrapping as agent tools

Localsandbox doesn't prescribe a tool format—you wrap the APIs in whatever framework you're using. Here's an example for a typical tool-calling pattern:

from planar.ai import Agent
from localsandbox import LocalSandbox, CommandError
 
sandbox = LocalSandbox()
 
def bash_tool(command: str) -> str:
    """Run a bash command in the sandbox."""
    try:
        result = sandbox.bash(command)
        return result.stdout
    except CommandError as e:
        return f"Command failed (exit {e.exit_code}): {e.stderr}"
    except FileNotFoundError as e:
        return f"File not found: {e.path}"
 
def python_tool(code: str) -> str:
    """Execute Python code in the sandbox."""
    try:
        result = sandbox.execute_python(code)
        return result.stdout
    except Exception as e:
        return f"Error: {e}"
 
def write_file_tool(path: str, content: str) -> str:
    """Write a file to the sandbox filesystem."""
    sandbox.write_file(path, content)
    return f"Wrote {len(content)} bytes to {path}"
 
def read_file_tool(path: str) -> str:
    """Read a file from the sandbox filesystem."""
    return sandbox.read_file(path)
 
# Then pass these tools to your agent framework
# Here we use our own planar agent API, but this would work for any other agent such as LangChain, PydanticAI, etc
code_executor_agent = Agent(
    name="code_executor",
    system_prompt="""You have access to the following tools:
- python_tool: Execute Python code in the sandbox
- bash_tool: Execute a bash command in the sandbox
- read_file_tool: Read a file from the sandbox
- write_file_tool: Write to a file in the sandbox
 
Important notes about the sandbox:
- Each execution is ephemeral - variables don't persist between calls
- You can use standard library modules
- Print statements will show in stdout
- The sandbox filesystem is mounted at /data
""",
    user_prompt="""
    Solve the problem below using the available tools:
 
    {{ input }}
    """,
    tools=[bash_tool, python_tool, read_file_tool, write_file_tool],
    model="openai:gpt-4.1",
    max_turns=10,
)

This gives you control over error handling—return errors to the agent for self-correction, or raise exceptions to halt execution.

When to use Localsandbox vs. container sandboxes

Use Localsandbox when:

  • Developing and testing locally
  • Building demos or prototypes
  • Running agents where the blast radius is acceptable
  • You need fast startup and low overhead

Use a container sandbox (Modal, Daytona, E2B) when:

  • Running in production with untrusted inputs and risk of prompt injection
  • You need strong multi-tenant isolation
  • You require full Linux compatibility

Localsandbox is not a security boundary in the way containers are. It provides isolation from your host filesystem and limits what bash and Python can do, but it inherits the security properties of its underlying components.

Limitations

  • Experimental. This relies on the security of AgentFS, just-bash, and Pyodide. Use caution in production.
  • Subset of bash. just-bash implements common utilities but not everything. Complex shell scripts may not work.
  • Subset of Python. Pyodide runs in WASM, so some stdlib modules and most C extensions aren't available. You can install pure-Python packages via micropip, but numpy, pandas, and similar libraries have limited support.
  • No networking. The sandbox doesn't provide network access by default.

Get started