h2code

The most lightweight CLI agent for Voice Coding.

Develop with a lightness no other agent can match

$ curl -fsSL https://raw.githubusercontent.com/ByOrlov/h2code/master/install.sh | bash
$ curl -fsSL https://raw.githubusercontent.com/ByOrlov/h2code/master/install.sh | bash
PS> irm https://raw.githubusercontent.com/ByOrlov/h2code/master/install.ps1 | iex
MCP ACP 14 cloud providers Local LLMs 20+ tools Subagents & swarm Goals & permissions Hooks & skills Voice coding Code from your phone E2EE session sync
~3 MB*
Idle RAM / agent
~130×**
Lighter than opencode
1
Static binary, no JS runtime
GPL
Copyleft — forever free

The world has gone mad.

I opened the system monitor and was horrified. Two opencode instances were eating 1 GB of RAM. Five kimi-code chats were doing the same — because each dragged a full Node.js runtime along for the ride.

I remembered 2007. My mother bought me 512 MB of RAM so I could play S.T.A.L.K.E.R. — a full 3D game that ran on a machine with 1 GB. And now, in 2026, we can't run two chats on 1 GB.

I just couldn't live in a world like that — so I built h2code.

But building the CLI agent exposed the next problem: me. I kept sitting at the computer, feeding the agent tasks by hand — then waiting there while it worked. Everything I dictated, I could just as well have dictated from my phone, from the kitchen, from anywhere. So the agent learned to travel: same session, voice and remote clients, wherever you are.

From featherweight
to heavyweight.

h2code sits ~7× under the nearest Rust agent, ~40× under the lightest Node agent, and ~130× under opencode. The Node family ships a V8 runtime per process — forever.

h2codeCrystal
~3 MB
grok-buildRust
~20 MB
Codex CLIRust
~30 MB
GooseRust + TS
~50–100 MB
Claude CodeTS / Node
~120 MB
AiderPython
~150–250 MB
kimi-codeTS / Node
~250 MB+
opencodeTS / Bun
~400 MB

The Node family spans ~120 MB to ~400 MB because each ships a V8 runtime per process and grows with use. The Rust agents are native and lean; h2code keeps pace on RAM and wins on readability and license.

PSS

How we measured

