all posts

The Best Open-Source Coding Agents in 2026 — and What Each One Needs From the Machine It Runs On

Ajay Kumar··14 min read

There are two questions you can ask about an open-source coding agent. The first is the one every roundup answers: how good is it at writing code? That question has a short shelf life, because the answer is mostly a property of the model behind it, and the models change every few months. The second question is the one almost nobody asks, and it is the one you will still be living with in a year: where does this thing execute the commands it decides to run?

Because that is what all of these tools are. Strip away the TUI, the diff viewer, the plan/act toggle, the repo map, the MCP extensions — underneath every open-source coding agent is a loop that asks a language model what to do next and then does it. Some of the things it does are file edits. Some of them are shell commands. And the default place those shell commands land, for nearly every tool on this page, is the machine you are sitting at, running as you, with your SSH agent, your cloud credentials, your kubeconfig, your npm token and your browser cookies all one `cat` away.

I'm Ajay. I build PandaStack, a Firecracker microVM platform that exists partly to be the other place those commands can land, so treat this as a vendor's roundup and weight it accordingly. I have tried to earn your trust in the only way that's available to me: everything I say about someone else's project is qualitative and checkable against their own docs, every number I quote is about my own platform, and there is a whole section near the end about when putting an agent in a microVM is the wrong call. If a roundup written by a vendor concludes that every reader should buy the vendor's thing, it is an ad with headings.

Standing caveat for the whole post: this category moves faster than any other part of the developer tooling world right now. Licences change, execution backends get added, sandboxing modes ship and get renamed, projects fork. Everything here is written to be true at the level of category and tradeoff rather than feature checkboxes — verify anything load-bearing against each project's own documentation and repository before you commit an engineering week to it. I deliberately quote no version numbers, no star counts, and no benchmark scores, because all three would be wrong by the time you read this.

First, three different products wearing the same word

The single most common mistake in this category is comparing tools that are not competitors. "Coding agent" currently covers at least three distinct products, and the sensible choice between them depends more on your workflow than on any capability benchmark.

  • Terminal-first pair programmers. You run them in a shell, in your repo, and they edit your working tree while you watch. The human is in the loop on roughly every step, and the value is speed of iteration on code you own and understand. Aider is the archetype; most of the CLI agents land here too.
  • Autonomous issue-solvers. You hand them a task — a GitHub issue, a failing test, a description — and they go away and work: read the codebase, edit, run tests, iterate, come back with a patch or a pull request. The human is in the loop at the end, not at every step. SWE-agent is the research-lineage version; OpenHands is the productised one.
  • IDE-embedded assistants with an agent mode. They live in VS Code or JetBrains, they know your open files and your selection, and they have graduated from autocomplete to multi-file edits plus a terminal tool. Cline, Roo Code and Continue live here. The ergonomics are excellent and the execution model is inherited from your editor, which is to say from your laptop.

These three shapes have genuinely different failure modes. A pair programmer that runs something stupid gets caught in about four seconds because you are staring at it. An autonomous issue-solver running unattended overnight against fifty issues will not get caught, which is exactly the property you wanted from it, and also exactly the property that makes the execution question urgent. An IDE assistant sits in the middle and is the most dangerous of the three in one specific way: the UI trains you to click approve, so by week three you are approving without reading, and there is usually an auto-approve setting that formalises the habit.

Every one of these tools is a shell with a language model attached. The interesting differences are not in the model. They are in what the shell can reach.

The axis this post is organised around

Before the field, the framework, because the field only makes sense against it. Any agent's execution model sits on one of four rungs, and — this is the part that catches people — most tools can be configured onto several of them, so the rung is a decision you make, not a property you buy.

Rung 0: your host, as you

The default. The agent runs `bash -c` as your user, in your repo, on your laptop or your dev box. Everything your shell can reach, it can reach: `~/.aws/credentials`, `~/.ssh/id_ed25519`, `~/.kube/config`, `~/.npmrc`, `~/.docker/config.json`, the GitHub token in your git credential helper, the production database whose hostname is in your `.env`, and the VPN route that makes all of the above interesting to somebody else.

The honest thing to say about rung 0 is that it is fine a lot of the time, and pretending otherwise makes the rest of this post easy to dismiss. A senior engineer running a pair programmer on a private repo they wrote, watching every diff, approving every command, is not in meaningful danger. The blast radius is real but the fuse is short and there is a human holding it. Where rung 0 stops being fine is precisely where agents get useful: unattended runs, long tasks, code you didn't write, dependencies you didn't audit, and any workflow where the agent reads text from outside your organisation.

Rung 1: a container on your machine

A Docker or Podman container with the repo bind-mounted in. This is the standard upgrade, it's cheap, and it removes most of what actually goes wrong: the agent gets a filesystem where your dotfiles do not exist, a process namespace of its own, and — if you configure it, which most people don't — a network policy. Several of the tools below either ship this as their default runtime or make it a one-flag change, and if you take exactly one action from this post, making your agent run in a container is the one with the best effort-to-risk ratio.

Two caveats worth internalising. First, a bind mount is a hole you drilled on purpose: the agent's `rm -rf` on the mounted path deletes your real files, container or no container. Second, the kernel is shared. Container escape via a kernel bug is not the threat model most teams should be optimising against, but "the agent's code has full access to your host's syscall surface" is a true sentence, and it matters more when the code is genuinely adversarial rather than merely careless. A mounted Docker socket — which people add so the agent can build images — collapses the rung to zero silently.

