Disposable dev boxes for AI-assisted coding from any device.
Imir spins up Hetzner Cloud VMs pre-configured with your dotfiles, Claude Code, and tmux. Connect from your laptop or phone, pick up where you left off. Destroy the box when you're done — nothing precious lives there.
Named after the planet in Adrian Tchaikovsky's Children of Memory — a world settled by colonists who had to make do with what they brought and adapt to what they found. IYKYK.
This is an intentionally opinionated setup. It solves specific problems I kept running into:
- Code on the go — SSH + tmux from a phone (via Termius) with full agent forwarding. Closer to the metal and more customizable than the Claude mobile app.
- Right-size the machine — local laptop chokes on ML training or large codebases. Spin up a beefier box for the job, destroy it when done.
- Consistent environment — chezmoi dotfiles, same tools, same shell, every time. New box in ~2 minutes (~30s with a baked snapshot).
Take it or leave it. Or fork it and rebuild it with your own AI.
- Hetzner Cloud account with an API token
- hcloud CLI (
brew install hcloud) - SSH key at
~/.ssh/id_rsa(or configure a different path) - chezmoi dotfiles repo on GitHub (optional, but this is how your dev environment gets configured)
curl -fsSL https://raw.githubusercontent.com/fuJiin/imir/main/install.sh | bashInstalls imir to ~/.local/bin (or /usr/local/bin), fish completions, and creates a config at ~/.config/imir/config.env.
# 1. Edit config — set HCLOUD_TOKEN and CHEZMOI_REPO at minimum
${EDITOR:-vi} ~/.config/imir/config.env
# 2. Create a dev box (~2 min, or ~30s with 'imir bake')
imir create myproject
# 3. Connect (drops into tmux)
imir connect myproject| Command | Description |
|---|---|
imir init |
Create config file at ~/.config/imir/config.env. |
imir create <name> [type] |
Create and bootstrap a new dev box. |
imir bake [--force] |
Bake a snapshot for faster box creation. |
imir connect <name> [session] |
SSH + tmux session (default: default). |
imir ssh <name> [cmd...] |
Plain SSH, no tmux. Runs a command if given. |
imir ip <name> |
Print a box's IP address. |
imir sessions <name> |
List tmux sessions on a box. |
imir kill-session <name> <session> |
Kill a tmux session on a box. |
imir list |
Show all running dev boxes. |
imir rename <old> <new> |
Rename a dev box. |
imir destroy <name> |
Destroy a dev box and clean up known_hosts. |
imir upgrade |
Upgrade imir to the latest version. |
imir uninstall |
Remove imir and all its files. |
~/.config/imir/config.env (created by imir init):
| Variable | Default | Description |
|---|---|---|
HCLOUD_TOKEN |
(required) | Hetzner Cloud API token |
CHEZMOI_REPO |
(optional) | GitHub shorthand for your chezmoi dotfiles (e.g. youruser/dotfiles) |
SSH_KEY_PATH |
~/.ssh/id_rsa |
Path to your SSH private key |
DEFAULT_SERVER_TYPE |
cpx21 |
Hetzner server type (3 vCPU, 4GB RAM) |
DEFAULT_LOCATION |
hil |
Hetzner datacenter (Hillsboro, OR) |
DEFAULT_IMAGE |
ubuntu-24.04 |
Base OS image |
BAKE_HOOK |
(optional) | Local script to run as root during imir bake (after system packages) |
BAKE_USER_HOOK |
(optional) | Local script to run as dev during imir bake for user-local tools |
| Type | vCPU | RAM | Disk | ~Cost/hr |
|---|---|---|---|---|
cpx21 |
3 | 4 GB | 80 GB | ~$0.01 |
cpx31 |
4 | 8 GB | 160 GB | ~$0.02 |
cpx41 |
8 | 16 GB | 240 GB | ~$0.05 |
The create command provisions a dev user with sudo and installs:
fish, emacs-nox + Doom Emacs, tmux, Claude Code, GitHub CLI, git, ripgrep, fd, jq, curl, build-essential — then applies your dotfiles via chezmoi. Your CHEZMOI_REPO should be a GitHub repo that chezmoi init --apply can consume (see fuJiin/dotfiles for an example).
Today, Claude Code is installed directly by imir during bake and per-box bootstrap. For personal tools like Codex, prefer keeping the installer in your dotfiles repo and using BAKE_USER_HOOK only to preinstall it into the baked image.
Bootstrap is split into two phases:
- Bake (system packages) — apt repos, package installs, lazygit, dev user creation. Slow (~90s) but identical across boxes.
- Per-box (user setup) — SSH keys, chezmoi dotfiles, Claude Code. Fast (~30s) and unique to each box.
Run imir bake to snapshot the first phase into a Hetzner image. Subsequent imir create calls use that snapshot and skip straight to per-box setup.
Set BAKE_HOOK to a local script path to run system-level setup during bake (e.g. apt packages, language runtimes). Set BAKE_USER_HOOK to run user-level setup as dev (e.g. a Codex installer that writes into ~/.local or ~/.config). Hook contents are included in staleness detection, so changing either hook triggers a rebuild warning.
The snapshot is tagged with a hash of the bake script and any configured hooks. If you update any of them (e.g. via imir upgrade), create will warn that the snapshot is stale. Run imir bake again to rebuild it.
The clean split is:
chezmoiowns your personal toolchain and shell/config state.imirowns box lifecycle and snapshot speed.
For Codex, keep the real installer in your dotfiles repo, make it idempotent, and optionally point BAKE_USER_HOOK at a local wrapper that invokes that same installer during imir bake. That gives you one source of truth for laptops and dev boxes, while still baking the tool into snapshots for faster startup.
- Usage guides — worktrees, multiple boxes, phone setup, git/GitHub auth
- Decisions — why Hetzner, why tmux, architectural trade-offs