Vibe Coding in Ancient C: Streaming *The Life of a Showgirl* on a 25-Year-Old Mac | debene.devTable of Contents
There’s a screenshot on my other monitor right now that I can’t stop looking at.<br>An M4 MacBook is running a VNC viewer. That viewer is connected to a Mac OS 9 machine with a broken display and broken clamshell (new parts on the way) running bare on my workbench. On that classic Mac desktop, a little app called Casquinha is playing The Fate of Ophelia off Taylor Swift’s The Life of a Showgirl. Album art loaded. Scrubber moving. “Up Next” queue populated.<br>The record came out in a world of Spotify, HLS, and DRM. The machine playing it predates all three. Between them sits a stack I built by hand, and honestly? This one meant something.<br>The signal path#<br>Here’s what happens when I click Next in that OS 9 window:<br>M4 MacBook (2025)<br>│ RealVNC Viewer, RFB over TCP<br>MiniVNC ── VNC server, running ON the classic Mac<br>│ (with statsd telemetry, because why not)<br>Mac OS 9.2.1 @ 10.x.x.x ─ iBook G3 Clamshell<br>│ 64MB RAM, dead LCD, running bare on the bench<br>Casquinha ── my C99 Spotify remote for Mac OS 9<br>│ Open Transport → gopher (RFC 1436) over TCP<br>gopher-spot ── Rust bridge on Kubernetes<br>│ Spotify Web API ↔ gopher menus<br>Spotify
“Skip to the next Taylor Swift track” travels from Apple Silicon, through a VNC server I ported to PowerPC, across Open Transport, over gopher — a protocol from 1991 — into a Rust service on a Kubernetes cluster, and out to Spotify’s modern API. Then the answer comes back and repaints a 1-bit progress bar.<br>Nothing in that path was designed to touch anything else. That’s the whole post.<br>The machine#
The hardware is an iBook G3 Clamshell I rescued from a basement. It was covered in mold . I disassembled the entire thing — logic board, keyboard, every connector — cleaned everything with isopropyl alcohol, and discovered the LCD was dead.
Parts are en route: a new Samsung LT121SU-123 LCD panel (arrives July 24), 256MB RAM upgrade (July 14), and an mSATA SSD with IDE adapter (arriving today). But I couldn’t wait. So I reassembled it on the workbench without the case , did a clean Mac OS 9.2.1 install, and kept coding.
VNC isn’t a choice here; it’s survival. The display is physically dead. MiniVNC is the only way I can see the desktop until that LCD arrives.<br>The cast#<br>Three pieces of software are doing the work. Two are mine.<br>Casquinha — the native client#<br>Casquinha is a Spotify remote written in C99 for Mac OS 9 . Real classic Toolbox — Controls Manager buttons, hand-managed now-playing pane, Open Transport networking. Built with Retro68 (GCC cross-compiling to PowerPC), which means 2026 code with 2001 headers.<br>MiniVNC — the periscope#<br>MiniVNC is the VNC server I ported to PowerPC and — the fun part — instrumented with statsd . Frame timings, RFB update counts, endpoint health all fire UDP packets to a metrics collector. The vintage Mac is now a monitored node . It has telemetry. I can look at a Grafana panel and know how a 2001 laptop is feeling.<br>Without MiniVNC there’s no screen. The classic Mac sits headless; MiniVNC serves its framebuffer over RFB so I can drive it from the M4.<br>gopher-spot — the enabler#<br>gopher-spot is the piece that makes all of this possible. It’s a Rust service running on my Kubernetes cluster that acts as the bridge between two incompatible worlds: Spotify’s modern OAuth2/TLS/JSON API on one side, and a 1991 text protocol on the other.<br>Without gopher-spot, there’s no way a 64 MB Mac from 2001 could talk to Spotify. The backend does the heavy lifting — OAuth token refresh, HTTPS connections, parsing megabyte JSON responses, maintaining WebSocket streams for now-playing state, handling rate limits — and translates all of that complexity down to plain gopher menus : tab-delimited text lines that a cooperative OS can parse in microseconds without freezing.<br>It’s more than a Spotify bridge. It’s the reference implementation of a pattern : modern service → K8s → gopher → thin native client. Any API — weather, transit, news feeds — can be reduced to gopher menus by a bridge running on hardware that can afford the complexity. Then any vintage machine gets to feel fast and native because it never has to do the hard part.<br>The architecture is the real trick here. Casquinha is 2,000 lines of C. gopher-spot is 1,500 lines of Rust. But the separation of concerns means the thin client stays simple, testable, and responsive, while the bridge handles every ugly reality of talking to a 2020s API.<br>That’s why this works. The protocol choice isn’t nostalgia—it’s deliberate offloading of complexity to where the compute lives.<br>Why gopher, not just HTTP?#<br>The classic Mac can do HTTP. There are TLS stacks that sort-of work.<br>But on a 64 MB machine with cooperative multitasking , every byte of parsing you avoid is a freeze you avoid. Modern TLS handshakes, chunked...