Rung 2: OS-level sandboxing on the host

Some agents have started shipping this themselves rather than delegating to a container: a seccomp/Landlock profile on Linux, a Seatbelt profile on macOS, restricting filesystem writes to the workspace and blocking network by default unless you approve it. Codex CLI and Gemini CLI both have something in this space, and it's a genuinely good development, because it means the safe mode is available to someone who does not run Docker. It's also the rung with the most variation between tools and the most churn between releases, so this is exactly the claim to check against current docs rather than against me.

Rung 3: a remote VM the agent owns entirely

The repo is cloned inside a machine that is not yours, the agent's shell tool is an RPC to that machine, and the worst thing an unhinged command can do is destroy an environment you were going to throw away anyway. Your credentials are not on it, because you never put them there. Its network egress is a policy enforced outside the guest, where the agent can't flush the rules. When the task is done the whole thing stops existing.

This rung used to have an obvious, fatal cost: latency. Booting a VM per task puts tens of seconds in front of every run; teams pool VMs to hide that; pooled VMs outlive tasks; and now you have shared mutable state plus a fleet to operate, having given up the exact property you wanted. Snapshot-restore is what changed the arithmetic. On PandaStack every create is a restore of a pre-booted memory image rather than a cold boot — about 179ms p50, 203ms p99 — so a fresh guest kernel per task costs roughly what a container start costs. That's the reason this rung is worth reconsidering in 2026 even if you dismissed it in 2023.

The rung is almost always chosen by accident — by installing the tool the way the README's quickstart shows, and never revisiting it. Go and find out which rung each agent you currently run is on. Not what it can be configured to do: what yours is doing right now, today, with the config on your disk.

The field, agent by agent

Ordered roughly by how autonomous they are, because that turns out to correlate with how much the execution question matters.

Aider

Aider is the terminal pair programmer that most of the category is a reaction to, and it remains the cleanest expression of the idea. You run it inside a git repository, you talk to it, it edits files and makes a git commit per change. That last detail is the design decision that makes it good: every edit is a commit, so `git diff` and `git reset` are your undo, and reviewing an agent's work becomes the thing you already know how to do. It builds a map of the repository so it can pick relevant context rather than shovelling the whole tree at the model, and it is model-agnostic — you point it at whichever API or local model you prefer.

Execution model: rung 0, deliberately. It edits your actual working tree, and running commands (tests, linters) is something it asks about rather than something it silently does. That is the correct design for what it is. Aider is a tool for a developer who is present, and the whole value proposition dissolves if the edits land somewhere other than the files in the editor you have open. If you find yourself wanting to sandbox Aider, what you probably want is a different tool, or Aider running inside a dev container so the workspace it edits is the workspace it's confined to.

Where it needs help from the machine: almost nothing. A shell, git, and whatever your project needs to run its tests. It is the least infrastructure-hungry entry on this page, and for a solo developer on their own code that is a feature and not a limitation.

OpenHands (formerly OpenDevin)

OpenHands is the most complete open-source implementation of the autonomous-issue-solver shape. It came out of the OpenDevin project, is developed in the open by All Hands AI, and it gives an agent a browser, a shell, a file editor and a code-execution surface, driven through a web UI or headlessly. You give it a task; it works the task. It's the project I'd point at if someone asked what "an open-source Devin" concretely looks like as software you can run.

Execution model, and this is why it leads the pack for our purposes: OpenHands treats the execution environment as a first-class, swappable component rather than an afterthought. Actions go to a runtime, the default runtime is a container, and there are remote and hosted runtime options in the ecosystem. That architecture is the right one, and it means the security question for OpenHands is not "can I sandbox it" but "which runtime did I configure and what does that runtime allow out to the network." Check the current runtime documentation before you deploy it anywhere multi-tenant, because this is the layer they iterate on most.

Where it needs help from the machine: more than you expect. An agent with a browser tool is running a headless Chromium, which wants real memory. An agent that clones a repo, installs dependencies, runs a build and executes a test suite needs disk and a warm toolchain or it spends its first three minutes on `npm install` every single time. And if you run more than one task at once — which is the entire point of an autonomous issue-solver — you are now running N of those environments concurrently, and the honest resource conversation is about gigabytes per concurrent agent, not per install.

SWE-agent

SWE-agent comes from the research lineage — the Princeton/Stanford work on getting language models to resolve real GitHub issues — and knowing that explains almost everything about its shape. Its central idea is the agent-computer interface: rather than handing a model a raw terminal and hoping, you design the commands the agent gets, the way their output is formatted, and the feedback it receives when it does something malformed. That framing was influential and you can see its fingerprints in tools that never cite it.

Execution model: containerised per task instance, by design, because it grew up running batches of benchmark instances where reproducibility and isolation are the whole point. The team also maintains a separate execution-backend layer for running agent commands across local, container and cloud targets, which is a sign of a project that took the "where does this run" question seriously years before the product-shaped tools did.

