strace-UI, Bonsai_term, and the TUI Renaissance

berlianta1 pts0 comments

Jane Street Blog - strace-ui, Bonsai_term, and the TUI renaissance

strace-ui, Bonsai_term, and the TUI renaissance

May 26, 2026 |

10 min read

Share on Facebook

Share on Twitter

Share on LinkedIn

By: James Somers

We’ve always found strace useful but somewhat hard to work with. Its output is often<br>inscrutable, it’s hard to follow subprocesses or threads, and if you want to filter<br>syscalls you have to rerun the trace with a flag for each one. What you want in debugging<br>is a tool for exploring, refining, etc., but strace can make this difficult.

Enter strace-ui, which turns strace into an interactive terminal UI:

strace-ui assigns short IDs to PIDs to make them easier to scan, formats structs, and<br>renders buffers as hexdumps instead of strings. It has some other nice features that you<br>can’t see in the screenshot:

Interactive filtering. Tracing an async OCaml process? Did you forget to pass -e<br>'!futex,timerfd_settime,epoll_wait'? Don’t worry: press h to hide any syscall you<br>don’t care about.

Trace a particular file-descriptor. Press > or What even is rt_sigprocmask? Press m to open the man page and find out.

Subprocesses or threads are assigned short numeric labels, instead of showing you the<br>raw pid, making it easier to follow a complex strace -f calls. (You can also filter by<br>PID or exclude PIDs.)

DNS resolution: strace’s --decode-fds=all will print file descriptors as<br>1411.11.11.11:56789]>, which is great. strace-ui goes one<br>step further and prints 14another-hostname:56789]> , which<br>makes it easier to see at a glance exactly what your process is doing.

Ian Henry, a dev here, made<br>strace-ui to scratch his own itch. In 2017, he’d gone looking for such a tool but never<br>found it. Having had experience building interactive terminal UIs (including in OCaml,<br>using lambda_term), he knew how difficult and unpleasant it could be. The idea percolated<br>over the years, never feeling worth it, until recently when a few forces converged to<br>make terminal UI development actually kind of delightful.

Bonsai, a powerful framework for reactive UIs

For years now we’ve been building web applications with OCaml in a functional style, using<br>a library we developed called Bonsai, loosely<br>inspired by Elm. A simple Bonsai component with a little<br>interactivity looks like this:

module Dice = struct<br>let faces = ...

let component (graph @ local) =<br>let face, set_face = Bonsai.state (List.hd_exn faces) graph in<br>let%arr face and set_face in<br>{%html|<br>div><br>You rolled a #{face}<br>button<br>style=""<br>on_click=%{fun _ -><br>let index = Random.int (List.length faces) in<br>set_face (List.nth_exn faces index)}<br>>Roll the dicebutton><br>div><br>|}<br>end

Components are implemented as purely functional state machines, and are easily composable.<br>Incrementalization inside the framework means that values don’t get recomputed until<br>necessary. This applies to every value, not just the view.

What’s neat about Bonsai is that it allows you to compose state and incrementality<br>primitives a la carte. The same primitives that prevent re-rendering the entire page during<br>user interaction can also be used to incrementalize an expensive business logic computation<br>on a live-updating dataset. (If you’re used to React, imagine if everything used something<br>very similar to hooks, and state was managed outside of the component hierarchy.)

And because Bonsai is written in OCaml, it becomes possible to use the same language and<br>types on both the backend and frontend. It’s hard to overstate the impact this has on<br>keeping a large web app’s codebase manageable, especially when you make pervasive use of<br>OCaml’s type system.

Bonsai is not really a web framework

So far we’ve actually been talking about Bonsai_web. Bonsai itself is agnostic to the<br>frontend, because when you think about it, all UIs can fundamentally be expressed as<br>stateful incremental computations, in which different components know how to render<br>themselves as their underlying data changes.

If Bonsai is a library for managing the lifecycle and scoping of state, with a layer on top<br>for expressing the particulars of a given UI surface, you can see how the same underlying<br>core can be adapted. And that is where Bonsai_term came from.

In the earliest days of Bonsai, back in 2019, the idea that you’d end up using it for<br>terminal apps felt almost like a joke. In some ways the whole point of Bonsai was that at<br>Jane Street we felt somewhat underpowered when it came to web development. Some of our<br>most important apps were built on the ancient and somewhat difficult<br>curses library, which lives<br>up to its name.

Terminal apps are fast and keyboard-centric, which we like, but the web also has a lot<br>going for it. It’s hard to beat the ergonomics of clicking a hyperlink; and of course the<br>web gives you a vast palette for constructing UIs, including charts and graphics that<br>aren’t practical on the command line, and integrated help (via tooltips and the like). In<br>the years after the release of Bonsai_web there was a huge flowering...

strace bonsai terminal ocaml state bonsai_term

Related Articles