17 May 2026·Engineering·5 min read · 970 words

Vibe coding Interval Coach.

4 hours from blank repository to deployed app, and the process that actually got it there.

I watch my running coach at hill intervals. She holds her phone the whole session, tapping split times, keeping track of who's on which lap. A few weeks ago I thought: I could build that. Better, maybe. And I could do it with vibe coding.

So I did. 4 hours, blank repository to deployed app. This is what that felt like.

Interval Coach main session view showing athlete list, lap counts, and split times
Fig. 1 — The finished app. The goal was to replace the coach's phone.

Before the first commit

I've done enough projects to know that the costly mistakes happen before you start coding. You have a shape of the idea but it has gaps: assumptions you haven't examined, constraints you haven't named.

My first tool wasn't Claude Code. It was ChatGPT, and I didn't use it to generate code. I used it to interview me. I'd describe part of the idea and ask it to keep asking me questions. You fill in blanks you didn't know were blank.

Once the idea was solid, I had ChatGPT generate a structured prompt summarising what I wanted to build. I took that to Claude Code and asked it to produce 3 things: a project planner, a task list, and a "getting started" doc written as if explaining the project to a junior developer.

That last one sounds like overhead. It isn't. Writing things out at junior developer level forces implicit assumptions to become explicit before they're baked into code. The reason I'd never done this before is that maintaining that kind of doc is tedious. With an LLM maintaining it on every commit, it's nearly free.

I read through the docs, confirmed the scope felt right, and only then started coding.

"Two tools, two roles: ChatGPT for thinking out loud. Claude Code for execution."

The split was partly deliberate to save cost, but also because they suit different modes of thinking. ChatGPT is conversational. Claude Code feels precise, like giving instructions to something that will follow them exactly.

Texture of the work

I'd estimate I directly wrote about 5% of the code. Probably less. But that number isn't the point. The texture of the experience is.

In the past, vibe coding sessions followed a familiar pattern: prompt, dislike what I see, rephrase, try again. Or: get something close, massage it a few times, eventually land somewhere acceptable. This time was different. Not frictionless. There was still massaging. But the ratio shifted. More checkpoints where I thought wow, it kept working, fewer moments of flushing and restarting.

I don't know how much of that is LLM improvement and how much is me getting better at leading development with my prompts. Probably both.

The first generated feature wasn't what I'd described. The plan had been read differently than I intended. I didn't throw it away. That felt new. I used the wrong output as a base and trimmed from it. That reframe helped.

"The thinking doesn't go away. It just gets applied differently."

Vue 3 was unfamiliar territory. I'd touched Vue 2 years ago and moved on. The principles from React transferred cleanly. I wasn't fighting the framework.

Small disciplines

A few things that made the session smoother than I expected.

CLAUDE.md as a live runbook

I used it less as a style guide and more as a set of "when X, do Y" rules. When the output wasn't right, I'd update the instructions rather than correcting the result inline. That way the fix propagates to future sessions instead of needing to be re-explained. I kept the file deliberately lean. It's sent with every conversation, so bloat quietly increases cost.

Offload style enforcement

I have an npm run check script that runs ESLint, type checking, and formatting together. Claude doesn't spend tokens trying to get formatting right; I just run the check after each coding pass. Faster iteration, cleaner separation.

Deploy early and rough

!

Ship v0.1 before it's ready. I deployed before it was complete, specifically to shake out the CI/CD pipeline before features stacked up. Adjusting deployment is much easier when there's almost nothing to break.

Tests as a later problem

This is a small project. Tests will earn their place later, when there's more to protect. Not yet.

Stay in the room

There's more idle time in a vibe coding session than I expected. The generation runs, and suddenly there are 30 seconds with nothing to do. The pull toward the phone is real.

I kept a rule: don't drift while something is running. I used the wait to read what was being generated, think about the next prompt, or flag something that looked wrong. The session stayed coherent in a way it wouldn't have if I'd kept stepping out.

Without an LLM, the same project could have stretched considerably longer, or I'd have scoped it down to something safer. I'd have used frameworks I already know instead of experimenting with Vue. There'd be more resistance: not inability, but inertia. Vibe coding lowered that bar enough that I actually did it.

The app might never get used at a real training session. That's fine. The goal was to take an idea that had been sitting in the back of my head and make it real. That happened.

What it actually is

This isn't a pitch for vibe coding. It's a log of what one session actually felt like: the hand-holding, the massaging, the moment the first feature came out wrong.

There's a process here. It's not "tell the robot what to think." It's a workflow with deliberate steps, feedback loops, and judgment calls about when to correct output versus when to update the instructions.

That's the part that took me 4 hours, and that's the part I found interesting.