Numbers are PSS (Proportional Set Size) — the fair-share metric from /proc/<pid>/smaps_rollup. PSS splits the cost of shared pages (shared libraries, mmap'd files) proportionally across every process that maps them, so a single agent is not charged for the entire libc.so or libcrypto just because it touched it.

Why not plain RSS? RSS double-counts shared memory: if 5 processes each map a 10 MB library, RSS reports 50 MB that isn't really there. RSS inflates every number in the table by the same shared-library tax, but inflates the Node family far more — each Node process drags its own copy of libv8, node, and libuv. PSS is the honest number an OS actually feels.

PSS = private pages + shared pages ÷ # processes sharing

Measured at idle — one process per agent, no prompts in flight. Figures for competitors are estimates from their public docs and community measurements; the h2code figure is reproducible from benchmarks/memory_benchmark.cr.

Everything you'd expect.
Nothing you don't.

A complete coding agent — protocols, providers, tooling, permissions — packed into one native binary.

Protocols
MCP

MCP — Model Context Protocol

Connect any MCP server (stdio, HTTP, SSE). OAuth-authenticated transports, lazy proxy tools, and a per-session tool cache — your agent gains every tool the MCP ecosystem ships.

ACP

ACP — Agent Client Protocol

Talk to your IDE natively. h2code runs as an ACP server over JSON-RPC stdio, so Zed, JetBrains, Neovim and any ACP-aware client embed it as a first-class agent.

Providers
API

14 cloud providers

Moonshot, DeepSeek, xAI (Grok), Z.AI / Zhipu, OpenRouter, Together, Fireworks, Groq, Cerebras and more — any OpenAI-compatible endpoint. Swap with a single /provider command.

LOC

Local providers — no API key

Run fully offline with Ollama and LM Studio. No credentials, no cloud round-trip, no telemetry — your prompts never leave the machine.

Agent tooling
TOOL

20+ built-in tools

Bash, Read, Write, Edit, Glob, Grep, WebSearch, FetchURL, TodoList, Skills, Goals, Cron, AskUserQuestion and more — the full coding-agent toolkit, prewired and permissioned.

SWARM

Subagents & swarm

Delegate to Agent for scoped work or fan out to an AgentSwarm — many parallel subagents over independent inputs, all under one parent.

Autonomy & safety
GOAL

Goals, plans, permissions

Four permission modes (default · plan · auto · yolo), durable goals with budgets, and a read-only plan mode — control exactly how much rope the agent gets.

HOOK

Hooks & skills

Fire shell hooks on PreToolUse, PostToolUse, SessionStart, Stop and 8 more lifecycle events. Compose reusable Skills and invoke them with slash-commands.

Beyond the terminal
MIC

Voice coding

Dictate instead of typing. Local speech-to-text — whisper.cpp + GigaAM — turns your voice into prompts, straight into the TUI. Audio is transcribed on your machine and never leaves it. Voice Converter →

PHN

Code from your phone

Start a session in the terminal, walk away, pick it up from your phone — same session, same history, live and resumable, synced end-to-end encrypted. Remote Control →

Three wins. One language.

We looked hard at Rust and Go. Each forced a trade-off we did not want. Crystal is the first language that let us keep all three wins at once — readable as Ruby, safe as Rust, light as Go.

01

Readable as Ruby

Crystal borrows Ruby's syntax wholesale — clean, expressive, reads like prose — but it compiles AOT to a native LLVM binary. Ruby's looks, C's speed: millisecond cold starts, no interpreter, no JIT warmup.

No problems with distribution, single binary, no memory eating aswell
02

Safe as Rust

A coding agent is a chat app, not a kernel. You don't need nanosecond gains you'll never notice on a desktop — and shouldn't pay for them with a borrow checker that turns every refactor into a research problem and gigs of build cache. Crystal gives you static typing, nil-safety, union types and generics, and exceptions instead of panics by default. Leave Rust for servers and kernels.

no annoying borrow checker, no panic from crates
03

Light as Go

CSP-style fibers and channels, sub-second compiles, single static binaries — the same ergonomics — but no if err != nil on every other line. You write the feature, not the ceremony.

no boilerplate in every function · no manual pointer management
One language. Three wins. No JS runtime.
SM

Why Crystal for the Solo Maintainer

When you're a one-person team, every 3 a.m. segfault is yours to fix. Go and Rust crash in ways that take down the whole process; Crystal throws a typed exception with a readable stack trace that you can rescue and recover from. Less firefighting, more shipping.

Failure mode Go Rust Crystal
Nil / null access panic — kills goroutine compile-blocked, or segfault in unsafe typed exception, catchable
Out-of-bounds index panic — kills goroutine panic! — kills thread IndexError, catchable
Crash in background task panic in goroutine kills the process panic in thread kills the process fiber exception, isolated & catchable
Error handling style if err != nil on every line Result + ? everywhere begin/rescue — only where it matters
Default failure result process exit thread abort / unwind exception with full trace

Bottom line: in Go and Rust a single unchecked panic in a background task terminates the entire application. In Crystal the same fault is a typed exception scoped to its fiber — your agent keeps running, your user keeps coding, and you read the trace in the morning.

Who owns the code.
Where your prompts go.

Memory is half the story. The other half: license, country-blocks, forced routers, and whether you can bring your own endpoint.

Agent License Country-blocked Forced router BYO endpoint
Claude Codeproprietaryyesyes (Anthropic)no
Codex CLIApache-2.0yesyes (OpenAI)no
grok-buildApache-2.0partialxAI defaultpartial
GooseApache-2.0nonoyes
AiderApache-2.0nonoyes
opencodeMITnonoyes
kimi-codeMITnoMoonshotyes
h2codeGPL-2.0-or-laternonoyes

Prefer to build it yourself?

You need Crystal ≥ 1.14 and ripgrep (rg).

  1. Install Crystal ≥ 1.14

    brew install crystal (macOS) · sudo pacman -S crystal (Arch)

  2. Install ripgrep

    Required by the Grep and Glob tools — brew install ripgrep or sudo apt-get install ripgrep

  3. Clone & build

    git clone the repo, then shards install and rake build → produces ./h2code

  4. Smoke-test & run

    ./h2code --hi to check credentials, then launch the TUI or go headless.

build.sh
# Clone and build
git clone https://github.com/ByOrlov/h2code
cd h2code
shards install
rake build            # → ./h2code (release flags)

# Setup credentials in Wizard while using application
./h2code 

# Or simply run
rake run