Back to browse
Why I Stopped Writing Boilerplate: A Vibe Coding Workflow
VIBE-CODING EASY 4 min
Here's a thing I had to unlearn: that writing every line of code myself was somehow more "real" than describing what I want and letting AI write it.
It's not. The end result is the same. And one of those approaches ships side projects; the other one has me fiddling with TypeScript generics at 11pm on a Tuesday.
Let me show you what I actually do.
The split
I divide every project into two kinds of code. Stuff I care about: core logic, anything tricky, anything that'll bite me later if it's wrong. Auth flows. Data transformations. Weird business rules. Stuff I don't care about: CRUD endpoints, form validation, database migrations, CSS, config boilerplate, test scaffolding, error handling. I write the first category by hand or at least read every line. For the second category I describe what I want, let AI generate it, skim it for weirdness, and move on. This split used to feel lazy. Then I tracked my time for a month and realized I was spending 60% of my coding time on code I didn't care about.The workflow
- Start with the data model. Not the code. Before I write anything, I write out (in comments or a doc) what the database tables are and how they relate. This is the part I don't outsource because getting this wrong cascades into everything.
- Generate the boring scaffolding. With Claude Code or Cursor, I describe the stack and the tables. I ask for migrations, basic CRUD routes, and the bare frontend forms. This takes maybe 20 minutes and it's usually 80% of what I'd have written by hand.
- Read the output carefully. This is the step people skip. Generated code often has subtle problems: hardcoded values that should be configs, missing edge cases, stuff that "works" but isn't what you asked for. I read every file end to end before I trust it.
- Write the interesting parts myself. Whatever the project is actually about, I type out. Because at this stage I need to think, and typing is how I think.
- Let AI do the cleanup. Tests, error messages, CSS tweaks, README. All of that is chore work. Describe it, generate it, move on.
What this looks like in practice
Last week I built a little tool to track my reading habits. Books, page counts, date finished, a small stats page.- Database + migrations: generated (10 min)
- Express routes for add/edit/delete books: generated (5 min)
- Frontend form with htmx: generated (10 min)
- The actual stats calculation (reading streaks, pages-per-day rolling average): wrote myself (45 min)
- Tests: generated, then edited (15 min)
- Deploy config: generated (5 min)
The mistake I kept making early on
I kept asking for too much at once. "Build me an app that does X, Y, and Z with user auth and a dashboard" produces garbage. Or rather, it produces code that sort of works but has weird architecture decisions baked in that you have to unwind. Now I go in pieces. "Write the database schema for a book tracker with title, author, pages, started_at, finished_at." That's one request. Then "write the migration for this schema." Then "write routes to add and list books." Each piece is small enough to verify. Small prompts, small files, small commits. The vibe coding doesn't work when you try to one-shot an entire app.Where I still write everything by hand
- Anything with security implications. Auth, session management, anything touching user passwords or tokens. I'll use AI to explain libraries but I want to understand and own that code.
- Anything weird or specific to my project. The stats calculation above is a good example. It's the actual point of the thing, so I need to think about it.
- Code I'm going to maintain for years. Generated code is fine for prototypes but for long-term stuff I want to know every line.