A note on benchmarks, since SWE-agent is the entry most associated with them. SWE-bench is a family of benchmarks — variants differ in task set, in whether the tasks are verified by humans, and in how the harness is allowed to help — and scores on it move constantly as models and scaffolds change. I am not quoting a number. Go and look at the current public leaderboards yourself, read which variant is being reported, and treat any vendor blog post citing a score without naming the variant and the date as marketing rather than evidence.

Where it needs help from the machine: batch capacity, more than anything else. The natural way to use SWE-agent is to run many instances in parallel across many task environments, which makes per-instance start-up cost and per-instance memory the numbers that decide whether an evaluation run takes an hour or a night.

Goose

Goose is Block's open-source agent, and it is the most interesting entry here for a reason unrelated to coding quality: it is not really a coding agent, it's a general on-machine agent that is very good at coding tasks. It ships as both a desktop app and a CLI, and its extension model is built on MCP, which means the set of things it can do is open-ended in a way the others are not — it can drive your development tools and also your ticket tracker, your cloud CLI, your browser, whatever you connect.

That openness is the whole security story. An agent whose capability set is a plugin list has a blast radius equal to the union of every extension you've enabled, and unlike a fixed shell tool that surface changes every time you add one. Extensions run with the agent's privileges, which by default are your privileges. If you run Goose with a handful of MCP servers connected to real systems, sit down and write out what the worst plausible sequence of tool calls does, because that list is your actual threat model, and it is not the same list as "the agent might delete a file."

Where it needs help from the machine: it is designed to be on your machine, and much of the value is the local context — your files, your CLIs, your credentials, your sessions. Boxing it up in a remote VM removes a lot of the point. The right move with Goose is not isolation, it's curation: be deliberate about which extensions are loaded for which session, and treat the extension list like an IAM policy rather than like a browser toolbar.

Cline and Roo Code

Cline is the VS Code extension that made the agentic-editor shape feel inevitable, and Roo Code is a fork of it that went its own way on configurability. Both are open source, both live inside your editor, and both do the thing that makes this category work: propose a plan, make multi-file edits, run terminal commands, read the output, iterate. The plan-then-act separation Cline popularised is a genuinely good UX invention — it lets you correct the approach before any code is touched, which is when correction is cheap.

Execution model: rung 0, through your editor. The commands run in your integrated terminal, on your machine, as you, in your repo. Both tools gate actions behind approval prompts by default, and both have auto-approve controls for people who find the prompts tedious. I want to be blunt about the auto-approve settings, because this is the single most common way a careful team ends up with an unsupervised agent: the prompts are annoying, the agent is right ninety-something percent of the time, so you widen the auto-approve list to get flow back, and now you have an autonomous agent with your credentials and no human gate — arrived at through a UI preference rather than a decision anybody wrote down.

Where it needs help from the machine: the editor's workspace, which is the point. The sane isolation story for these two is a dev container: VS Code's remote-container support means the extension and its terminal live inside the container, so the agent's world is the workspace and its dependencies rather than your home directory. That's a rung-1 answer that costs you almost no ergonomics, and it's the one I'd recommend to most teams using them.

Continue

Continue is the open-source IDE assistant that treats the assistant itself as configuration. It runs in VS Code and JetBrains, it does autocomplete and chat and agent-style edits, and its distinguishing feature is that the model, the context providers, the rules and the tools are declared rather than baked in — you can point it at a hosted API, at your own inference endpoint, or at a local model, and share that configuration across a team.

That makes it the natural pick for an organisation with a constraint about where inference happens. If code cannot leave your network, an assistant that will happily talk to a model server you host is worth more than a marginally smarter one that won't. Execution model is rung 0 again, through the IDE, with the same dev-container upgrade path as Cline and Roo. Its agent mode is less aggressively autonomous than the issue-solvers above, which correspondingly lowers the urgency of the isolation question — but only correspondingly, not to zero.

Where it needs help from the machine: if you're running local models to keep code in-house, the machine requirement moves from the agent to the inference server, and that's a GPU conversation rather than a sandbox one. Don't let a sandboxing project distract you from the fact that your bottleneck is a model server.

The vendor CLI agents: Claude Code, Codex CLI, Gemini CLI

These belong in this post with an asterisk, because "open source" is doing uneven work across them. Codex CLI and Gemini CLI are open-source clients for proprietary models — the terminal agent is code you can read and fork, the intelligence is an API you rent. Claude Code is not open source at all; I'm including it because it defines the shape a lot of this category is now copying, and because the execution question applies to it identically. Anthropic makes Claude Code, and I use it; disclose that and discount accordingly.

What makes them relevant here rather than out of scope is that the vendors shipping them have, collectively, done more practical work on local agent sandboxing than the rest of the ecosystem combined. Codex CLI ships OS-level confinement — a Seatbelt profile on macOS, Landlock and seccomp on Linux — with approval modes governing when the agent may write outside the workspace or reach the network. Gemini CLI can run its tools inside a container or a macOS Seatbelt profile. Claude Code gates tool calls behind permission prompts with allow and deny lists, and there's an established pattern of running it inside a dev container for unattended work. The details differ per release and I'd check each project's current sandboxing docs rather than trusting this paragraph in six months.

The reason this matters for the open-source tools above: it has normalised the idea that the safe mode ships in the box. If you're choosing between two otherwise-similar agents, the one that has a documented, tested confinement mode is the better engineering bet, independent of which writes prettier code this quarter.

The cohort that didn't exist last year

