Skip to content

Breaking Work Into Bite-Sized Pieces ​

The most common mistake in vibe coding is not a bad prompt. It is a prompt that tries to do too much.

"Build a SaaS dashboard with user management, subscription billing, analytics, a report builder, email notifications, and an admin panel." This prompt is not going to work. Not because the agent is not capable of building those features — it is. But because a prompt this large has too many ambiguous decisions, too many edge cases, and too much surface area for the agent to get lost. The agent will build something. It will look complete. But it will not be what you wanted, and you will spend more time debugging it than you would have spent building it in smaller pieces.

The skill you need is decomposition: the ability to take a product vision and break it into a sequence of prompts where each prompt builds on the last, each one is small enough for the agent to handle reliably, and together they add up to the complete product.

What you'll learn

  • An agent can build a feature in one prompt. It cannot build a product in one prompt. The gap between a feature and a product is decomposition
  • Decomposition is not about making prompts shorter — it is about ordering them so each prompt has a stable foundation to build on, and no prompt tries to build something that depends on a feature that does not exist yet
  • Each decomposed task should be small enough that the agent can complete it in one session without losing context, and self-contained enough that it can be reviewed and committed independently
  • A 15-prompt sequence that produces a working product is faster than one giant prompt that produces a broken one — not because the agent is faster, but because you spend zero time debugging what the agent invented

The problem: the one-prompt product ​

Imagine you are building a customer support ticketing system. The vision: customers submit tickets, support agents claim and resolve them, managers see a dashboard of ticket volume and response times, and everything sends email notifications at the right moments.

If you type that vision as a single prompt, here is what happens:

  1. The agent scaffolds the whole thing — database, routes, templates, email integration.
  2. The database schema looks reasonable but misses the "claimed by" relationship between tickets and agents.
  3. The dashboard queries aggregate over the wrong fields because the agent did not know which metrics mattered.
  4. The email notifications fire on every status change, including ones where you definitely do not want an email.
  5. The whole thing is 2,000 lines of code across 15 files, and you cannot tell which parts are correct and which are not without reading all of it.

You now have a "complete" system that is 70% correct and 30% subtly wrong, and finding the 30% takes longer than building it from scratch in pieces. The one-prompt approach failed not because the agent was bad, but because the prompt asked the agent to make too many decisions without feedback.

Options & when to use each ​

ApproachWhat it is good forWhat it costs youWhen to pick it
One giant promptPrototypes you will throw away after the demoHigh debugging cost; unpredictable output; no intermediate checkpointsDemos and throwaway experiments only — never for code you plan to keep
Decomposed by feature (ticketing, then dashboard, then notifications)Products where features are largely independent of each otherFeatures built in isolation may not connect cleanly; the agent may use different patterns for each featureProducts where each feature has its own database tables and UI pages
Decomposed by layer (database first, then API, then UI, then integrations)Products where the data model is the foundation everything else builds onFrontend work is blocked until the API is done; hard to demo progress earlyData-heavy applications where getting the schema right is the hardest part
Decomposed by user story ("as a customer, I can submit a ticket")Products where the user flow is the organizing principle; each story delivers a complete, testable sliceStories may overlap; agent may duplicate work across storiesCustomer-facing products where the UX is the hardest part to get right

For vibe coding, decomposing by feature is the most natural fit. The agent thinks in features — "add a ticket submission form" is a coherent unit of work. Layer-based decomposition can work for backend-heavy projects, but it creates a long gap between "the database exists" and "something a user can see." User-story decomposition is ideal when the frontend experience matters most, but it risks duplication if the agent builds similar things in different stories.

The real answer: start with feature decomposition, but order the features by their dependencies. Build the foundation features first (the ones other features depend on), then the dependent features. This gives you the best of both worlds: each prompt is a self-contained feature, and no prompt tries to build on something that does not exist yet.

Build it: decomposing a SaaS dashboard ​

We will decompose "build a SaaS dashboard" into a sequence of prompts. The vision: a dashboard that shows key metrics (users, revenue, active subscriptions), with filters by date range, and a settings page for configuring which metrics appear.

Step 1: draw the dependency map ​

Before writing any prompts, list the features and their dependencies:

