Writing

Essays

Things I have learned. Things I built, broke, and eventually figured out.

  1. Snake, React-style, in your terminal Jun 29, 2026 · 14 min A complete snake game in one Rust file: signals for state, use_input for steering, an alternate screen for the arena, and a 200ms tick loop you own yourself. React patterns, zero JavaScript. rust · tui · tutorial
  2. What survived the port Jun 22, 2026 · 12 min Porting Ink from TypeScript to Rust: hooks and flexbox crossed over almost unchanged, the React reconciler didn't, and the most valuable artifact turned out to be the test suite — including the tests we refused to port. rust · tui
  3. A panic must not take the terminal with it Jun 15, 2026 · 12 min A panicking component in a TUI can leave your shell in raw mode with a hidden cursor. How inkrs catches component panics, surfaces them as last_error, and re-renders cleanly on the next tick. rust · tui
  4. The subtlest component in Ink Jun 8, 2026 · 12 min <Static> prints items exactly once, above a live region that repaints forever — the shape of every test runner and build log. The 'first Static is the accumulator' rule, and why append-only output inside a diffing renderer is harder than it looks. rust · tui
  5. Terminal rendering is a diff problem Jun 1, 2026 · 13 min Clear-and-reprint flickers; a real TUI repaints only what changed. Inside log-update: erase-line math, incremental line diffs, and a scroll-region trick that moves a whole band of the screen without redrawing it. rust · tui
  6. Forty years of history arrive on stdin May 25, 2026 · 12 min Arrow keys are three bytes, Esc is ambiguous by design, and Ctrl+I is indistinguishable from Tab. Parsing terminal keypresses in Rust, and how the kitty keyboard protocol finally cleans up the mess. rust · tui
  7. Your terminal executes strings May 18, 2026 · 13 min Every string you print is a little program: escape sequences can move the cursor, erase the screen, retitle the window. What sanitize-ansi strips before untrusted text hits the render grid — and why it's an allowlist, not a blocklist. rust · security · tui
  8. Wrapping text without breaking its colors May 11, 2026 · 11 min Naive line-wrapping cuts ANSI styles in half and bleeds color across your UI. How the wrap-text crate tokenizes styled text into SGR runs, wraps the visible characters, and keeps every line self-contained. rust · tui
  9. How wide is a string? May 4, 2026 · 10 min Rust gives you three ways to count a string — bytes, chars, graphemes — and a terminal UI needs a fourth. How the measure-text crate counts cells: CJK doubles, emoji lie, and ANSI escapes count for nothing. rust · tui