Introducing tapStory for Web
I used Claude Code to port my iPad app, tapStory, to the web. I touched precisely 0% of the code in this project.
I shouldn’t be surprised, at this point, by the state of the art in agentic coding. But I am genuinely amazed by the result.
You can read my original story Pea and Carrot with the current beta implementation. Page through the whole story, move the characters, record your animations with audio, and play back your performance.
It has a few bugs, and it’s missing features for saving recordings and creating new stories. But what’s there feels pretty close to a one-for-one port.
It was fast and (relatively) cheap.
It took me less than a week of calendar time, and in the neighborhood of 12 hours of continuous clock time. Most of that time, from my perspective, was waiting for Claude to burn tokens “thinking” and writing code. The rest was me crafting detailed prompts, testing the ongoing progress in my browser, and going back and forth with Claude to make corrections, fix bugs, and deliberate on decisions.
I used the flagship model as of right now—Claude Opus 4.7—and set it to xHigh effort (one stop short of Max, the highest level). It cost $5 per million tokens of input, and $25 per million output tokens. To date, I’ve spent roughly $425.
From one perspective, that’s a considerable expense. But to pay an experienced web developer market rate to do the same work would have been a couple orders of magnitude more expensive. I’m looking at a project with 47 JavaScript files totaling just under 20,000 lines of code, plus another ~1,500 lines of HTML across 13 files. Realistically, this is several weeks of work for a high-caliber developer, probably between 100-200 hours.
If I were to tackle the project on my own, it would be even more expensive, given how much work it would take for me to learn the skills and techniques that this code exhibits.
While I can’t vouch for its quality, the code looks pretty reasonable at first glance. It’s well organized, commented, and has a sound architecture—at least from my perspective as a senior software engineer without any web development experience.
I was (more than?) halfway up the mountain.
So the code was impressive—but look at where I started. My tapStory iPad project has roughly 80,000 lines of Objective-C code, developed over more than half a decade. It’s commented extensively and well organized, and I made sound architectural decisions throughout.
So to build tapStory for Web, I pointed Claude Code at this iPad project.
It did a great job of spelunking my entire Objective-C codebase. It synthesized the results in a summary Markdown document that details all the components of the app (in programming terminology, its classes), their basic roles, and how they interact with the others.
My process was simple.
I asked Claude to draft a plan for porting tapStory to the web as a native JavaScript/HTML/CSS app, using its own summary document and the original code as references. I told it to avoid third-party dependencies like React. It asked me questions along the way to work out major architectural decisions. The planning process probably took around two hours.
Once I had the plan in hand, the process was simple. I asked it to implement the project phase by phase, with tests at each step to ensure that nothing seriously broke along the way. Some phases went very smoothly with no input from me. Others required me to intervene, either to correct a mistaken notion, redirect an approach, or point Claude toward a particular piece of Objective-C source to make sure it understood the assignment.
A couple steps required more heavy intervention. The most complicated work I did was handling recording and playback of audio; getting playback to sync to the character animations was a lot trickier than I had anticipated. I know nothing about how browser engines handle audio input and output, so it was a good stress test for Claude Code. It took the better part of one day, on and off, to iterate through buggy implementations before arriving at the correct solution. I had to rely on my developer instincts and taste to guide me through the process—I’m not sure how a non-coder or more junior developer would have fared. I had Claude write a debrief after the fact which you can read below if you’re interested. (It also left lots of helpful comments in the source code.)
On the whole, the process was akin to working with a competent developer who can work through complex tasks in decent-size chunks with little direction. It’s a significant improvement compared to my earlier (already good) experience with TicketBook.
I had fun!
This is the perfect kind of project to live closer to the hands-off end of the LLM coding continuum. It’s a project I’ve wanted to try for a long time. I don’t rely on tapStory for my livelihood, and I didn’t touch my original code. No risk, all upside.
Being able to move this rapidly to create something is fun. From idea to implementation in a week for a complex project—it’s an entirely novel experience. I got into computer science because I love the craft of coding, and because I can express my creativity in near-unlimited ways. It’s like having a giant pile of LEGO bricks. With an LLM, I have a lightning-fast expert builder in the pile with me.
We live in wild and confusing times.
There’s a lot of discussion in the developer community about AI-assisted coding. People are worried that existing skills will atrophy. They’re concerned that we senior developers are pulling up the ladder behind us, leaving the entry-level job market in dire shape. How are new coders supposed to build the skills and experience necessary to wield these powerful tools properly? To say nothing of the ethical implications of the models and AI companies themselves, or the potential long-term consequences.
Many open-source projects are drowning under a flood of contributions of dubious value. More than a few technology companies are cynically using this moment to fire thousands of people, citing the efficiency gains from AI despite the fact that the utility of LLMs is outstripped by their marketing.
People also mourn the loss of the art and craft of programming. Can you take genuine pride in something you didn’t build yourself? What do you lose in the process? LLM-generated code can be incoherent and unmaintainable. What’s the cost of creating software that way? What are the implications of building with unfamiliar software components without needing to learn how to use them?
I share many of these feelings and worries, and I try my best to apply discernment and caution when I use any AI technology.
People are also thrilled by these new superpowers, both novices and graybeards alike. They are unleashing their imaginations to create things that were well beyond their reach only a few short months ago. Hobbyists are scratching itches with hand-built code and just having fun with games and toys. Professionals are accelerating their work, teaching themselves new skills, improving code quality and security, prototyping and testing ideas for effectively zero cost.
I also have some of the same optimism. This moment has opened up my career in ways I could have never anticipated. One of the reasons I got into computer science was because I knew I’d never stop learning. That’s as true today as it was in 1992, when I declared my CS major, and 1983, when I wrote my first BASIC program.
It’s dizzying to have so many opinions that span such a huge gamut. I’m constantly challenging assumptions and re-evaluating old positions. It’s exhausting when it’s not thrilling or terrifying.
We’ve only just begun.
In my first blog post, not much more than a year ago, I expressed similar feelings to those in this post. In AI terms, an entire era has passed. I don’t think my overall trajectory has changed, which is comforting with so much turbulence around me.
Over the past year, I’ve completed several projects using Claude Code. I know I’ll continue to learn how to use AI for coding and other work. I’ll continue to wrestle with all my conflicting thoughts and emotions, and continue to be overwhelmed by the scope and pace of its development.
I continue to believe that LLMs are overhyped. I’m also sure that we’ll be able to do more and more with them, and that they’ll continue to advance in coding capabilities.
I’ve certainly gotten my wish from all those years ago: I’ll always have more to learn.