VizLearn
From the workshop
Engineering notes on how VizLearn is built — the architecture, the hand-drawn animation engine, and the decisions behind them.
All posts · newest first
- EngineeringJuly 28, 20267 min read
Two arrows, never one bus
A lesson player has 'player state': the input, the highlighted line, the log, whether it's playing. The obvious build is one context every surface reads. I used two instead, pointing opposite ways — the learner's input flows in, the animation's position flows out — because a React context re-renders every subscriber on every change, and those two flows move at wildly different speeds.
- EngineeringJuly 8, 20266 min read
Highlight the phase, not the line
The code panel lights up the line the animation is on. Then I added a Python/JavaScript toggle and a naive-vs-optimized switch that both change the code, and the same animation kept highlighting the right line in all four. The trick is that the animation never emits a line number. It emits what's happening, and each code file answers where.
- DesignJune 24, 20267 min read
I drew the algorithm, not an icon
The easy way to cover a catalog of lessons is a stock icon per card. I drew a tiny diagram for each instead — the lesson squeezed into one monochrome 320×180 frame with a single label. The social card and the poster-size cover then come for free: the same drawing, rendered bigger.
- EngineeringJune 15, 20269 min read
Your play button shouldn't know what it's playing
VizLearn grew three kinds of animation — a recorded sort, an interactive data structure, a live neural net you draw on — and each quietly grew its own play button. Collapsing them into one transport bar meant noticing the few verbs all three engines already had in common.
- LearningJune 14, 20267 min read
Contrast is the cheapest depth
A single run that works teaches almost nothing you'd actually believe. What teaches is the second run — the same idea with one variable changed, so the property you're trying to show appears in one and vanishes in the other. It turned out to be the cheapest depth I could add to a lesson, and the one I kept reaching for.
- LearningJune 13, 20267 min read
You don't understand it until you can predict it
Watching an animation feels like learning, but recognition isn't recall. So I built a quiz that makes you commit to the next step before it happens — and made it hard to cram, because every run is a fresh random one and every answer is read straight off the trace that drives the animation.
- LearningJune 8, 20266 min read
The animation that lied
An animation can be correct in every pixel and still teach the wrong thing — by faking a state the code never reaches, or by selling a limit of the canvas as a limit of the algorithm. The worst bugs I've shipped weren't crashes. They were lies a learner had no reason to doubt.
- EngineeringJune 1, 20267 min read
I told users to rotate their phone
VizLearn's first answer to a phone was an overlay telling you to rotate it. Taking that guard out meant admitting the fixed canvas had already solved more of mobile than I had noticed — shrink the picture, keep the input panel, widen the strokes that break.
- AIMay 25, 20265 min read
Record the agent, don't script it
The textbook ReAct diagram is a tidy little fiction. When I ran a real model on the same task, it didn't reason out loud or stumble and recover — so I stopped scripting my AI lessons and started recording them. The lesson changed because the recording refused to match my plan.
- DesignMay 11, 20265 min read
Most of the frame should be quiet
Draw every element at full strength and the frame comes out accurate and unreadable — a learner can't tell where to look. The thing I kept coming back to, lesson after lesson, was dull: pick one thing to be loud and let the rest go quiet.
- DesignApril 25, 20266 min read
I deleted the legend
Every algorithm visualizer ships a color key — yellow is comparing, red is swapping, green is sorted. I shipped one too, for longer than I'd like to admit, until I stopped naming colors by how they look and named them by what they mean. Then the key explained nothing the picture didn't, so I took it off.
- DesignApril 2, 20266 min read
The default input is the curriculum, not a sample
Most learners never open the config panel, so the array that loads by default is the only run they ever see. That makes it the lesson — and a tidy default that hides the property you came to teach quietly downgrades the whole thing to a movie.
- DesignMarch 23, 20265 min read
It's not too fast
The bug report is usually the same three words — it's too fast — and the fix it asks for is to slow the clock down. But in lesson after lesson, too fast turned out to be a density problem: too much happening in one beat. The cure was duller than any clock knob — split the beat into more beats and leave the seconds alone.
- DesignMarch 15, 20265 min read
A fixed canvas is why one component kit works everywhere
The reflex in 2026 is a fluid, responsive canvas that fits any screen. I kept doing the opposite: every VizLearn lesson draws on a canvas that is always exactly 1920×1080. It looked backwards at first, then turned into the constraint that let a hand-drawn component move from a sorting lesson to a neural net and still land in the right place.
- EngineeringMarch 13, 20265 min read
AI is a great reverse-engineer. That's the trap.
An AI read Motion Canvas's compiled bundle and Excalidraw's renderer for me and handed back the parts that mattered. That was useful enough to keep doing — and comfortable enough to lead me into a month building a tool I should have just adopted.
- EngineeringMarch 12, 20268 min read
I wanted a paintbrush, not a drawing app
VizLearn's hand-drawn look started life on the Excalidraw npm package — until it became clear I'd adopted a whole drawing app when what I needed was a paintbrush. This is the detour through roughjs and Remotion, the bug that made my rounded rectangles look terrible, and the two Excalidraw functions I kept (and credited).
- EngineeringMarch 11, 20269 min read
I wanted a dependency, not an engine
I could make Motion Canvas play, and even seek — I wrote a player that did. The trouble was that 'step 7' isn't a timestamp; it has to drive the animation, the code highlight, the log, and the input at once. Chasing that mismatch down, I rebuilt Motion Canvas in 679 lines of my own — then deleted it for Remotion.
- EngineeringMarch 9, 20269 min read
I wanted a component, not a studio
VizLearn's first three months ran on Motion Canvas, not Remotion. I switched when learner input, scrubbing, and code-sync all needed to live inside the app — and the detour taught me to pay attention to the boundary I was building at, not just the output format.
- EngineeringFebruary 26, 20268 min read
I built a debugger, not an animator
Most algorithm visualizers play you a movie. VizLearn pins the code, the visual stage, and the log to the same instant — a trace debugger for learning an algorithm, not a clip to watch. This is the architecture I ended up with after chasing that alignment through the implementation.
- LearningFebruary 18, 20266 min read
I started with binary search
Before VizLearn there was AlgoV, and before that, binary search: five lines of code where every hard part is a boundary. Static diagrams could only ever show the author's input. I wanted to type mine.