Tachikoma.jl is a pure-Julia framework for building rich, interactive terminal applications. It uses an Elm-inspired Model/update!/view architecture with a 60fps event loop, double-buffered rendering, 30+ composable widgets, and built-in recording/export.
GitHub: github.com/kahliburke/Tachikoma.jl
Docs: kahliburke.github.io/Tachikoma.jl

Install
using Pkg
Pkg.add("Tachikoma")
Requires Julia 1.12+.
What’s in the box
Architecture — Define a Model struct, write update! for events, write view to render. The framework handles the event loop, frame pacing, and diff-based terminal output.
30+ widgets — Text inputs, text areas, code editor with syntax highlighting, data tables with column resize/sort, forms with validation, tree views, charts, sparklines, calendars, modals, dropdowns, markdown viewer, and more.
Constraint layouts — Fixed, Fill, Percent, Min, Max, and Ratio constraints with nested horizontal/vertical splits. Draggable resizable pane borders with layout persistence via Preferences.jl.
Animation — Tweens with 10 easing functions, physics-based springs with retarget!, timeline composition (sequence, stagger, parallel), and organic effects (pulse, breathe, shimmer, jitter, flicker, drift).
Graphics — Three rendering backends: Braille dots (2x4 per cell), quadrant blocks (2x2), and pixel rendering via Kitty or sixel protocol (16x32 per cell). Vector drawing API with lines, arcs, circles, and filled shapes.
11 themes — Cyberpunk, retro, and classic palettes (Kokaku, Esper, Motoko, Kaneda, Neuromancer, Catppuccin, Solarized, Dracula, Outrun, Zenburn, Iceberg) with hot-swap switching at runtime.
Async tasks — spawn_task! / TaskQueue for background work that delivers results back to the main thread as events, preserving the single-threaded Elm architecture. Cancel tokens, timers, and repeat scheduling.
Recording & export — Live recording via Ctrl+R, headless record_app() / record_widget() for CI/docs, native .tach format with Zstd compression, export to SVG and GIF.
Testing — TestBackend for headless widget rendering with char_at(), style_at(), row_text(), find_text() inspection APIs.
Quick example
A Game of Life in ~30 lines:
using Tachikoma
@kwdef mutable struct Life <: Model
quit::Bool = false
grid::Matrix{Bool} = rand(24, 80) .< 0.25
end
Tachikoma.should_quit(m::Life) = m.quit
function Tachikoma.update!(m::Life, e::KeyEvent)
e.key == :escape && (m.quit = true)
end
function Tachikoma.view(m::Life, f::Frame)
h, w = size(m.grid)
g = m.grid
nc = [sum(g[mod1(i+di,h), mod1(j+dj,w)]
for di in -1:1, dj in -1:1) - g[i,j]
for i in 1:h, j in 1:w]
g .= (nc .== 3) .| (g .& (nc .== 2))
a, buf = f.area, f.buffer
for i in 1:min(h, a.height), j in 1:min(w, a.width)
g[i,j] || continue
set_char!(buf, a.x+j-1, a.y+i-1, '█',
tstyle([:primary,:accent,:success,:warning,:error][clamp(nc[i,j],1,5)]))
end
end
app(Life())
Gallery
| Dashboard | Form with Validation |
![]() |
![]() |
| Animation Showcase | Todo List |
![]() |
![]() |
| GitHub PR Viewer | Animated Backgrounds |
![]() |
![]() |
Comparisons
Tachikoma is designed full-screen interactive applications with their own event loop, like what you’d build with Textual (Python), Ratatui (Rust), or Bubbletea (Go). If you want to build a dashboard, data explorer, or game that takes over the terminal, that’s what Tachikoma is for.
Tutorials
The docs include step-by-step tutorials that build complete apps:
- Getting Started — A dice game covering model, input, layout, and widgets
- Dashboard — Multi-panel layout with charts, tables, and live data
- Todo List — CRUD app with forms, validation, and modal dialogs
- GitHub PRs — Async data fetching with DataTable and markdown rendering
- Animation Showcase — Tweens, springs, timelines, and organic effects
Feedback, issues, and contributions welcome at github.com/kahliburke/Tachikoma.jl.





