How to really vibe code
Vibe coding became known as a synonym for “throwing a prompt at AI and seeing what happens”. In practice, this produces code that works once, under specific conditions, and breaks at the first change.
What actually works is different: using AI to accelerate every step of a process you already understand. Without the process, AI amplifies chaos. With the process, it amplifies speed.
This is the workflow I use.
1. Idea → Detailed requirements
The first mistake is going straight from “I have an idea” to the editor. Before writing any code, it’s worth spending time answering simple questions:
- What exactly does this feature need to do?
- What are the edge cases?
- What’s out of scope?
- Etc
When you approach AI with a vague requirement (“make an authentication system”), the result is generic. When you approach it with clear requirements (“email/password authentication, JWT with a refresh token, no OAuth for now”), the result is usable.
AI is good at filling gaps — the problem is that it fills them silently, with assumptions that might not be yours.
2. Studying references + defining the architecture
If you’ve never done anything similar, it’s worth studying how others solved the same problem before defining the architecture in order to understand the decisions that have already been validated.
Architecture defined after the code exists is much more expensive to change. Defined beforehand, with AI as a conversation partner (“given these requirements, which architectural approaches make sense and why?”), it becomes a productive conversation.
This step is where you decide: monolith or separate modules? Global or local state? REST API or something different? Etc
3. Studying and choosing technologies
With a clear architecture, choosing technology becomes more objective. You’re no longer choosing “what looks cool” — you’re choosing what solves the problem within the constraints you’ve defined.
Useful questions at this step:
- Is this library still actively maintained?
- Does it have what I need or will I need workarounds?
- Is the learning curve worth it given the project’s scope?
- Etc
AI helps a lot here — comparing options, understanding trade-offs, checking whether the library supports your specific use case. There’s no secret, if you don’t know just ask A.I. for some direction, and then study it.
4. Building the project structure
Monorepo or not. Folder structure. Linting, formatting, CI. TypeScript configuration.
It’s worth putting care into this. Fixing code conventions after there are 50 files is work nobody wants to do.
5. Creating tests
Tests before screens. Not necessarily pure TDD — but defining what each part of the system needs to do before building the interfaces helps separate logic from presentation from the beginning.
With tests defined, AI has a clear acceptance criterion when generating code. Instead of “generate a function that calculates a discount”, you provide: “generate a function that calculates a discount — the tests are here”. The result is more reliable.
6. Planning each screen
Before building any screen, it’s worth doing a quick outline:
- What data does this screen need?
- What actions can the user take?
- What happens in each state (loading, error, empty, data)?
- Is it worth creating this component to share across other screens?
- Etc
This plan can be a sketch on paper, a simple wireframe, or even a text description. It’s for you, and you’ll ask AI for it step by step. Remember not to overload it with information, which increases the chance of it failing.
7. Building each screen + shareable components
This is where AI really shines. With clear requirements, a defined architecture, chosen technologies, and planned screens, each prompt has enough context to generate code that fits into what already exists.
Shareable components emerge naturally as you build — when you realize you’re implementing the exact same thing for the third time, it might be time to extract it (YAGNI DRY KISS).
The central point of all this: AI doesn’t replace the process — it accelerates every step of it. The more context and clarity you bring to each prompt, the better the result. The process exists to create that context.
“Vibe coding” isn’t less rigorous — it’s just faster. Oh and remember to review each step.