Appearance
Systems Design & Project Management for Vibe Coding
A project manager walks into a vibe coding session and freezes. "Where do I put the requirements document? Where is the task board? How do I track dependencies?" The answer, once you see it, is obvious: you already have everything you need. The concepts did not disappear. They changed shape.
Every concept from traditional project management and systems design maps directly onto vibe coding. A requirements document becomes a system prompt. A task breakdown becomes a sequence of prompts. An architecture diagram becomes the context you feed the agent. Dependencies become the order you describe components. This is not a metaphor. This is a literal mapping, and once you internalize it, you can run a vibe-coded project with the same discipline you would bring to a traditional one, minus the parts that were always overhead.
What you'll learn
- Traditional PM concepts have direct vibe coding equivalents: specs become prompts, task breakdowns become prompt sequences, architecture becomes context
- Components in a system design become isolated conversations you have with the agent, each focused enough to produce a coherent output
- Dependencies determine the order you describe things, not a chart you maintain separately
- The project manager's mental model of scoping, sequencing, and dependency management is the same skill set, applied to a different medium
The problem: keeping a vibe-coded project coherent
The most common failure mode in vibe coding is not that the agent produces bad code. It produces decent code. The problem is coherence. You build the auth system on Tuesday. You build the dashboard on Wednesday. On Thursday they do not fit together because the agent had no memory of what it built on Tuesday, and you described the dashboard without mentioning the auth system's data contracts.
Traditional project management solved this problem decades ago. Requirements, scoping, task breakdowns, interface contracts, dependency graphs: these are tools for keeping multiple pieces of a system coherent when built by different people at different times. Vibe coding has exactly the same problem, at exactly the same scale. The difference is that instead of documents you hand to developers, you are handing context to an LLM.
Options & when to use each
| Approach | What it is good for | What it costs you | When to pick it |
|---|---|---|---|
| System prompt as spec | Giving the agent persistent rules, conventions, and constraints across every session | Must be kept current as the project evolves; stale specs produce wrong output | Every project. Start with one, update it as you learn |
| Task breakdown as prompt sequence | Breaking a feature into discrete, independently promptable pieces | Requires thinking through dependencies before you start typing | Features with 3+ distinct parts that depend on each other |
| Architecture diagram as context | Showing the agent how components relate before it writes any code | Diagram must be accurate; wrong context produces wrong architecture | Projects with multiple interacting services or complex data flow |
| Interface-first description | Defining data contracts before implementation so pieces fit together | Feels slow at first; you are describing what you want before building it | Any project where two components talk to each other |
| Session-by-session scoping | Keeping each agent session focused on one thing | Context switching between sessions; need a system for tracking what was done | Projects that span multiple days of work |
Build it: mapping PM concepts to vibe coding
Here is the mapping. Not as an analogy but as a literal translation guide. Every box on the left has a direct equivalent on the right.
Requirements become system prompts
A traditional requirements document says: "The system shall authenticate users via email and password. Failed attempts shall be rate-limited. Sessions shall expire after 24 hours."
A system prompt says the same thing, formatted for an agent:
markdown
# Auth System Requirements
- Email/password authentication with bcrypt hashing
- Rate limit: 5 failed attempts per email per 15 minutes
- Session expiry: 24 hours, enforced server-side
- Use the existing user model in @models/user.py
- Return JWT tokens, not session cookiesThe difference is not the content. It is the format and the audience. A requirements doc is written for a human developer who already knows your codebase conventions. A system prompt is written for an agent that needs the conventions spelled out or, better yet, pointed at with @ references.
Task breakdowns become prompt sequences
Traditional: "Task 1: Create the user model. Task 2: Build the registration endpoint. Task 3: Build the login endpoint. Task 4: Add rate limiting middleware."
Vibe coding, same breakdown, different medium:
Prompt 1: > Create a User model with email, password_hash, and created_at
fields. Use the same ORM patterns as @models/project.py.
Prompt 2: > Build a POST /register endpoint that creates a user. Validate
email format. Hash passwords with bcrypt. Return a JWT.
Prompt 3: > Build a POST /login endpoint. Verify password against stored
hash. Return JWT on success, 401 on failure. Use the User model
from @models/user.py.
Prompt 4: > Add rate limiting to the login endpoint: 5 attempts per email
per 15-minute window. Use Redis for the counter. Read the existing
Redis config at @config/redis.py.Each prompt depends on the output of the previous one. The dependency is in the order you ask things, not in a separate tracking document.
Architecture diagrams become context
In a traditional project, you draw boxes and arrows to show how components connect. In vibe coding, you describe the same relationships in the agent's context. Before you ask the agent to build anything, you tell it what connects to what:
markdown
# System Architecture
This project has four components:
1. **API Gateway** (FastAPI, port 8000): receives all client traffic,
routes to services, handles auth
2. **User Service** (internal, port 8001): manages user accounts,
authentication, profiles
3. **Task Service** (internal, port 8002): manages tasks, projects,
assignments
4. **PostgreSQL** (port 5432): single database, separate schemas per service
Data flow: Client -> API Gateway -> User Service/Task Service -> PostgreSQL
Auth flow: Client -> API Gateway -> User Service (validate JWT) -> forward to serviceThe agent now has a structural understanding of the system before it writes a single line of code. It knows not to put user logic in the task service. It knows the database is shared but schemas are separate. This is exactly what an architecture diagram does for a human team.
Dependencies become prompt order
In traditional PM, you maintain a dependency graph. Task C cannot start until Tasks A and B are complete because C depends on interfaces defined in both. In vibe coding, the dependency graph is the order you issue prompts. You do not need a separate tracking artifact because the agent cannot build something that depends on code that does not exist yet. You describe the foundation first, then the things that sit on top of it.
The discipline is the same: think through what depends on what before you start. The difference is that you enforce it by the order you type, not by a chart you update.
What goes wrong
| Mistake | How you notice it | The fix |
|---|---|---|
| Describing a component without telling the agent what it connects to | The agent builds an isolated piece that works in isolation but breaks when wired into the rest of the system | Feed the architecture context first, before the implementation prompt. The agent needs to know the neighbors before it builds the house |
| Writing a system prompt once and never updating it | The agent follows old conventions that you changed three sessions ago. Output drifts from current codebase patterns | Treat CLAUDE.md as a living document. Update it when conventions change, same as you would update a project wiki |
| Issuing prompts out of dependency order | The agent invents interfaces or data shapes because the upstream component does not exist yet. Later, the real upstream has different contracts | Build foundations first. If Component B depends on Component A, build A before you ask for B |
| Letting a single session grow too large | Context window fills up, the agent loses track of early decisions, output becomes inconsistent or contradictory | Scope each session to one component or one coherent piece. Start fresh sessions for new components, feeding only the relevant context |
| Not defining data contracts between components | Two components built in separate sessions use different field names or data shapes for the same concept. They do not fit together | Describe the interface before either component. "The user object passed between services has these fields: id, email, name, role" |
Confirm it worked
Take a feature you have already built, one with at least two components that talk to each other. Now describe it as a vibe coding project using the mapping above. Write a system prompt that captures the requirements. Break it into a prompt sequence. Describe the data contract between components. Feed the whole thing to Claude Code (or your preferred agent) and ask it to rebuild the feature from scratch.
If the rebuilt version works and the components fit together on the first try, the mapping holds. If the agent produces two pieces that do not connect, check whether you described the data contract clearly enough before asking for implementation.
Then try the reverse: take a project you have been meaning to build, scope it using traditional PM concepts, translate the whole plan into vibe coding equivalents using the mapping above, and build it. The test is not whether the plan looks good on paper. The test is whether the resulting system works.
Next: How LLMs Like to Code -- the code patterns that make an LLM produce consistent, reliable output instead of creative surprises.