The editor for when
you pause to think.
Hm is a native code editor with an AI coding agent built in. The agent writes fast; the decision about what lands in your codebase stays with you.

Talks directly to the models you already pay for
Built around the pause before you merge.
Hm is the sound you make when you read a diff, a stack trace or a suggestion, and decide whether it is right. Everything in Hm is built to make that moment count.
A real editor, right there
Every change lands in a full editor with the language server, diagnostics and git diff beside it, not a chat bubble.
Modes that slow down
rubber-duck plans and pushes back before touching code. lazy changes only what is necessary.
Asks before it acts
Shell commands and deletes need your OK by default, and guard.yaml rules always win.
Nothing is final
Undo the last turn and its file changes, or go back to any message and try again. Every branch is kept.
Fast where it can be,
quiet when you need to think.
Everything you reach for,
nothing you wait on.
Written in Go and drawn on the GPU with WebGPU, Hm starts quickly and stays light, with the tools you expect from a modern editor.
Tree-sitter highlighting for 20+ languages
Multiple cursors and column selection, regex find and replace, folding, soft wrap, indent guides, auto-closing pairs, Markdown preview and an optional Vim keymap.
Native, GPU-rendered
No Electron, no browser engine. A Go binary drawing its own UI with Yoga.
Language servers
Diagnostics, hover, completion, definitions, references, rename and formatting. Missing servers install in one click.
Search with ripgrep
Project-wide regex search and replace, with results on the left and an editable preview on the right.
Git, built in
Stage, commit, branch, merge with conflict tracking, fetch, pull and push. Tokens stay in your keychain.
Quick open & command palette
⌘ P for files, ⌘ ⇧ P for every command, go to symbol and go to tab.

Settings that are just YAML
A settings page on top of config.yaml, user and project level, applied live on save with errors shown at their line.

Integrated terminal
Multiple sessions, opened from the footer.
Inline completions
Ghost text at the caret from a small, fast model you pick. Tab accepts.
Splits, tabs, sessions
Split editor groups, back and forward, and your session restored on launch.
An agent that works with you,
not around you.
Bring your own key, keep your code on your machine, and stay in control of every step.
Any model, switched mid-session.
Anthropic, Gemini (API key or Vertex AI), OpenAI, Azure OpenAI and any OpenAI-compatible endpoint. Presets for OpenRouter, Groq, Mistral, xAI, DeepSeek, Ollama, LM Studio and more only ask for a key.
- Ctrl L searches every provider's models; the history goes along.
/think off…maxsets how hard the model thinks, per session.- A
models.jsonregistry drives the context meter, compaction and the cost of every reply. - Keys live in the OS keychain or come from environment variables.
agent:
default_provider: anthropic
default_mode: rubber-duck
providers:
anthropic: { type: anthropic, api_key: "keychain:anthropic" }
openrouter: { type: openrouter, api_key: "${OPENROUTER_API_KEY}" }
local: { type: ollama, model: qwen3, context_window: 32768 }
favorite_models: [anthropic/claude-opus-5-5, local/qwen3]
compaction: { enabled: true, threshold: 0.85 }
subagents: { max_depth: 1, max_concurrent: 4 }Sessions are trees. Nothing is lost.
Edit and resend any message to start a branch, or branch from the end of any turn. The old branch stays. Undo puts back the agent's last turn and the files it changed.
/treeto search and jump between branches,/forkto split a session off.- Saved after every step; an interrupted task reopens with a Resume button.
/exportto one offline HTML page, secrets redacted;/shareas a secret gist.
- ●userAdd retries to the HTTP client
- │assistantPlan: wrap Do() with backoff…
- ├─userUse the stdlib only, no deps
- │ │toolsedit client.go +42 −6
- │ └assistantDone. Retries 5× with jitter v1
- └─userRespect Retry-After headers too
- │toolsedit client.go +18 −3
- └assistantWaits as long as the API asks…
Guardrails you write, not hope for.
Approval per tool and per mode, plus a guard.yaml of deny, read-only and ask rules checked before anything runs. A cloned project's rules can only tighten yours, never loosen them.
- Modes: lazy, rubber-duck, auto, fullstack, or your own.
- Type while it works: Enter steers, Alt Enter queues a follow-up.
- Sub-agents run in parallel, in the foreground or background, read-only unless allowed.
paths:
deny: [".env", "*.pem", "~/.ssh", "~/.aws"]
read_only: ["migrations/**"]
commands:
deny: ["rm -rf /*", "sudo *", "re:curl .*\\| *(ba)?sh"]
ask: ["git push*", "git reset --hard*"]
network:
allow_hosts: ["pkg.go.dev", "github.com"]Reads your AGENTS.md
And CLAUDE.md, from every folder between home and the workspace. SYSTEM.md replaces or extends the base prompt.
Prompt templates
Every .md in .hm/prompts or .claude/commands becomes a /command, with arguments and file includes.
MCP, skills & your tools
Add MCP servers, skills, or wrap any CLI as a tool. Arguments never go through a shell.
Images in, too
Paste a screenshot, drop a file, or mention @shot.png. Large pictures are scaled down first.
Long sessions keep going
Near the window's limit, older messages are summarised. A context meter shows how full it is.
Survives flaky APIs
Rate limits and dropped connections are retried with backoff, and the chat tells you so.
The same agent, without the window.
Run it in scripts and CI, drive it from another program, or embed it in your own Go code. Same config, same guard.yaml, same sessions.
# Review a diff in CI, no window needed
git diff origin/main... | hm agent -p "review this"
# Resume the newest session and let it edit files
hm agent --continue --approve edits -p "now fix the tests"
# Every event as JSON lines, for scripts and jq
hm agent -p --output json "list the packages" \
| jq -c 'select(.type == "tool_call")'{"id":"1","type":"prompt","text":"fix the failing test"}
{"id":"2","type":"steer","text":"only touch the parser"}
{"id":"3","type":"approve","call_id":"toolu_01","allow":true}
{"id":"4","type":"set_model","provider":"anthropic","model":"claude-opus-5-5"}
{"id":"5","type":"export","format":"html"}r, err := agent.New(agent.Options{Root: ".", Approver: myApprover{}})
if err != nil {
return err
}
defer r.Close()
go func() {
for e := range r.Events() {
log.Println(e.Kind)
}
}()
err = r.Prompt(ctx, "what is wrong here?", agent.Image{Data: png})
fmt.Println(r.Answer())Hands stay on the keys.
Every binding can be changed in Settings or YAML, with two-chord sequences and VS Code-style when conditions.
Take a moment. Hm.
Build it from source today. Signed releases for macOS, Linux and Windows are on the way.
git clone https://github.com/usehm/hm.git && cd hm && make install