How We Use Claude Code to Build MVPs in 2 Weeks
TL;DR: An inside look at how HouseofMVPs uses Claude Code as a core development tool, covering prompting strategies, full stack workflows, the limitations where human developers still matter, and why AI assisted development makes fixed price MVP delivery possible.
The Honest Starting Point
Two years ago, "build an MVP in two weeks" was a marketing claim that required cutting corners you would regret later. The code would work but it would not be maintainable. The architecture would hold for six months, then become a liability.
Claude Code changed the math. Not by making developers faster at typing, but by compressing the time between "I understand what needs to be built" and "it is built." The cognitive load of translating a clear design into working code has dropped dramatically. The design thinking, architectural decisions, and business logic judgment still take the same time they always did. Before starting an MVP build with Claude Code, use the MVP Cost Calculator to scope timelines and investment realistically.
Here is exactly how we use it.
Our Internal Workflow
Every project starts with the same two artifacts: a scope document and a CLAUDE.md.
The scope document captures the user flows, the data model, and the integrations. We write this before touching code because Claude Code is most effective when the task is well defined. Vague tasks produce vague code.
The CLAUDE.md is the persistent context file that travels with the project. We start from a template and customize it for each project:
# Project: [Client Name] MVP
## Overview
[2-3 sentences on what the product does and who it is for]
## Stack
- Backend: Hono + TypeScript on Railway
- Database: PostgreSQL + Drizzle ORM
- Frontend: React + Vite + Tailwind + shadcn/ui
- Auth: Better Auth
- Email: Resend
- Payments: Polar.sh
## File Structure
- apps/api/src/routes/ — all API route handlers
- apps/api/src/db/ — Drizzle schema and migrations
- apps/web/src/pages/ — top level page components
- apps/web/src/components/ — reusable components
## Conventions
- Use named exports everywhere
- Zod for all request validation at the route level
- API errors return { error: string, code: string }
- Database queries go in apps/api/src/db/queries/ not inline in routes
- React Query for all data fetching in the frontend
## Current Sprint
[Update this each day with the current task focus]
The "Current Sprint" section is updated every morning. It tells Claude Code what we are working on so the first prompt of each session does not require re establishing context.
Daily Development Rhythm
Each working day follows the same structure:
Morning (30 min): Update CLAUDE.md with today's focus. Review any open tasks. Start a Claude Code session and ask for a summary of where things stand based on recent git commits.
Development blocks (2 to 3 hours each): Focused sessions on specific features. Each session has a clear goal defined before starting. We close sessions and commit before switching to a different area of the codebase.
End of day: Run the full test suite. Commit everything that is working. Update CLAUDE.md with anything learned about the codebase today (new conventions discovered, decisions made, files to avoid).
The discipline of committing frequently matters more with Claude Code than without it. Because Claude Code can make changes across many files simultaneously, an uncommitted session that goes wrong is harder to recover from than a series of small committed increments.
Prompting Strategies for Full Stack Development
Be specific about the contract first
For any backend feature, start by defining the API contract before asking Claude Code to write the implementation. A prompt like this works well:
"Add a POST /api/projects endpoint. It takes
{ name: string, description?: string }in the body. The user must be authenticated. It creates a project record in the database linked to the current user, and returns the created project. Follow the pattern in apps/api/src/routes/users.ts for authentication and error handling."
The explicit reference to an existing file ("follow the pattern in users.ts") is important. It tells Claude Code which patterns to copy rather than inventing something new. Consistency is critical for a codebase that will be maintained and extended.
Use the codebase as the spec
For frontend work, reference the design system rather than describing it from scratch:
"Build a ProjectCard component. Look at apps/web/src/components/UserCard.tsx to understand the card pattern we use. The project card should show name, description, creation date, and a link to the project detail page."
Claude Code reads UserCard.tsx and builds ProjectCard in a style that matches it. No style guide document needed. The existing code is the style guide.
Scope error handling explicitly
Error handling is where Claude Code defaults vary and where production reliability lives:
"The project creation endpoint needs proper error handling. If the database insert fails due to a unique constraint (duplicate project name per user), return a 409 with code 'DUPLICATE_PROJECT_NAME'. All other errors should log to console with request context and return 500 with code 'INTERNAL_ERROR'. Do not expose the database error message to the client."
Generic error handling prompts produce generic error handling code. Specific error handling prompts produce code that handles the actual failure modes your application will encounter.
Ask for tests alongside implementation
The most effective pattern for test coverage is to ask for tests in the same prompt as the implementation:
"Add rate limiting to the auth endpoints. Use the existing Redis connection in apps/api/src/lib/redis.ts. Limit login attempts to 5 per IP per 15 minutes, return 429 with a retry-after header when exceeded. Write tests for the rate limiting logic using Vitest."
Separating the test writing into a second session means you have to re establish context. Asking for both in one prompt produces implementation and tests while the context is fully loaded.
How Claude Code Handles Specific Technologies
React and Frontend Work
Claude Code handles React well for:
- Component structure and props design
- Custom hook extraction when logic gets complex
- React Query integration (data fetching, mutations, cache invalidation)
- Form handling with react-hook-form and Zod
- Routing with react-router or TanStack Router
It is less useful for:
- Visual layout decisions (spacing, color, responsive breakpoints)
- Complex animation and interaction design
- Performance optimization that requires profiling
- Accessibility edge cases beyond basic ARIA attributes
The pattern we follow for frontend: let Claude Code handle the structure and data integration, then do a manual pass for visual polish and responsive behavior. The functional code is usually solid. The visual details need a human eye.
Database Schema and Migrations
Drizzle schema work is one of the strongest use cases:
"Add a projects table to the schema. A project belongs to a user, has a name (unique per user), optional description, and status (draft, active, archived). Add the appropriate indexes. Create the migration."
Claude Code writes the Drizzle schema, generates the migration with pnpm db:generate, and runs pnpm db:push to apply it. The schema usually needs minimal revision because Drizzle's TypeScript types enforce correctness at the schema level.
For query writing, Claude Code produces good basic queries. Complex queries with multiple joins, window functions, or performance requirements need more careful review. Always check the query plan with EXPLAIN ANALYZE for queries that will run at scale.
Third Party API Integrations
For integrations with well documented APIs (Stripe, Polar.sh, Resend, Anthropic), Claude Code produces reliable integration code because these APIs have dense training data. For newer or less documented APIs, it may hallucinate endpoint paths or parameter names. Always validate against the actual API documentation.
Our pattern:
"Integrate Polar.sh checkout. Read the Polar.sh webhook handler in apps/api/src/routes/polar.ts to understand how we've set up the client. Add a POST /api/checkout endpoint that creates a checkout session for the Pro plan with product ID [ID]. Return the checkout URL."
The reference to the existing Polar.sh handler gives Claude Code the actual SDK usage patterns from our codebase rather than relying on training data that may be out of date.
Where Human Developers Still Matter
Being clear about this is important. Claude Code is a force multiplier for a skilled developer, not a replacement. Understanding what an MVP actually is keeps the scope disciplined when you hand prompts to Claude Code — the model will build what you describe, not what you implicitly assumed.
Architectural decisions
When a client asks "should we build this as a monolith or microservices?" or "should we use PostgreSQL or a document database for this use case?", that requires judgment about the client's growth trajectory, team size, operational complexity tolerance, and budget. Claude Code can explain tradeoffs, but it cannot make the call.
Debugging genuinely novel problems
When a bug has no obvious cause, debugging requires forming hypotheses about system behavior, designing experiments to test them, and following the evidence wherever it leads. This process benefits from Claude Code's help in executing experiments (editing code, running tests), but the hypothesis generation and experiment design require human reasoning.
Understanding stakeholder requirements
A client says "we need users to be able to share projects." What does that mean? Read only links? Editor access? Per user permissions? Expiring links? Does sharing create a copy or link to the original? These questions require a conversation, not code. Getting the requirements right before writing any code is the most valuable thing a developer does, and it is purely a human skill.
Security review
Claude Code can follow security patterns when instructed, but it does not proactively audit code for security vulnerabilities the way a security focused developer would. Input validation, SQL injection, authentication edge cases, and authorization logic need explicit human review, especially before a production launch.
Performance at scale
Claude Code writes code that is correct and reasonably efficient. It does not optimize for performance at scale without being specifically asked, and even then it lacks the operational context of what "scale" means for this specific system. A developer who has run systems under load knows where the bodies are buried. Claude Code does not.
Why AI Assisted Development Makes Fixed Pricing Possible
Traditional software development agencies quote on time and materials because scope uncertainty translates directly to time uncertainty, which translates to cost uncertainty. A feature that turns out to be harder than expected blows the budget.
Claude Code compresses two specific types of uncertainty:
Implementation time uncertainty: How long will it take to write this code? With Claude Code, implementation time for well defined tasks is dramatically more predictable. The mechanical work has a more consistent time cost.
Iteration cost: When we build something and discover it is not quite right, the cost to revise it with Claude Code is much lower than without. We can afford to build, test, get feedback, and rebuild faster.
These two compressions together make the total project duration more predictable. When duration is more predictable, fixed pricing becomes viable.
The scope still has to be disciplined. We are explicit with clients about what the two week engagement includes: a functional MVP of the core user flow, deployed and working, with clean code they can extend. We are equally explicit about what it does not include, and we document that clearly before the project starts.
For how we think about MVP scope and what to build first, see our post on how to build an MVP and our MVP development services page.
A Real Example: Billing Module in Half a Day
To make this concrete: in a recent project, the client needed Polar.sh payment integration with three pricing tiers, webhook handling for subscription events, and gating of features based on the active plan.
With Claude Code, this took about four hours:
- 30 minutes: Define the data model (subscriptions table, plan enum, relationship to users)
- 20 minutes: Create the schema and migration
- 45 minutes: Build the checkout endpoint and Polar.sh client setup
- 45 minutes: Build the webhook handler with subscription event processing
- 30 minutes: Add plan checking middleware to gated routes
- 30 minutes: Write integration tests for the webhook handler
- 30 minutes: Manual review, edge case testing, fix a bug with trial period handling
Without Claude Code, the same work would take two to three full days. Not because the logic is complex but because of the time to write boilerplate, look up Polar.sh API documentation, write the handler pattern from scratch, and manually iterate on the test setup.
That compression, replicated across every feature, is what makes the two week timeline real. For a comparison of how Claude Code stacks up against other AI coding agents like Cursor and Codex in real project conditions, see the AI coding agents comparison.
For more context on our tech stack choices and how we structure full stack projects, see our guide on how to choose a tech stack for your MVP. And for the complete Claude Code reference, see the Claude Code complete guide.
Build With an AI-Native Agency
Free: 14-Day AI MVP Checklist
The exact checklist we use to ship production-ready MVPs in 2 weeks. Enter your email to download.
MVP Development CLAUDE.md Template
Our internal CLAUDE.md template for new MVP projects, covering stack conventions, naming patterns, and session management.
Frequently Asked Questions
Frequently Asked Questions
Free Estimate in 2 Minutes
Already know your scope? Book a Fixed-Price Scope Review
