I have a theory that only bad projects get finished — good ones keep finding new things to do. Asciinema is a case in point. What started as a way to share terminal sessions with friends has, over 14 years, grown into a full suite of tools covering recording, hosting, playback, and live streaming — and been rebuilt multiple times along the way. So what does it actually take to record and replay a terminal session faithfully in a browser?
Joining us for this conversation is Marcin Kulik, Asciinema's creator. The project's architecture has passed through almost every interesting corner of software engineering: a Python recorder built around pseudo-terminals (PTY), a ClojureScript terminal emulator for the browser that hit performance limits with immutable data structures and garbage collection pressure, a move to Rust compiled to WebAssembly, a Go experiment that didn't last, and a new Rust CLI for concurrent live streaming backed by an Elixir/Phoenix server that calls Rust code via NIFs. The same Rust terminal emulator library now powers all three components — the browser player, the server, and the CLI.
If you've ever looked at those terminal animations embedded in a README and wondered what's underneath them, or if you're interested in how a passionate open-source developer navigates 14 years of language changes and rewrites, this conversation has plenty to offer.
---
Support Developer Voices on Patreon: https://patreon.com/DeveloperVoices
Support Developer Voices on YouTube: https://www.youtube.com/@DeveloperVoices/join
Asciinema: https://asciinema.org
Asciinema Docs: https://docs.asciinema.org
Asciinema CLI (GitHub): https://github.com/asciinema/asciinema
Asciinema Player (GitHub): https://github.com/asciinema/asciinema-player
Asciinema Server (GitHub): https://github.com/asciinema/asciinema-server
AVT - Rust terminal emulator library: https://github.com/asciinema/avt
vt-clj - the original ClojureScript terminal emulator: https://github.com/asciinema/vt-clj
Paul Williams' ANSI/VT100 State Machine Parser: https://vt100.net/emu/dec_ansi_parser
Rust: https://www.rust-lang.org
WebAssembly: https://webassembly.org
SolidJS: https://www.solidjs.com
Elixir: https://elixir-lang.org
Phoenix Framework: https://www.phoenixframework.org
Rustler (Rust NIFs for Elixir/Erlang): https://github.com/rusterlium/rustler
Clojure: https://clojure.org
ClojureScript: https://clojurescript.org
cmatrix: https://github.com/abishekvashok/cmatrix
Marcin Kulik on GitHub: https://github.com/ku1ik
Marcin Kulik on Mastodon: https://hachyderm.io/@ku1ik
Marcin Kulik on asciinema.org: https://asciinema.org/~ku1ik
"They're Made Out of Meat" demo: https://asciinema.org/a/746358
Kris on Bluesky: https://bsky.app/profile/krisajenkins.bsky.social
Kris on Mastodon: http://mastodon.social/@krisajenkins
Kris on LinkedIn: https://www.linkedin.com/in/krisjenkins/
---
0:00 Intro
2:28 What Is Asciinema?
4:48 How Asciinema Started
9:51 The Problem of Parsing Terminal Output
14:07 Building a Cross-Platform Recorder
17:01 Rewriting the Parser in ClojureScript
22:19 The Hidden Complexity of Terminals
29:28 Rendering Terminals in the Browser
39:47 When ClojureScript Can't Keep Up
45:28 Moving to Rust and WebAssembly
52:01 The Go Experiment
57:43 Adding Live Terminal Streaming
1:07:12 Can You Scrub Back in a Live Stream?
1:14:40 Editing Recordings
1:25:27 Outro