TTFX rewrote 37 Python terminal effects in Rust. The benchmark is the easy part.
The repo shows 37 effects ported in hours, byte-level parity, and a benchmark that has already moved past the viral post.
The 9.6x claim is already stale. The repo tells a better story about agent-built software.
TerminalTextEffects, or TTE, is a Python library that animates text piped through a terminal. ChrisBuilds wrote it. It is MIT-licensed, and its pyproject.toml declares no runtime packages of its own. Using it still means installing a Python package and paying for an interpreter start every time a shell prompt wants an animation.
That stopped being the only option on 9 August 2026. David Heinemeier Hansson and Omacom published TTFX, a Rust port of TTE v0.15.0 built for the Omarchy Linux setup and since tested on macOS. It ships as one compiled binary with no interpreter to provision.
The post that carried TTFX around opened with "The SaaS monopoly ends this year." TTE is not SaaS and was never a monopoly, so we read the Git history, the plan file, and the checked-in benchmarks to see which parts of the story the repository supports and which parts have quietly moved since launch.
git clone https://github.com/omacom-io/ttfx.git
cd ttfx
cargo build --release
git log --oneline -10 | ./target/release/ttfx matrixWhat the Git history supports
The timeline holds. The first commit is stamped 12:50 PDT on 9 August 2026. All 37 effects passing the parity suite landed at 14:23, ninety-three minutes later, with 354 parity cases behind them. The v0.1 tag followed at 16:01. That is one afternoon, and every commit in it is public.
A compatibility job, not a translation
The most useful file in the repository is plan.md, all 473 lines of it. It pins the source to TTE v0.15.0 at commit 7a91dd9, sets byte-identical frames as the goal, lists the deliberate differences, and maps the Python object graph into Rust before a single effect module goes to an agent.
Python lets characters, scenes, paths, events, and callbacks hold references to each other freely. The Rust port replaces that graph with arenas and small IDs. Engine methods fetch state again after synchronous event dispatch, which preserves Python's callback order without holding conflicting Rust borrows. Python closures become enum variants with owned payloads.
The port also reproduces behavior a normal rewrite would call a bug and fix: banker's rounding, integer floor division inside gradients, a Bezier length approximation that drops its final segment, and looping scenes that report completion on every tick. Those quirks are in the contract because any one of them can change a frame.
The repository checks more than rendering:
The parity harness injects the same test PRNG into both programs so it can compare frames byte for byte. Outside that harness the two diverge on purpose: TTFX runs xoshiro256++ and Python runs Mersenne Twister, so the same `--seed` does not produce matching random choices across them. Python plugin effects are unsupported. The current README limits byte-exact parity to Linux and glibc, because macOS math can differ in the last bit.
The benchmark moved after launch
The circulated post says startup fell from 87 ms to 2 ms and rendering became 9.6x faster. The 9.6x figure is in the repository. That exact startup pair is not, in any commit we inspected.
What the benchmark measures
The benchmark harness runs the real `ttfx` and `python -m terminaltexteffects` commands, sends their output to the null device, and keeps the fastest wall-clock result. For the main throughput test it disables frame pacing. At 200 by 50 cells, the current README reports slide at 76 ms against 2,203 ms, beams at 181 ms against 5,564 ms, rings at 521 ms against 10,439 ms, and waves at 374 ms against 8,745 ms.
That is engine throughput, and it is real. It is not the same thing as every animation feeling 27.5 times faster. A normally paced effect sleeps between frames on purpose, and matrix and thunderstorm contain fixed wall-clock phases. TTFX can draw more frames inside a three-second phase. It cannot make the phase shorter than three seconds without changing the effect.
The repository publishes the harness, which is better evidence than a number on its own. It does not record the benchmark machine in the README, and these are maintainer results rather than an independent run. Treat the ratios as reproducible claims to test on your own target, not as hardware-neutral constants.
Why the agents moved this fast
The first commit did not turn 37 agents loose on 37 files. It landed a 473-line plan, a pinned Python tree, the Rust engine scaffold, an ANSI input parser, Python-semantics helpers, a renderer, and 112 first-frame parity checks. Before any effect was written, the project had a narrow contract and an oracle that could reject a wrong answer without a human reading it.
Once the engine held, the effects became good parallel work. Each one lived in its own module, used the same engine, and had parity cases waiting to fail it. The Git history then shows worktree-agent batches landing separate groups of effects. Claude Fable 5 appears as co-author throughout the initial run, with David Heinemeier Hansson as the commit author.
What one-shot hides
It was still iterative software work. There were 67 commits before v0.1, multiple worktree merges, benchmark corrections, another performance pass, macOS support, terminal resize handling, and signal cleanup. The current history has contributions from four people. A repository can be created in an afternoon and still need maintenance the next morning.
Our read
Our read, and this is the studio's opinion rather than anything the repository states: the transferable part is not Rust, and it is not the agent count. It is that "port this library" was rewritten as "match this pinned program byte for byte under these inputs, keep these four known exceptions, and do not merge until this suite passes." That sentence is a build system. Agents go fast when the task splits cleanly and wrong answers fail loudly, and TTFX bought both before it wrote a single effect. What TTFX does not tell us is what happens when the acceptance test is a customer's changing behavior, a regulator's judgment, a production incident, or five years of compatibility promises. Those do not compile.
Run the proof, not the slogan
Clone both pinned trees, build the release binary, and run the repository's own test entry point. On Linux that covers the Rust tests, the CLI corpus, PTY behavior, and the byte-level parity suites.
./bin/test
TTFX_BENCH_COLS=200 TTFX_BENCH_LINES=50 TTFX_BENCH_FILL=1 \
python3 tools/tests/bench_full.py 5Then inspect one failed or slow effect before you change anything architectural.