There is a steady stream of new terminal-first agents — OpenCode and Crush among them, plus forks and descendants of Cline in the editor space — and by the time you read this there will be more. I'm not going to characterise tools I haven't run for long enough to have an opinion worth publishing. What I'll say instead is that they all have the same architecture underneath and therefore the same question: read the README section on sandboxing, and if there isn't one, that is itself the answer. A coding agent released in 2026 without a documented execution boundary is telling you which rung it's on.

What actually goes wrong, in rough order of likelihood

The threat everybody talks about is `rm -rf`, and it is genuinely the least of these. Here is the list as I'd rank it by how often it actually costs someone something, informed by watching agents run on our own platform and by the incident reports of people who let them run somewhere else.

  1. Dependency install scripts. The agent decides it needs a package, runs the install, and an npm postinstall or a Python setup.py executes arbitrary code as you, before your agent has produced a single line of output. This has nothing to do with the model being wrong — the agent behaved correctly and the supply chain did the damage. It is the most common way an agent session becomes a compromise, and no amount of approval-prompt discipline helps, because you approved the install and the install was reasonable.
  2. Credential exfiltration through ordinary-looking commands. Your cloud credentials are in a file, and reading a file is the most normal thing an agent does all day. There is no anomaly to detect: `cat ~/.aws/credentials` and `cat src/config.ts` are the same syscall. If the agent can be induced to read and transmit, the boundary you needed was that the credentials weren't there.
  3. Prompt injection from repository and issue content. The agent reads a README, an issue body, a code comment, a dependency's docs, a web page it fetched — and that text contains instructions. This is not hypothetical and it is not solved. It is the reason "the agent only runs commands I approve" is weaker than it sounds: a sufficiently plausible-looking command gets approved. The mitigations that work are structural, not behavioural: no credentials in the environment, egress default-denied, and a machine you were going to delete.
  4. Destructive mistakes. `rm -rf` on the wrong path, `git reset --hard` over uncommitted work, a migration run against the wrong database because both connection strings were in the environment. Recoverable if your work is committed and your prod credentials aren't reachable; expensive otherwise. Aider's commit-per-change design is a real mitigation here and deserves credit for it.
  5. Runaway resource consumption. An agent in a retry loop, a test suite that forks, a build that eats memory until the OOM killer picks your editor. On your laptop this is an annoyance. On a shared dev box running several people's agents it's an outage, and it's the failure mode that most often turns "we let the team try agents" into "we banned agents on the build server."
  6. Uncontrolled network egress. Less about exfiltration than about the agent quietly reaching internal services because it's on a machine with VPN routes. The agent doesn't know your staging database isn't a toy. Egress policy enforced outside the execution environment is the only version of this control that survives contact with an agent that can edit iptables.

Look at that list and notice what the mitigations have in common. Almost none of them are "be more careful with approvals." They are all structural properties of the environment: what credentials exist in it, what network it can reach, and whether destroying it costs anything. That is the entire argument for moving up a rung, and it's an argument about architecture rather than about trusting the model.

The problem you hit second: running more than one

The first thing that happens when an agent becomes useful is that you want two of them. Then five. One per issue in the backlog, or three attempts at the same hard bug so you can pick the one whose tests pass. This is where the execution model stops being a security question and becomes a plain engineering constraint, because agents are extremely bad at sharing a working directory.

Two agents in one repo will fight over the index, stomp each other's edits, and produce a `git status` that means nothing. The obvious fix is `git worktree` — separate checkouts, shared object store, cheap — and it genuinely solves the source-control collision. What it doesn't solve is everything else that isn't in git: `node_modules` resolved differently per branch, a `.venv`, a port number two dev servers both want, a local database with schema from whichever migration ran last, a build cache that now has entries from three different branches interleaved. Worktrees give you three checkouts on one machine, and the machine is the shared mutable state.

Containers fix that: one container per agent, each with its own filesystem, its own ports, its own dependency tree. It's a good answer and for most teams it's the right one. The costs show up at the edges — image build and dependency install per container unless you're careful with layer caching, and the memory of N concurrent environments, which is a real number once each one is running a language server and a test suite.

The VM answer adds one thing the container answer structurally can't: forking a live environment. Once you've got a machine with the repo cloned, dependencies installed, the database migrated and the dev server running, you can copy that entire state — memory and disk — and hand a copy to each attempt. On PandaStack that's a copy-on-write fork: memory pages are shared until written, the disk clone is an XFS reflink, and a same-host fork takes 400 to 750 milliseconds. Every attempt starts from the identical warmed state, at the millisecond after the setup finished, and diverges from there.

For three agents attacking one bug, that's the difference between three independent five-minute setups that are subtly different from each other and three forks of one setup that are provably identical. For an eval harness running hundreds of task attempts, it's the difference between a night and an hour. If you never need this, it's a curiosity. If you do need it, nothing at rung 0 or rung 1 gives it to you, and that asymmetry is most of why I built what I built.

Pointing an agent's shell tool at a remote machine

Here's the concrete shape, because "run your agent in a sandbox" is vague enough to be useless as advice. You do not rewrite the agent. You replace the implementation of exactly one function — the one behind its bash or run_command tool — so that it makes an RPC instead of calling `subprocess.run`. Everything above that function is unchanged: the same loop, the same prompts, the same model.

