How to run Aider in a cloud sandbox
Install aider-chat with uv in a Linux microVM, keep the model key as a secret, run aider --message --yes-always and take the diff.
Runtime runs Aider on Python 3.12 out of the box, with the model key held
outside the machine. Aider's installer pins Python 3.12, which is the
sandbox image's own Python, and uv is already installed, so Aider's recommended
uv tool install line works unchanged. Each sandbox is a Firecracker microVM
with its own Linux kernel and Ubuntu 24.04. The model key is a Runtime secret:
the environment variable Aider reads holds a placeholder, and the host's proxy
adds the real key only on requests to the model API. At 2 vCPUs and 4 GiB a
sandbox costs $0.03125 an hour while Aider waits on the model. aider-chat
0.86.2 was the current PyPI release on 25 September 2026.
How Aider differs from the other agents
Aider edits the files you name and the files its repository map points it to. It does not run a free-form shell loop; it runs the commands you configure, such as a test command, and feeds failures back to the model. That makes it a good fit for batch jobs: the same instruction over many repos, one sandbox each.
| Aider habit | In a sandbox |
|---|---|
| Commits every change by default | --no-auto-commits leaves the change for your own diff |
| Stops to confirm edits and new files | --yes-always answers yes |
Adds .aider* to .gitignore |
--no-gitignore leaves the repo's file alone |
Runs --test-cmd after edits with --auto-test |
Tests run inside the microVM, not on your runner |
| Checks PyPI for updates at start | --no-check-update skips it |
Aider is not an MCP client, so there is one direction here: Aider running inside a Runtime sandbox.
Store the key
Aider takes Anthropic keys from ANTHROPIC_API_KEY and OpenAI keys from
OPENAI_API_KEY. Store the one you use, bound to its API host:
Terminalprintf %s "$ANTHROPIC_API_KEY" | npx withruntime secrets set ANTHROPIC_API_KEY --host api.anthropic.comSandboxes of your account see the variable with a placeholder such as
rtsec_3f9c…. Requests to api.anthropic.com go out with the real key; a
request anywhere else carries the worthless placeholder
(secrets sandboxes never see).
Script a change
TypeScriptimport { writeFile } from "node:fs/promises";import { Sandbox } from "withruntime";const repo = "https://github.com/your-org/your-repo";const message = "Add type hints to every public function in src/billing.py and fix any test that breaks.";await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 3600 });const install = { check: true, timeoutMs: 600_000 } as const;await sbx.exec("uv tool install --force --python python3.12 --with pip aider-chat@latest", install);await sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], install);await sbx.exec("pip install -e . pytest", { ...install, cwd: "/workspace/app" });await sbx.network.set({ internet: true, allow: ["api.anthropic.com"] });const run = await sbx.exec( [ "aider", "--model", "sonnet", "--message", message, "--yes-always", "--no-auto-commits", "--no-gitignore", "--no-check-update", "--analytics-disable", "--no-pretty", "--test-cmd", "pytest -q", "--auto-test", "src/billing.py", ], { cwd: "/workspace/app", timeoutMs: 1_800_000, onStderr: (text) => process.stderr.write(text) },);console.log(run.exitCode, run.stdout.slice(-2000));await sbx.exec("git add -A && git diff --cached -- . ':!.aider*' > /workspace/aider.patch", { cwd: "/workspace/app", check: true,});await writeFile("aider.patch", await sbx.files.readText("/workspace/aider.patch"));Pythonimport sysfrom withruntime import Sandboxrepo = "https://github.com/your-org/your-repo"message = "Add type hints to every public function in src/billing.py and fix any test that breaks."with Sandbox.create(disk_mib=8192, timeout_seconds=3600) as sbx: sbx.exec("uv tool install --force --python python3.12 --with pip aider-chat@latest", check=True, timeout_ms=600_000) sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], check=True, timeout_ms=600_000) sbx.exec("pip install -e . pytest", cwd="/workspace/app", check=True, timeout_ms=600_000) sbx.network.set(internet=True, allow=["api.anthropic.com"]) run = sbx.exec( ["aider", "--model", "sonnet", "--message", message, "--yes-always", "--no-auto-commits", "--no-gitignore", "--no-check-update", "--analytics-disable", "--no-pretty", "--test-cmd", "pytest -q", "--auto-test", "src/billing.py"], cwd="/workspace/app", timeout_ms=1_800_000, on_stderr=sys.stderr.write, ) print(run.exit_code, run.stdout[-2000:]) sbx.exec("git add -A && git diff --cached -- . ':!.aider*'" " > /workspace/aider.patch", cwd="/workspace/app", check=True) with open("aider.patch", "w") as file: file.write(sbx.files.read_text("/workspace/aider.patch"))What happens, in order:
- uv installs Aider as a tool with its own environment and puts
aiderin/workspace/.local/bin, first on the sandbox'sPATH. uv comes with the image, and the Python 3.12 it asks for is the system one. - The project's own dependencies install next, while PyPI is still
reachable, so
pytesthas what it needs once the network narrows. - The network narrows to the model API. Aider also tries to fetch model
metadata from GitHub at start and carries on without it when that fails;
add
raw.githubusercontent.comto the list if you want its context-window figures current. --messagesends one instruction, applies the edits and exits, which Aider's scripting guide describes as its command-line automation mode.--message-filereads a longer instruction from a file.--test-cmdwith--auto-testruns the tests after each edit and gives failures back to the model to fix.- The file list at the end adds those files to the chat; Aider's repo map finds related code on its own.
- The diff leaves out Aider's own
.aider*history files and comes back as a file, clear of the 64 KiB output cap.
Flags for scripted runs
From Aider's options reference, 25 September 2026. Each flag has an
AIDER_ environment variable too, for example AIDER_YES_ALWAYS.
| Flag | What it does |
|---|---|
--message, -m |
One instruction, then exit |
--message-file <path> |
The instruction from a file |
--yes-always |
Yes to every confirmation |
--no-auto-commits |
Leave changes uncommitted (the default is to commit) |
--test-cmd, --auto-test |
Test after edits and fix failures |
--dry-run |
Show edits without writing files |
--no-stream, --no-pretty |
Plain output for logs |
--model <name> |
The main model; aider --list-models anthropic/ lists them |
Aider's Python API (Coder.create) runs inside the sandbox too, but its
authors say it may change without notice; the command line is the stable
surface. To run the same message over many repos,
fork one prepared sandbox into several so each copy
starts with Aider already installed.
What it costs
Runtime bills measured CPU at $0.025 per vCPU-hour, with a floor of a twentieth of a vCPU, and reserved memory at $0.0075 per GiB-hour. A 2 vCPU, 4 GiB sandbox is $0.03125 an hour while Aider waits on the model and $0.08 an hour while tests keep both cores busy (pricing). The model provider bills tokens on your key. New accounts get 50 sandbox hours free, no card:
Terminalnpx withruntime sandbox run --trial -- python3 --versionFor agents that run their own shell loop, see Claude Code and OpenHands. Batch jobs over many repos are covered in agent evals and SWE-bench.
Sources
Checked 25 September 2026.
- Installation:
aider-install,uv tool install --force --python python3.12 --with pip aider-chat@latest - Scripting aider:
--message,--yes-always, the Python API and its stability note - Options reference:
--auto-commits,--test-cmd,--auto-test,--check-update,--analytics-disable, environment variables - Anthropic:
ANTHROPIC_API_KEYand--list-models anthropic/ - aider/models.py:
the model metadata fetched from
raw.githubusercontent.com - aider-chat on PyPI: version 0.86.2, Python 3.10 to 3.12
Facts on this page were checked on 25 September 2026.