When Vibe Coding Is Actually Fine
March 7, 2026
I’ve written a lot about why vibe coding breaks at scale. And I stand by it. But I also vibe code every single day, and I think you should too — in the right contexts.
The problem isn’t vibe coding. The problem is vibe coding everything.
Prototyping and exploration
When I don’t know what I want yet, a spec is premature. You can’t specify the unknown.
Last month I was exploring a new layout for the Octopus Coder homepage. I didn’t have a design. I didn’t know if I wanted a grid, a list, or a featured-post hero. I opened Claude Code and said: “Try a layout with a featured post at the top, then a 2-column grid below.”
Looked at it. “Actually, make the featured post full-width with the description beside the image.” Looked again. “Drop the image. Just title and description, larger text.” Three iterations and I had a direction.
Writing a spec for that would have been absurd. I was finding the design, not executing one. Conversational iteration is exactly the right tool for exploration.
The key: once I knew what I wanted, I wrote a spec for the real implementation. The vibe coding session gave me clarity. The spec gave me clean code.
Learning a new framework
When I started building Triumfit’s cross-platform features with React Native, I didn’t know the navigation patterns. I didn’t know how the gesture system worked. I didn’t know the right abstractions for shared components.
So I vibe coded. “Show me how to set up a tab navigator with these four screens.” “How does the gesture handler work for swipe-to-delete?” “What’s the pattern for sharing styles between iOS and Android?”
This is conversation. It’s supposed to be conversational. The back-and-forth is the point. I’m learning, not building. The agent is a tutor, not a contractor.
Speccing a learning session would be like writing a lesson plan for a conversation with a friend. Technically possible. Completely wrong.
One-off scripts
Last week I needed to rename 200 image files from a photo_001.jpg convention to scouter-hero-001.webp. I opened Claude Code and said: “Write a script that renames all files in this directory from photo_XXX.jpg to scouter-hero-XXX.webp and converts them to webp.”
Done. Ran it. Deleted the script.
Writing a spec for a throwaway script is overhead with zero return. The script ran once. There’s no codebase to keep consistent. There’s no architecture to protect. There’s nobody reviewing the diff.
The heuristic: if the output is disposable, skip the spec.
Small personal tools
I have a little script that checks if any of my Railway deployments are down and sends me a Slack message. I vibe coded the whole thing in 15 minutes. It’s about 40 lines. It works.
Is the code clean? Probably not. Are there edge cases? Definitely. Do I care? No. It’s a personal utility. The cost of it being messy is zero. The cost of speccing it out would have been 10 minutes of overhead on a 15-minute task.
Not every piece of code is a product. Some code is a tool that you use and nobody else sees. Spec that code and you’re optimizing for the wrong thing.
Bug investigation
Something’s broken. You don’t know what. This is inherently conversational.
“The Lucid export button isn’t working. The PDF generates but it’s empty. Can you check what renderEntry() is returning when the entry has images?”
The agent investigates. Reports back. You ask a follow-up. It digs deeper. Eventually you find the issue — the image URLs aren’t resolving in the PDF renderer.
Now you know the problem. Now you can write a spec: “In src/features/export/pdfExport.ts, convert image URLs to base64 before passing them to the PDF renderer. Use the existing fetchAsBase64() utility from src/utils/images.ts. Don’t change the rendering logic for text-only entries.”
Investigation is vibe coding. The fix is spec coding. Trying to spec an investigation is like writing a spec for “find out why this is broken.” You don’t know enough yet to be specific.
Brainstorming architecture
When I was planning how Scouter’s real-time features would work, I had a conversation with Claude Code about the tradeoffs between WebSockets and Server-Sent Events. I wasn’t building anything. I was thinking out loud with an assistant.
“What are the tradeoffs of SSE vs WebSockets for one-way real-time updates?” “How does that change if I need bidirectional communication later?” “Show me the connection lifecycle for both.”
This is research, not execution. Specs are for execution.
The anti-pattern: over-speccing trivial work
I’ve seen people take the spec coding methodology and apply it to everything. Changing a button color gets a spec. Fixing a typo gets a spec. Adding a console.log for debugging gets a spec.
This is the equal and opposite mistake from vibe coding everything. Overhead should be proportional to risk. A button color change has near-zero risk. A database migration has high risk. Spec the migration. Just change the button.
My rule of thumb:
- Under 10 lines of output, low risk: Just tell the agent what to do.
- 10–50 lines, moderate risk: Brief scope. File paths and constraints.
- 50+ lines, touches multiple files, or affects data: Full spec.
Most of my daily work falls in the middle category. A brief scope isn’t a formal spec — it’s two or three sentences with a file path and a constraint. That’s enough for most focused tasks.
The actual problem
The argument isn’t “vibe coding bad, spec coding good.” The argument is about defaults.
If your default is vibe coding and you spec the exceptions, you’ll end up vibe coding things that should have been specced. The drift is always toward conversational because it’s easier to start. By the time you realize the task needed a spec, you’re 10 minutes into a conversation that’s going sideways.
If your default is spec coding and you vibe the exceptions, the worst case is you spend 90 seconds writing a spec for something that didn’t need one. That’s a rounding error.
Default to specs. Vibe code when the context calls for it. That’s the whole framework.
For the full comparison between the two approaches, see vibe coding vs spec coding. And if you want to understand the methodology that sits on top of this — the workflow that makes it all work across multiple projects — start with the spec coding complete guide.
The short version
Vibe code when you’re exploring, learning, investigating, or building something disposable. Spec code when you’re building something that ships, something that needs to be right, or something that runs while you’re working on something else.
The tool isn’t the problem. Using the wrong tool for the job is the problem.