This is the whole trick, and it's why the execution model is a genuinely swappable component in any agent whose tool layer is a function. The agent believes it has a shell. It does. The shell is just somewhere else.

# agent_shell.py -- swap an agent's local shell tool for a remote microVM.
#
# pip install pandastack   (PANDASTACK_API_KEY in the environment)
#
# The only thing that changes is the body of bash(). Everything above it --
# the agent loop, the tool schema, the prompt -- stays exactly as it was.

import os
from pandastack import Sandbox

REPO = "https://github.com/acme/widgets.git"


def start_workspace(task_id: str) -> Sandbox:
    """One task, one microVM, its own guest kernel. ~179ms p50 to create."""
    sbx = Sandbox.create(
        template="base",              # Ubuntu + mise: node, python, go, bun
        ttl_seconds=3600,             # a wedged agent gets reaped, not billed
        metadata={"task": task_id, "owner": "agent-runner"},
    )

    # Notice what is NOT in this environment: your ~/.aws, your ~/.ssh, your
    # kubeconfig, your npm token, your VPN routes. The agent cannot exfiltrate
    # credentials that were never put on the machine. That is the control --
    # not a prompt telling it to behave.
    sbx.exec(f"git clone --depth 1 {REPO} /work", check=True)
    sbx.exec("cd /work && npm ci", timeout_seconds=600, check=True)
    return sbx


def bash(sbx: Sandbox, command: str, timeout: int = 120) -> dict:
    """The agent's shell tool. This is the entire integration.

    Return the same shape your agent already expects from its local
    implementation -- stdout, stderr, exit code -- and the loop above it
    neither knows nor cares that the command ran on another machine.
    """
    r = sbx.exec(f"cd /work && {command}", timeout_seconds=timeout)
    return {
        "stdout": r.stdout[-20_000:],   # models do not need 4MB of webpack log
        "stderr": r.stderr[-20_000:],
        "exit_code": r.exit_code,
    }


# --- wire it into whatever tool-calling framework you already use ----------
TOOL_SCHEMA = {
    "name": "bash",
    "description": "Run a shell command in the project workspace.",
    "input_schema": {
        "type": "object",
        "properties": {
            "command": {"type": "string"},
            "timeout": {"type": "integer", "default": 120},
        },
        "required": ["command"],
    },
}


def run_task(task_id: str, agent_loop) -> str:
    sbx = start_workspace(task_id)
    try:
        # agent_loop calls bash(sbx, ...) whenever the model emits a tool call.
        # rm -rf / in here costs you a machine you were deleting anyway.
        agent_loop(tools={"bash": lambda **kw: bash(sbx, **kw)})
        diff = sbx.exec("cd /work && git diff", timeout_seconds=60)
        return diff.stdout
    finally:
        sbx.kill()   # workspace, node_modules, page cache and guest kernel
                     # all stop existing together

Two details in there are load-bearing and easy to miss. The first is the output truncation: an agent's shell tool that returns the full stdout of a failing webpack build will blow your context window and cost you real money, and every team building this discovers it the expensive way. Truncate at the tool boundary, keep the tail rather than the head, because the error is at the end.

The second is the `finally`. Teardown that depends on the agent finishing cleanly is teardown that doesn't happen, because the interesting failures are the ones where the agent didn't finish cleanly. The TTL is the backstop for when your own process dies too — set it, because a fleet of orphaned sandboxes from a crashed orchestrator is the most predictable bill in this business.

And the version that runs three attempts at once

Same primitive, one extra step: prepare the workspace once, fork it, give each fork to a different agent configuration. The forks share memory pages and disk blocks until they write, so N attempts cost roughly one warm environment plus each attempt's own divergence.

from concurrent.futures import ThreadPoolExecutor
from pandastack import Sandbox

# Prepare ONCE: clone, install, migrate, warm the caches, start the dev server.
# This is the expensive part and you should pay for it exactly one time.
base = Sandbox.create(template="base", ttl_seconds=7200)
base.exec("git clone --depth 1 https://github.com/acme/widgets.git /work", check=True)
base.exec("cd /work && npm ci", timeout_seconds=600, check=True)
base.exec("cd /work && npm run db:migrate", timeout_seconds=300, check=True)

# Fork it. Copy-on-write memory + XFS reflink disk: 400-750ms per fork on the
# same host. Every child starts from the identical millisecond of warm state,
# which is what makes attempts comparable rather than merely similar.
attempts = base.fork_tree(3, metadata={"task": "fix-flaky-auth-test"})


def attempt(child, strategy: str) -> dict:
    try:
        child.exec(f"cd /work && echo {strategy!r} > /work/.strategy")
        # ... run your agent loop against child.exec here ...
        result = child.exec("cd /work && npm test -- auth", timeout_seconds=900)
        patch = child.exec("cd /work && git diff", timeout_seconds=60).stdout
        return {"strategy": strategy, "passed": result.exit_code == 0, "patch": patch}
    finally:
        child.kill()


with ThreadPoolExecutor(max_workers=3) as pool:
    results = list(pool.map(
        lambda s: attempt(*s),
        zip(attempts, ["minimal-diff", "rewrite-helper", "add-retry"]),
    ))

winners = [r for r in results if r["passed"]]
base.kill()

