# 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: ```bash no-run printf %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](/docs/security#secrets-sandboxes-never-see)). ## Script a change ```ts check import { 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")); ``` ```python check import sys from withruntime import Sandbox repo = "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 ` | 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 ` | 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](/docs/javascript#snapshots-and-forks) 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](/docs/pricing)). The model provider bills tokens on your key. New accounts get 50 sandbox hours free, no card: ```bash no-run npx withruntime sandbox run --trial -- python3 --version ``` For agents that run their own shell loop, see [Claude Code](/integrations/claude-code) and [OpenHands](/integrations/openhands). Batch jobs over many repos are covered in [agent evals and SWE-bench](/use-cases/agent-evals-and-swe-bench). ## Sources Checked 25 September 2026. - [Installation](https://aider.chat/docs/install.html): `aider-install`, `uv tool install --force --python python3.12 --with pip aider-chat@latest` - [Scripting aider](https://aider.chat/docs/scripting.html): `--message`, `--yes-always`, the Python API and its stability note - [Options reference](https://aider.chat/docs/config/options.html): `--auto-commits`, `--test-cmd`, `--auto-test`, `--check-update`, `--analytics-disable`, environment variables - [Anthropic](https://aider.chat/docs/llms/anthropic.html): `ANTHROPIC_API_KEY` and `--list-models anthropic/` - [aider/models.py](https://github.com/Aider-AI/aider/blob/main/aider/models.py): the model metadata fetched from `raw.githubusercontent.com` - [aider-chat on PyPI](https://pypi.org/project/aider-chat/): version 0.86.2, Python 3.10 to 3.12 Facts on this page were checked on 25 September 2026.