Why I built this

I built teru because I was running Claude Code with agent teams — multiple AI agents working in parallel — and they kept destroying my tmux layouts. Every time an agent spawned 4–5 subprocesses, tmux would split into unusable fragments. I was managing three config layers (tmux.conf + shell scripts + xmonad keybindings) just to keep terminal panes organized.

The terminal emulator had no idea what was happening. It saw bytes. My tiling manager saw windows. tmux saw panes. None of them understood process relationships, AI agent state, or why some panes were waiting for others.

I wanted a single tool that understood all of it — that knew which pane was running which agent, what its current task was, whether it succeeded or failed, and how it related to the other agents. Something that could receive Claude Code's spawn commands directly, without a tmux intermediary.

teru is that tool. It's a terminal emulator, multiplexer, and tiling manager in one 1.3MB binary. Written in Zig 0.16, CPU SIMD rendering via @Vector, no GPU. Frame times under 50μs.

Technical decisions

Zig over Rust

Zig's comptime was invaluable for platform selection (-Dx11=false, -Dwayland=false). Inline tests keep test code adjacent to implementation. The build system is expressive without a separate DSL. And Zig's @Vector made SIMD blending straightforward.

CPU over GPU

For terminal rendering — text on a character grid — the GPU is idle 99.9% of the time. SIMD blitting on CPU is faster for this workload and works everywhere: SSH sessions, VMs, containers, cheap VPS with no GPU. Benchmarked both paths; CPU won.

No tmux dependency

The multiplexer is part of the same event loop as the renderer. No separate process, no IPC overhead, no config translation. This also made it possible to implement the CustomPaneBackend protocol without an adapter layer.

Compressed scrollback

Storing expanded character cells in a ring buffer is expensive. Storing the VT byte stream with keyframe/delta compression gives 20–50x better ratios. A 50,000-line scrollback costs ~5MB instead of ~150MB.

Current status

teru is v0.1.x — it works as my daily driver on X11. Wayland works but keyboard handling is still raw passthrough (proper xkbcommon integration from compositor keymap FD is pending). Missing: full Unicode (emoji/CJK), shell integration scripts, detach/attach daemon mode (planned v0.2.0), plugin system (planned v0.4.0).

The AI integration — CustomPaneBackend, MCP server, OSC 9999, hook listener — is fully wired and stable. That's the part I built teru for, and it works well.

See the Roadmap for what's coming, and the Changelog for what's shipped.

Author

Nicholas Glazer

contact: [email protected]

Company

Up Go Corp.

License

MIT

Free to use, modify, and distribute

Source Code

Codeberg

Primary repository

Arch Linux

AUR: teru

paru -S teru

Issues

Codeberg Issues

Bug reports and feature requests

Contributing

Contributions are welcome. teru is written in Zig 0.16-dev — make sure you have the right version installed.

1 Fork and clone from Codeberg
2 Install Zig 0.16-dev and system deps: libxcb, libxkbcommon, wayland
3 Run make test to verify your setup (250 tests)
4 Make your changes, ensure all tests pass, submit a pull request

Areas looking for help: Full Unicode (CJK/emoji), shell integration scripts (bash/zsh/fish OSC 133), detach/attach daemon, Wayland keyboard from compositor keymap FD, macOS AppKit backend, Windows ConPTY.