You can approximate this with containers and a well-cached image, and if that's where you are, do that — it's less machinery. What you can't approximate is forking a process tree mid-flight: a database that has already started, a dev server that has already compiled, a language server that has already indexed. Those live in memory, and memory is the thing a container snapshot doesn't give you.

What each one actually needs from the machine it runs on

The part the title promised. This is deliberately qualitative — exact numbers depend on your repo more than on the tool — but the shape of the requirement differs enough between these that it should inform your choice.

  • Aider — a shell and git, and that's genuinely it. The heaviest thing in the loop is your own test suite. Runs comfortably on the laptop you already have. Wants your real working tree; does not want to be sandboxed away from it.
  • OpenHands — the most demanding entry. A container runtime, real memory per concurrent task (a browser tool means a headless Chromium), disk for repos and dependency trees, and a warm toolchain if you don't want every task to start with a cold install. Scales by running more environments, so plan capacity per concurrent agent rather than per install.
  • SWE-agent — container per task instance and batch capacity. The number that decides your experience is per-instance start-up cost multiplied by however many instances you're running, which is usually a lot. Reproducibility of the task environment matters more here than for anything else on the list.
  • Goose — your machine, on purpose, plus whatever every enabled MCP extension needs. The resource question is minor; the privilege question is the whole thing. Audit the extension list the way you'd audit an IAM policy.
  • Cline / Roo Code — your editor's workspace and your integrated terminal. Modest resource needs beyond what the project already demands. Best isolation upgrade is a dev container, which costs almost no ergonomics.
  • Continue — same as above, unless you're running local models to keep code in-house, in which case the machine requirement moves entirely to the inference server and becomes a GPU sizing exercise.
  • Claude Code / Codex CLI / Gemini CLI — a terminal and your repo. All three have some documented confinement story; which one and how strong varies per tool and per release, and that is the thing to read before you run any of them unattended.

The through-line: the tools that want to be on your machine (Aider, Goose, the IDE assistants) are cheap to run and expensive to isolate, because isolation removes the context that makes them good. The tools that want to work autonomously (OpenHands, SWE-agent) are expensive to run and cheap to isolate, because they were designed to work in a box from the start. That correlation is not an accident and it's a useful heuristic when you're evaluating something new.

Where a microVM earns its keep

Concretely, five situations. If you're not in one of them, don't buy compute you don't need.

  1. Unattended runs. Anything triggered by a queue, a webhook, a cron, or a backlog rather than by a human pressing enter. The whole reason approval prompts work is that a human is reading them; remove the human and the prompt is a no-op. Unattended is the single clearest line in this post.
  2. Code you didn't write. An agent triaging an issue on an open-source repo, reviewing a fork's pull request, or working on a customer's codebase is reading and executing input from outside your trust boundary. Prompt injection is unsolved, so assume the text can steer the agent and put the agent somewhere that doesn't matter.
  3. Many agents at once. Past about three concurrent agents, the per-agent environment stops being a detail and becomes your architecture. This is where fork-from-warm-state changes the economics rather than merely the safety posture.
  4. Agents as a product feature. If your users' prompts cause code to execute on your infrastructure, you are running a multi-tenant code execution service whether or not you planned to, and a shared kernel between tenants is a decision you should have to defend in writing. KVM-level isolation with a per-tenant guest kernel is the answer here, and it's not close.
  5. Reproducible evaluation. Comparing two agent configurations, or two models, requires that they faced identical environments. Baking the environment into a snapshot and forking it per attempt gives you that by construction, rather than by hoping your setup script is deterministic.

What PandaStack specifically brings to those: Firecracker microVMs with a per-sandbox guest kernel rather than a shared one; snapshot-restore on every create at about 179ms p50, so the strong boundary doesn't cost you queue time; copy-on-write fork of a running sandbox in 400 to 750 milliseconds same-host; scale-to-zero, so an idle agent environment costs nothing rather than costing a reserved instance; managed Postgres with branching and point-in-time restore for when the agent's task needs a real database it can wreck; and Python and TypeScript SDKs, because the integration point is a function call, not a Kubernetes manifest.

Where it's overkill, honestly

Most single-developer workflows. If you are one person, running Aider or Cline on a repository you wrote, reading every diff before you accept it, on a laptop whose credentials you'd notice going missing — use the local mode. Adding a remote machine to that loop costs you the thing that makes the loop good, which is that the edits appear in the files you're already looking at. There is no version of this where I tell you to pay me for that.

Anything where a dev container is sufficient. If your worry is leftover state between runs and your agents are driven by employees on private code, container-per-agent solves it, you probably already have Docker, and the marginal security gain from a hypervisor boundary is small relative to the operational cost of a new platform. I'd rather you run a good container setup than a badly-operated VM fleet.

Goose with local extensions. An agent whose value comes from touching your local systems does not become better when you remove its access to your local systems. Curate the extension list instead.

Latency-critical inner loops. A tight edit-run-see-result cycle where the file must be on your disk for your editor, your language server and your hot-reload to see it. Remote execution means the source of truth moved, and syncing it back is a problem you didn't have five minutes ago.

Environments without KVM. Firecracker needs `/dev/kvm`. That rules out a good deal of managed Kubernetes and any provider that doesn't expose nested virtualisation. If you're going to self-host our stack, check that first, before anything else — it's the constraint that ends the conversation.

