I took a side project I built by hand in 2021 and used AI to turn it into a product-level app in a few days. The speed is not the story; the story is that the prototype had already made every hard decision.
Search posts, research, projects and tags, or jump to a page.
In 2021 I started building a graph editor by hand. No Copilot, no chat window, just Create React App, a stack of library docs, and a lot of evenings. The idea was easy to say and hard to build: draw a graph on a canvas, write a real Python algorithm against it, and watch every step animate. Pyodide ran CPython in a web worker, a custom Graph class bridged Python calls to the React DOM, and BFS lit up nodes one frame at a time.
It took about a hundred commits spread across eighteen months of weekends. It ended life as a good prototype: undirected graphs only, no accounts, no persistence, a Docker image for anyone brave enough to run it, and a README apologizing for the missing mobile support.
This week I rebuilt it with AI in a few days. The new Graph Editor runs on Next.js and React 19 with a WebGL canvas, real accounts, saved graphs behind row-level security, directed and weighted graphs, multi-file Python projects where imports actually work across files, and a playback engine you can scrub like a video. Migrations apply from CI. By any honest measure it is a product now, not a prototype. The full write-up is on the project page.
The tempting takeaway is "AI is fast." That is true and boring. The interesting question is why this rebuild went so smoothly when plenty of AI-assisted projects wander off into the weeds.
The 2021 codebase had one genuinely good idea: real Python driving the canvas. But more importantly, it encoded hundreds of small decisions that took me months to converge on. The shape of the Python API, down to setCurrentNode(node, peek=True). The semantics of visited versus peeked versus path. The frame-based animation model. Keeping the interpreter off the main thread so the UI never freezes. Each of those was, at some point, a weekend argument with myself.
By the time I sat down to rebuild, none of that thinking needed to be redone. The brief I could hand the AI was unusually sharp: keep the Python-to-canvas bridge, it was always the right idea; modernize or replace everything around it. When the model proposed something, I never had to figure out what I wanted. I only had to check the proposal against a picture that already existed, in my head and in the old repo.
That is a very different job than inventing the product while also building it. And I think it explains most of the speed.
Give a model a defined problem, a reference implementation, an API contract to preserve, a test that says what "done" means, and it is relentless. It does not get tired of boilerplate, it holds more of the codebase in view than I can, and it happily rebuilds in an afternoon what would take me a week of context switching.
Give it an undefined problem and it does something else: it guesses. It fills every gap in your spec with its own taste, which is really an average of everyone else's taste. Each guess becomes the foundation for the next one, and an hour later you are reviewing an app you do not recognize. The model did not fail; it answered a question you never actually asked.
I watched both modes during this rebuild. The bridge, the graph API, the animation semantics: defined, and the AI nailed them almost immediately. The visual identity: undefined, because the old app never had one, and the first passes came back looking like every other generated dashboard. It only converged after I made design a defined problem too. Pastel palettes, light-first, monospace only inside the code editor, and the algorithm states must stay distinguishable at a glance. Constraints in, quality out.
Fred Brooks wrote in 1987 that "the hardest single part of building a software system is deciding precisely what to build." He was arguing there is no silver bullet for the essence of software, only for the accidents. Nearly forty years later that split describes AI coding tools almost perfectly. The accidents, the typing, the wiring, the boilerplate, the framework trivia, have collapsed to nearly zero. The essence, deciding precisely what to build, is still entirely yours.
Sometimes defining the problem really is half the battle, and I had unknowingly finished that half in 2021.
Which suggests a practical corollary: old side projects are specs in disguise. If you have a repo from years ago where you did the hard thinking by hand, that thinking is still good. The code aged; the decisions did not. You can pour them into a modern stack in days.
Keep going, and keep the repo. Every hour spent deciding how peek should behave felt like it only mattered for a toy project nobody would use. It turned out to be the durable half of the work, the half no tool has automated yet.
The rebuild took a few days. Defining the problem took eighteen months of weekends. AI let me skip the second eighteen months, not the first.
0 comments
Sign in to join the discussion