Runtime

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

Sandboxes 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 aider in /workspace/.local/bin, first on the sandbox's PATH. 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 pytest has 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.com to the list if you want its context-window figures current.
  • --message sends one instruction, applies the edits and exits, which Aider's scripting guide describes as its command-line automation mode. --message-file reads a longer instruction from a file.
  • --test-cmd with --auto-test runs 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 --version

For 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_KEY and --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.