A middle path a lot of teams land on and I think is correct: local mode for the supervised inner loop, remote microVMs for the unattended outer loop. You pair with Aider or Cline on your laptop during the day; overnight, the same repo gets worked by OpenHands in throwaway VMs against the issue backlog, with no credentials in the environment and egress denied by default. Two rungs, chosen deliberately, for two genuinely different jobs.

Side by side

  • Aider — Shape: terminal pair programmer. Default rung: 0, your working tree, by design. Autonomy: low, human present. Best for: a developer who wants fast, reviewable, commit-per-change edits on code they understand. Watch for: nothing much, as long as you're actually watching.
  • OpenHands — Shape: autonomous issue-solver with a UI and a headless mode. Default rung: 1, container runtime, swappable and remote-capable. Autonomy: high. Best for: working a backlog, or building agent workflows on a project that treats the execution environment as a component. Watch for: resource footprint per concurrent task, and reading the current runtime docs before multi-tenant use.
  • SWE-agent — Shape: research-lineage autonomous issue-solver with a designed agent-computer interface. Default rung: 1, container per instance, with a separate execution-backend layer. Autonomy: high, batch-oriented. Best for: evaluation runs, research, and anyone who wants to think carefully about the interface between model and computer. Watch for: benchmark numbers quoted without a variant and a date.
  • Goose — Shape: general on-machine agent, strong at coding, MCP extension model. Default rung: 0, your machine, deliberately. Autonomy: medium to high depending on extensions. Best for: workflows that span coding and everything around it. Watch for: blast radius equal to the union of enabled extensions.
  • Cline / Roo Code — Shape: agentic VS Code extensions with plan/act separation. Default rung: 0, your integrated terminal, with approval prompts. Autonomy: medium, and quietly higher once auto-approve is widened. Best for: multi-file edits with a human reviewing at the plan level. Watch for: the auto-approve list becoming your real security policy. Upgrade path: dev container.
  • Continue — Shape: configurable IDE assistant for VS Code and JetBrains. Default rung: 0, through the IDE. Autonomy: low to medium. Best for: teams that need to control which model sees their code, including fully local inference. Watch for: your bottleneck being the model server rather than the agent.
  • Claude Code / Codex CLI / Gemini CLI — Shape: vendor terminal agents; Codex CLI and Gemini CLI are open-source clients for closed models, Claude Code is not open source. Default rung: 0 with real confinement options — OS-level sandboxing on Codex CLI, container or Seatbelt on Gemini CLI, permission prompts and dev-container patterns on Claude Code. Autonomy: medium to high. Best for: the terminal workflow, with the best in-the-box safe modes in the category. Watch for: sandboxing specifics changing between releases.

How to choose

  1. Answer the supervision question first, because it dominates everything else. Will a human read each proposed change before it happens? If yes, pick on ergonomics and stop worrying about rungs. If no, the execution boundary is your primary criterion and most of the ergonomic differences stop mattering.
  2. Then pick the shape, not the brand. Supervised inner loop: a terminal pair programmer or an IDE assistant. Unattended backlog work: an autonomous issue-solver. Evaluation and research: SWE-agent's lineage. Cross-tool workflows: Goose. Getting these categories mixed up is the most common way teams conclude that agents don't work.
  3. Check the sandboxing documentation before the capability demos. A project with a written execution-boundary story has thought about the problem; a project without one has answered it by omission. This is a better long-run signal than which one wrote a nicer function in a screen recording.
  4. Make the cheap upgrade this week regardless. Put your existing agent in a dev container or turn on its built-in confinement mode. It costs an afternoon, it removes the leftover-state and dotfile-exposure classes entirely, and it does not require you to adopt a platform.
  5. Escalate to a VM boundary only for the specific jobs that need it: unattended runs, untrusted code, many agents in parallel, agents as a product feature, reproducible evals. Run those on microVMs and leave the supervised workflow local. Two rungs for two jobs is a better answer than one rung for both.
  6. Whatever you pick, fix credentials on the same day. No long-lived cloud keys in the agent's environment; short-lived, narrowly-scoped tokens minted per run; egress default-denied and enforced outside the execution environment. This is worth more than any choice on this page, and it's independent of all of them.
Don't pick from this post, or from any roundup, including one written by a vendor who appears in it. Take your top two, point them at a real ticket from your actual backlog — not a toy — and measure three things: how many of the agent's proposed changes you'd merge without edits, how long the loop takes end to end including environment setup, and how many times you had to intervene to stop it doing something dumb. That third number is the one that tells you which rung you need.

Where this leaves you

The open-source coding agent field in 2026 is healthier than the discourse suggests. Aider is a genuinely good tool with a design idea — commit per change — that more projects should steal. OpenHands is the most complete open implementation of the autonomous shape and has the best-architected execution layer in the category. SWE-agent's agent-computer interface framing influenced everything after it. Goose is doing something structurally different and interesting. Cline, Roo and Continue made agentic editing feel normal. And the vendor CLIs, whatever you think of the licensing, dragged local sandboxing from an afterthought into a shipped feature.

