denv — dev environments over plain ssh
ssh -t [-L port:localhost:port] you@denv.sh denv github:owner/repo[#branch|#pr/N] [command ...]
~ $ ssh -t marco@denv.sh denv github:marco/webapp denv: authenticated as marco (github.com/marco.keys) denv: environment marco/webapp ready — repo cloned in 2.8s denv: uv.lock detected — uv sync running in the background marco@webapp:/workspace$
No signup, no CLI to install, no YAML. Your SSH username is your GitHub username, and your keys are checked against github.com/you.keys — the key you already use to push is the whole identity. One command:
Any -L port rides the same connection — the destination host is always your environment, so -L 8000:localhost:8000 makes the dev server you start in the repo reachable on your machine.
Environments are reused while you're connected and reaped after 30 minutes of idle time. Reconnecting with the same command drops you exactly where you left off.
After the clone, the repo is inspected and the environment prepared while your shell is already attached:
New shells pick up the result (or run denv-reload). The image ships nix, mise, uv, neovim, tmux, and zellij.
ssh you@denv.sh # list your environments
ssh -t you@denv.sh denv github:owner/repo # create or attach
ssh -t you@denv.sh denv github:owner/repo#pr/123 # review env for a PR
ssh -t you@denv.sh denv github:owner/repo make test # run a command
ssh you@denv.sh denv rm github:owner/repo # delete
Sessions that survive disconnects — run your multiplexer as the command:
ssh -t you@denv.sh denv github:owner/repo tmux new -A -s main
A single Go gateway speaks SSH on the front and Kubernetes on the back. Interactive sessions ride a persistent multiplexed connection to a small agent inside the environment, warmed while you authenticate — the Kubernetes apiserver is not in the keystroke path. The clone runs in an init container, so a ready environment always means a ready repo.
Public repos only for now; private repos via a GitHub App are planned. Workspaces are ephemeral — anything you want to keep, push.