Vibe Coding
You: "Make a React component that shows user notifications"
AI: *generates component*
You: "Add read/unread toggle"
AI: *updates code*
You: "Use Tailwind instead"
AI: *refactors*
Fast. No requirements doc. Context lives in the chat window and dies when you close it.
Spec-Driven
# notification-feature.md
## Requirements
- Notifications in descending chronological order
- Read/unread toggle
- Real-time updates via WebSocket
- Filter by type (mention, like, follow)
## Acceptance Criteria
- [ ] Unread badge updates in real-time
- [ ] Click marks as read
- [ ] Works at 320px width
- [ ] Keyboard navigable
Slower to start. Context persists in files. Agent reads the spec, builds it, checks criteria.
Tradeoffs
| Vibe | Spec-Driven | |
|---|---|---|
| First prototype | Minutes | Hours (includes design) |
| Context | Lost when chat closes | Lives in repo |
| Team handoff | "Read the chat history" | Reviewable specs |
| Exploration | Great | Too much overhead |
| Maintenance | No record of intent | Specs document "why" |
When to Use Each
Vibe coding: prototypes, learning a new framework, scripts under 200 lines, debugging, anything you'd be fine rewriting from scratch.
Spec-driven: production features, team projects, multi-file changes, code you'll maintain for months, anything that needs an audit trail.
The Hybrid Pattern
1. Vibe code a prototype — get something working fast
2. Extract into a spec — document what worked
3. Spec-driven rebuild — agent generates clean implementation
4. Vibe code refinements — tweak styles, optimize
Most teams land here. Speed during exploration, structure during implementation.