What none of them can decide for you is where the commands land. That's your call, it's made by default if you don't make it deliberately, and it is the decision that survives every model upgrade between now and whenever this post gets stale. Rung 0 is fine for a supervised loop on your own code and I'd tell you to stay there. Rung 1 — a container, a dev container, a built-in confinement mode — is an afternoon's work and removes most of what actually goes wrong; nearly everyone reading this should be on it and isn't. Rung 3, a real machine with its own kernel that you throw away, is for the jobs where the agent is unattended, the code is untrusted, or there are a lot of agents at once.

If that last description is your situation, snapshot-restore is what makes it affordable now — 179ms to a fresh guest, sub-second copy-on-write forks from a warmed environment, nothing running when nothing's happening. And if it isn't your situation, the best infrastructure decision you can make about your coding agent is to not make one.

Frequently asked questions

What is the best open-source coding agent in 2026?

There is no single winner, because the leading tools are different products that happen to share a word. For a supervised terminal workflow where you review every change, Aider is the cleanest design — it edits your real working tree and makes a git commit per change, so review and undo are just git. For autonomous work on a backlog of issues, OpenHands is the most complete open implementation and treats its execution environment as a swappable component. For research and batch evaluation, SWE-agent's lineage and its agent-computer-interface framing are the reference point. For agentic editing inside VS Code, Cline and its fork Roo Code, with Continue as the most configurable option if you need to control which model sees your code. Goose is a general on-machine agent that is strong at coding and spans tools beyond the editor. Pick by workflow shape first, and treat coding quality as a model property that will change before your choice of tool does.

Do I need to sandbox my AI coding agent?

It depends entirely on whether a human reads each proposed action before it happens. A developer supervising a pair programmer on their own private repository, approving each command, is not in serious danger, and adding a remote machine to that loop mostly costs ergonomics. You need a real boundary when the agent runs unattended — triggered by a queue, a webhook, a cron, or an issue backlog — because approval prompts only work when someone is reading them; when the agent processes code or text you did not write, because prompt injection from a README, an issue body or a fetched web page is unsolved; and when your users' prompts cause code to run on your infrastructure, which makes you a multi-tenant code execution service whether you planned to be one or not. The cheap intermediate step, which most teams should take and haven't, is running the agent in a dev container or turning on its built-in confinement mode.

What is the biggest security risk when running a coding agent locally?

Not the destructive command everyone worries about. The most common real-world damage comes from dependency install scripts: the agent decides it needs a package, the install runs, and an npm postinstall or a Python setup script executes arbitrary code as your user before the agent has produced any output. Approval discipline does not help, because you approved the install and the install was reasonable. Close behind it is credential exposure, because reading a file is the most ordinary thing an agent does and there is no syscall-level difference between reading your source and reading your cloud credentials. Third is prompt injection from repository or issue content steering the agent into a plausible-looking command that gets approved. All three mitigations are structural rather than behavioural: don't put long-lived credentials in the environment, deny network egress by default and enforce it outside the execution environment, and run the agent somewhere you were going to delete.

How do I run several coding agents in parallel on the same repository?

Not in one working directory — concurrent agents will fight over the git index and stomp each other's edits. Git worktrees solve the source-control collision by giving each agent its own checkout over a shared object store, but they do not solve anything outside git: dependency trees, virtual environments, port numbers, local databases and build caches are still shared, and the machine itself becomes the contended resource. A container per agent fixes that properly and is the right answer for most teams, at the cost of image and dependency setup per container plus the memory of N concurrent environments. The step beyond it is forking a prepared environment: on PandaStack you set up one sandbox with the repo cloned, dependencies installed and services running, then copy-on-write fork it per agent in 400 to 750 milliseconds same-host, so every attempt begins from provably identical warm state including running processes — which containers cannot reproduce, because the state you want to copy lives in memory.

Can I run OpenHands or SWE-agent in a microVM instead of a Docker container?

Yes, and both projects make it more straightforward than the others because they were designed around a swappable execution layer rather than assuming the local host. OpenHands routes agent actions through a runtime abstraction whose default is a container and which supports remote runtimes; SWE-agent's team maintains a separate execution-backend layer for running agent commands against local, container and cloud targets. In either case the integration point is the same single function: the thing that currently calls subprocess.run or the Docker API instead makes an RPC to a remote sandbox and returns the same stdout, stderr and exit code. The agent loop above it needs no changes. The reason to bother is a per-task guest kernel rather than a shared one, and an environment that holds none of your credentials — and the reason it is now practical is that snapshot-restore puts a fresh VM at roughly container start-up cost rather than a multi-second boot.

Is Claude Code open source?

No. Claude Code is Anthropic's proprietary terminal agent, distributed as a package you install rather than source you can fork. Among the vendor CLI agents, OpenAI's Codex CLI and Google's Gemini CLI are open-source clients for proprietary models — you can read and modify the agent, but the intelligence is a rented API. They are worth knowing about in an open-source roundup for one specific reason: collectively, the vendor CLIs have done more shipped work on local agent confinement than the rest of the ecosystem, including OS-level sandboxing with Seatbelt on macOS and Landlock plus seccomp on Linux, container-based tool execution, and permission models with allow and deny lists. Sandboxing specifics change between releases, so check each project's current documentation rather than any blog post, including this one.

Keep reading

Run code in a microVM in one API call.

49ms p50 cold start. Fork, snapshot, and scale to zero.

Start free
Written by Ajay Kumar, Founder, PandaStack.