A minimal natively compiled single-binary coding agent with a ~1 MB footprint. For professionals on limited hardware who want results, not bloat.
Startup time ~1ms means Puny is always ready when you are — no spinner, no waiting. The ~1 MB binary and minimal memory footprint mean it runs comfortably on a Raspberry Pi, a remote server over SSH, or a decade-old laptop. Every millisecond and megabyte is deliberate: there is no hidden runtime, no garbage collector, no Node.js dependency, no Electron shell.
Puny is designed around the way I work. It is highly opinionated.
Other coding agents include MCP, subagents, plugins, extensions, animations, and dozens of other features I never asked for. Puny does not. The feature set is limited to what I need to get results: read files, write files, run commands, search code, load skills, fetch web pages. If you want parallel work, run another instance.
Each feature earns its place. Nothing ships because it looks good on a comparison table. This is not a platform — it is a tool.
Puny does not show the model's reasoning or thinking output by default. I do not care about the model's internal monologue. I see it as a wall of text, a huge TL;DR you have to scroll past to get to the actual answer. If you want it, pass --show-thinking. If you think you want it later, pass --chat-log which saves the entire conversation, noise included, to puny_chat.log.
The four supported providers are the ones I use personally:
The four providers I use personally: LM Studio, OpenCode Zen, OpenCode Go, and GitHub Copilot
Read, write, and list files, run shell commands, search code, load skills, and fetch web pages
Load reusable prompt-engineering skills via slash command, keyword triggers, or automatic model invocation
Multi-turn conversations with session management and PRD export
Interactive model selection on startup
One-command installation that automatically detects your platform, downloads the latest release, and installs it to your chosen directory.
curl -fsSL https://christianhelle.com/puny/install | bash
irm https://christianhelle.com/puny/install.ps1 | iex
INSTALL_DIR=$HOME/.local/bin curl -fsSL https://christianhelle.com/puny/install | bash
$install = irm https://christianhelle.com/puny/install.ps1
& ([scriptblock]::Create($install)) -InstallDir "$env:USERPROFILE\bin"
Each session is identified by a UUID. A new session is created on every start, /new, or /reset. Use /sessions to list saved sessions and /prune to clean up old ones. In /plan mode, once you confirm the plan is ready, the model saves the final PRD as both plan.md and plan.html to the session folder via the save_prd tool.
Puny supports reusable prompt-engineering skills stored as markdown files. Skills are scanned from ~/.agents/skills/ (global) and <repo>/.agents/skills/ (per-project).
Each skill directory contains a SKILL.md file with YAML frontmatter:
name | Canonical identifier |
description | Short summary shown in /skills |
triggers | Comma-separated phrases that auto-load the skill |
disable-model-invocation | Set to true to restrict to manual loading |
Skills load three ways: /<name> slash command, mentioning a trigger phrase in your message, or the model calling load_skill automatically when it finds a relevant skill.
Start LM Studio, load a model with tool-calling support, then:
puny
puny --provider opencode --api-key YOUR_API_KEY
puny --provider opencode-go --api-key YOUR_API_KEY
puny --provider copilot
Load the first prompt from a local file or an http:///https:// URL via --prompt-file at startup or /file in a session:
puny --prompt-file spec.md --oneshot
Puny is published as a container image to both Docker Hub and GitHub Container Registry.
docker pull christianhelle/puny:latest
docker run -it --mount "type=bind,source=${PWD},target=/app" christianhelle/puny
For detailed Docker documentation, including LM Studio integration, one-shot prompts, and building locally, see Docker Documentation.