Feature              Depends on
─────────────────────────────────
1. Project scaffold     (nothing)
2. Database schema      Project scaffold
3. User model + seed    Database schema
4. Auth (login/logout)  User model
5. Dashboard layout     Project scaffold
6. Metrics API          Database schema, Auth
7. Dashboard widgets    Dashboard layout, Metrics API
8. Date filters         Metrics API
9. Settings page        Dashboard layout, Auth
10. CSV export           Metrics API

This map tells you the order: you cannot build the metrics API before the database schema exists, and you cannot build the dashboard widgets before both the layout and the metrics API are done.

Step 2: turn each feature into a prompt ​

Now write one prompt per feature, in dependency order. Each prompt assumes the previous prompts have been completed and committed.

Prompt 1: Project scaffold

Create a new FastAPI project called "saas-dashboard" using the conventions in the
parent directory's template. Set up the project structure: app factory, configuration,
middleware, and a health check endpoint at /health. Use Python 3.12 and uv.
Write a CLAUDE.md with the stack and conventions.

Prompt 2: Database schema

Add SQLite database support to the project. Create the schema file at data/schema.sql
with tables for: users (id, email, password_hash, created_at), subscriptions
(id, user_id, plan, status, started_at, revenue), and events (id, user_id, event_type,
created_at). Add database initialization to the app factory. Seed the database with
10 test users, 3 subscription plans, and 3 months of event data.

Prompt 3: Auth

Read the user model in data/schema.sql and add login/logout to the application.
Routes: GET /login (login form), POST /login (authenticate), GET /logout (clear session).
Use session-based auth with Flask-style session cookies. Password hashing with bcrypt.
Protect future routes with a `@login_required` decorator. Add auth to CLAUDE.md
conventions.

Prompt 4: Dashboard layout

Create the main dashboard page at GET /dashboard. It requires authentication.
For now, the page is a layout shell: a sidebar with navigation links (Dashboard,
Settings), a top bar with the user's email and a logout button, and a main content
area that is empty. Use Jinja2 templates. The layout should look clean and professional
with Tailwind CSS. The spec is at @specs/dashboard-layout.md.

Prompt 5: Metrics API

Add a metrics API endpoint at GET /api/metrics. It returns JSON with:
- total_users: count from users table
- active_subscriptions: count of subscriptions with status='active'
- monthly_revenue: sum of revenue from subscriptions where started_at is in the
  current month
- events_today: count of events created today
Use raw SQL queries, no ORM. The endpoint requires authentication. Follow the error
response format in CLAUDE.md.

Prompt 6: Dashboard widgets

Read the metrics API at @app/dashboard/metrics.py and the dashboard layout at
@app/dashboard/routes.py. Add widget cards to the dashboard page that display
the four metrics from the API. Each widget shows: the metric name, the current value,
and a trend indicator (up arrow if the value increased from last month, down arrow
if it decreased). Fetch the data from /api/metrics and render server-side using Jinja2.

Prompt 7: Date filters

Add date range filtering to the metrics API. The endpoint /api/metrics accepts
optional query parameters: start_date and end_date (format YYYY-MM-DD). When
provided, all metrics are filtered to that date range. Update the dashboard page
to include a date range picker (two date inputs with a submit button). When the
user selects a range and submits, the dashboard reloads with filtered metrics.

Prompt 8: Settings page

Add a settings page at GET /settings (requires auth). The page shows checkboxes
for each of the four metric widgets, defaulting to all checked. When the user
unchecks a widget and saves, that widget is hidden from the dashboard. Store
preferences in a new user_settings table (user_id, setting_key, setting_value).
Update the dashboard page to read and respect these settings.

Prompt 9: CSV export

Add a CSV export feature to the dashboard. A "Download CSV" button on the dashboard
page triggers a download of the current metrics as a CSV file. The endpoint is
GET /api/metrics/csv?start_date=...&end_date=... and returns a CSV with columns:
Metric, Current Value, Previous Value, Change. Respect the current date filter.
Use Python's csv module for safe CSV generation.

That is nine prompts. Each one is a self-contained unit of work the agent can handle in one session. Each one builds on the previous ones. Each one has a clear, reviewable output.

Step 3: estimate what fits in one prompt ​

The most common decomposition mistake is making prompts too big. A prompt that takes the agent longer than 15-20 minutes to execute will cause problems: the agent loses context, the implementation quality drops, and you lose the ability to review midway through.

Here is a rough sizing guide:

Prompt sizeWhat fitsSignal it is too big
Small (5-10 min)One route, one template, one database tableThe agent writes more than 200 lines of new code
Medium (10-20 min)A complete feature: multiple routes, a few templates, database changesThe agent touches more than 10 files
Large (risky)Multiple features or an entire subsystemThe agent opens files it should not be touching; implementation quality varies across the feature

If a prompt would produce more than ~300 lines of new code, it is too big. Split it. The split should happen at a natural boundary — finish the API before starting the UI that consumes it, finish the data model before starting the features that use it.

Step 4: the real 15-prompt decomposition ​

Here is a complete 15-prompt decomposition for "build a SaaS dashboard with user management, subscription billing, analytics, and admin panel." This is what a real product decomposition looks like:

  1. Project scaffold + CLAUDE.md
  2. Database schema (users, subscriptions, events, settings)
  3. Seed data (test users, plans, historical data)
  4. Auth system (register, login, logout, session management)
  5. User profile page (view/edit profile, change password)
  6. Admin user management (list users, disable accounts, view activity)
  7. Subscription plans (define plans, pricing, features per plan)
  8. Billing integration stub (subscription creation, status tracking — Stripe comes later)
  9. Dashboard shell (layout, navigation, empty widget grid)
  10. Core metrics API (users, revenue, subscriptions, churn)
  11. Dashboard widgets (metric cards with trends and sparklines)
  12. Date range and segment filters (by plan, by status, by date)
  13. Analytics page (event funnel, conversion rates, user activity timeline)
  14. CSV and PDF export (current view, scheduled reports placeholder)
  15. Admin system settings (configuration, feature flags, maintenance mode)

Every prompt assumes the previous prompts are done. Every prompt produces a reviewable, committable chunk. The whole sequence, executed in order, builds the complete product. No single prompt is overwhelming for the agent, and no prompt asks the agent to guess about something that has not been built yet.

What goes wrong ​

MistakeHow you notice itThe fix
Prompts that depend on features not yet builtThe agent invents a stub for the dependency (a fake user model, a placeholder API), and later prompts build on the stub instead of the real thingOrder prompts by dependency. Build the foundation first (database, auth), then the features that depend on it. Never ask the agent to build something that consumes an API you have not built yet
Prompts that are too smallEach prompt is one function or one template. You spend more time reviewing and committing than the agent spends coding. Your prompt list is 40 items longCombine adjacent, non-dependent tasks. "Add the login route" and "add the login template" are one prompt: "Add login (route + template)"
Skipping the seed data stepEvery feature prompt starts with "the database is empty, so here are some test records the agent invented." The test data is inconsistent across featuresAdd a seed data step early (prompt 3 in any sequence). Every feature after that works with realistic data
Not committing between promptsPrompt 5 introduces a bug. You keep going. By prompt 9, you have 4 prompts of code built on a broken foundation, and you cannot isolate which change caused the problemCommit after every prompt. The git workflow is the safety net — one prompt, one commit, one reviewable unit
Reordering mid-streamYou realize after prompt 6 that prompt 4 should have been different, so you redo prompt 4. But prompts 5 and 6 were built on the old version and now do not workIf you need to redo an earlier prompt, you must redo all subsequent prompts that depend on it. This is why the dependency map matters — it shows you the blast radius of a change
The agent builds the "full" version instead of the staged versionYou ask for a subscription billing stub, and the agent builds a full Stripe integration because "stub" means "incomplete" to the agent and the agent does not ship incomplete codeBe explicit: "This is a stub. It stores subscription data but does not connect to a payment processor. Hardcode a test plan ID." The word "stub" alone is not enough

Confirm it worked ​

Take a product idea you have — something you might actually build. Write down the features. Draw the dependency map. Turn each feature into a prompt, ordered by dependency. Count the prompts. If your product is 15 prompts or fewer, you have a buildable plan.

Execute the first three prompts in order. After each prompt, review the output and commit. After prompt 3, ask yourself: does the agent have everything it needs to build prompt 4? If yes, your decomposition is working. If the agent had to invent a dependency, your ordering is wrong — move the missing dependency earlier in the sequence.

The real test is the one you cannot do in a lesson: six months from now, when you have a product idea and you instinctively draw the dependency map before you type a single prompt. That instinct — "what does this depend on, and what depends on this?" — is the difference between building a feature and building a system.

Next: Git Workflows for Vibe Coding