How to Build Apps with Claude Code: A Complete Workflow Guide
The Problem
I asked Claude Code to build a complete feature from scratch. I gave it a detailed PRD with all the requirements. It started coding immediately, created dozens of files, and after two hours of work, the codebase was a mess of half-finished components, broken imports, and functionality that didn’t match the requirements.
This pattern repeated every time I tried to “one-shot” an application:
PRD → Claude generates 50+ files → 30% work → Broken tests → Context dilution → Lost requirements → Give up and start overThe Reddit community confirmed I wasn’t alone:
- Context dilution: After 20 files, Claude forgets earlier decisions- No direction: Generates code without architectural consistency- No feedback loop: No opportunity to course-correct mid-way- Overconfident output: Produces broken code confidentlyThe key insight from experienced users: Treat Claude Code like a mid-level engineer who is onboarding. Give incremental tasks. Break PRDs into tiny vertical slices. Iterate through prototype, architecture, implementation, test, and debug cycles.
The Solution: Incremental Development Workflow
The correct approach looks like this:
PRD → Phase 0: Setup/Specs → Phase 1: Foundation → Phase 2: Slices → Phase 3: Iterate → Working application
Each phase builds on the previous. Each step is small enough to verify.Phase 0: Setup and Specification
Before writing any code, create a CLAUDE.md file with architecture decisions and constraints:
# Project Architecture
## Tech Stack- Backend: Python Flask with SQLAlchemy- Frontend: HTML + Alpine.js + Tailwind (no CDN, local assets)- Database: PostgreSQL
## Constraints- No remote CDN dependencies- All user input must be validated with Zod schemas- Maximum file size: 400 lines
## Key Decisions- Use repository pattern for database access- API responses follow standard format with success/error fields- All state changes go through dedicated hooksThis specification serves as a contract. Claude references it throughout development. When it forgets context, the spec keeps it on track.
Phase 1: Foundation Layer
Build the foundation first. No features yet:
1. Project structure (directories, initial files)2. Database schema and migrations3. Base configuration files4. Core utilities and helpers5. Authentication/authorization frameworkHere’s how I prompt this phase:
Create the foundation layer for this project:
1. Set up project structure with these directories: - /backend (Flask app) - /frontend (static assets) - /migrations (database migrations)
2. Create base configuration: - config.py with environment variable loading - requirements.txt with pinned versions
3. Define database schema for User and Post models
4. Create base repository pattern with CRUD operations
DO NOT implement any features yet. Only the foundation.I verify each foundation piece before moving forward:
[ ] Project structure matches spec[ ] Config loads environment variables correctly[ ] Database models match schema[ ] Base repository has all CRUD methods[ ] Tests pass for foundation codePhase 2: Vertical Slices
Instead of building all features horizontally (all models, then all routes, then all views), build vertical slices. One complete feature at a time:
WRONG (Horizontal): Model A → Model B → Model C → Route A → Route B → Route C → View A → View B → View C
CORRECT (Vertical): Feature A (Model + Route + View + Test) → Feature B (Model + Route + View + Test) → Feature C (Model + Route + View + Test)Each slice is a complete, working piece:
Feature: User Registration
Slice 1: Registration endpoint - Create /register route - Add input validation - Test registration success - Test validation failures
Slice 2: User creation - Add user repository method - Hash passwords - Test user creation - Test duplicate email handling
Slice 3: Registration UI - Create registration form - Add Alpine.js validation - Connect to endpoint - Test UI interactions
Each slice ends with working, tested code.I never let Claude start a new slice until the current one works:
- Feature works end-to-end- Tests pass (unit + integration)- No console errors- Code matches CLAUDE.md constraints- Linter shows no errorsPhase 3: Iteration Cycles
The iteration cycle is where real development happens:
┌─────────────────────────────────────────────────────────────────┐│ ││ ┌──────────┐ ┌──────────┐ ┌──────────┐ ││ │ Prototype │────▶│ Arch/Design│────▶│ Implement │ ││ └──────────┘ └──────────┘ └──────────┘ ││ ▲ │ ││ │ ▼ ││ │ ┌──────────┐ ││ │ │ Test │ ││ │ └──────────┘ ││ │ │ ││ │ ▼ ││ │ ┌──────────┐ ││ └────────────────────────────│ Debug │ ││ └──────────┘ ││ │└─────────────────────────────────────────────────────────────────┘Prototype: Quick implementation to validate approach
Create a minimal prototype for [feature].Focus on the happy path only.Don't worry about edge cases or error handling yet.Goal: Prove this approach works.Architecture/Design: Refine for production
Review the prototype. Refine the architecture:- Add proper error handling- Consider edge cases- Apply design patterns from CLAUDE.md- Ensure consistency with existing codeImplementation: Build the real version
Implement [feature] following the refined architecture.Reference CLAUDE.md for constraints.Write tests as you implement.Test: Verify everything works
Run all tests for [feature].Report any failures.If failures exist, list them clearly.Debug: Fix issues and loop back
Analyze the test failures:1. Root cause of each failure2. Proposed fix for each3. Impact on other code
Fix issues and run tests again.This cycle repeats until the feature is complete. Each iteration is small enough to understand and verify.
Why This Matters
The compound effect of good process is dramatic:
BAD PROCESS: Time wasted on broken code: 4 hours Time fixing context issues: 2 hours Time debugging architectural mess: 3 hours Total: 9 hours, may or may not work
GOOD PROCESS: Phase 0 (Specs): 30 minutes Phase 1 (Foundation): 1 hour Phase 2 (Slices): 3 hours Phase 3 (Iterations): 2 hours Total: 6.5 hours, working applicationBeyond time savings, the result is:
+ Consistent architecture across all features+ Every piece has tests+ No context dilution (small steps)+ Clear progress tracking+ Easy to review (small commits)+ Easy to rollback (small changes)Common Mistakes to Avoid
I’ve made every mistake on this list:
Mistake 1: Skipping the specification phase
WRONG:"Just build me a todo app with users and tasks"
RIGHT:"First, let me create a CLAUDE.md with architecture decisions.Then we'll build the foundation layer.Then we'll implement features one at a time."Mistake 2: Asking for complete features
WRONG:"Implement the entire user authentication system with registration,login, password reset, and email verification"
RIGHT:"Let's break this into slices:Slice 1: Registration endpoint onlySlice 2: Login endpoint onlySlice 3: Password reset only..."Mistake 3: No verification between steps
WRONG:Claude: "I've created the user model"Me: "Great, now add the post model"[Claude creates post model without testing user model]
RIGHT:Claude: "I've created the user model"Me: "Let me verify. [runs tests, checks schema]Found an issue with the email validation.Fix this before we move to post model."Mistake 4: Horizontal instead of vertical development
WRONG:"Create all the models first: User, Post, Comment, Tag, Category"[20 minutes later, 5 models, no tests, no working functionality]
RIGHT:"Create the User model with full CRUD and tests"[verify it works]"Now create the Post model with full CRUD and tests"[verify it works]"Create the relationship between User and Post"[verify it works]Mistake 5: Letting Claude run too long
WRONG:[One prompt generates 30 files over 45 minutes]Result: Context dilution, forgotten requirements, broken code
RIGHT:[Each prompt generates 1-3 files][Verify between each prompt][Maximum 10-15 minutes per prompt]Result: Consistent quality, no lost contextEffective Task Breakdown
Here’s a template I use for breaking down features:
Feature: [Name]
Phase 0 Checklist:[ ] CLAUDE.md created with architecture decisions[ ] Dependencies documented[ ] Database schema defined
Phase 1 Checklist:[ ] Project structure created[ ] Base configuration working[ ] Database models defined[ ] Core utilities implemented[ ] Foundation tests pass
Phase 2 Slices:[ ] Slice 1: [Smallest vertical piece] - Implementation: ____ - Tests: ____ - Verified: ____
[ ] Slice 2: [Next vertical piece] - Implementation: ____ - Tests: ____ - Verified: ____
[ ] Slice 3: [Next vertical piece] - Implementation: ____ - Tests: ____ - Verified: ____
Phase 3 Iterations:[ ] Prototype done[ ] Architecture refined[ ] Implementation complete[ ] All tests pass[ ] Code reviewedEffective Prompting
The way I prompt determines success:
Context: [Brief description of what we're building]Current state: [What's already done]This task: [Specific slice to implement]Constraints: [Reference to CLAUDE.md rules]Success criteria: [How we verify this works]Example:
Context: Building a blog management app where users cancreate, edit, and publish posts.
Current state:- User authentication complete (login, logout, sessions)- Post model exists with title, content, status fields- No routes or UI yet
This task:Implement the "create post" slice:1. /posts/new route (GET) - shows form2. /posts route (POST) - creates post3. Form with title and content fields4. Validation: title required, max 200 chars5. Redirect to /posts/{id} on success6. Show errors on validation failure
Constraints from CLAUDE.md:- Use repository pattern for database access- Validate all inputs with Zod schemas- Maximum file size 400 lines- No console.log statements
Success criteria:- Form renders at /posts/new- Creating a post saves to database- Validation errors display correctly- Redirect works after creation- All tests passThis level of specificity eliminates ambiguity. Claude knows exactly what to build, what constraints to follow, and how success is measured.
Summary
In this post, I explained why one-shot building with Claude Code fails and how to fix it. The solution is treating Claude Code like a mid-level engineer who is onboarding:
- Phase 0: Create CLAUDE.md with architecture decisions and constraints
- Phase 1: Build foundation layer (structure, config, models, utilities)
- Phase 2: Implement vertical slices (one complete feature at a time)
- Phase 3: Iterate through prototype → architecture → implementation → test → debug cycles
The key is small, verifiable steps. Each step completes before the next begins. Each slice works end-to-end. The spec keeps Claude consistent when context fades.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Reddit: Claude Code Best Practices
- 👨💻 Anthropic Claude Code Documentation
- 👨💻 CLAUDE.md Configuration Guide
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments