The 5-Day MVP Scope
TL;DR: Any idea can become a testable MVP in 5 days if you scope it right. Cut features, not corners. Ship the smallest thing that proves your hypothesis.
Most MVPs fail because they're not minimal enough.
Why 5 Days (Not 5 Weeks)
The problem with longer timelines:
- Feature creep becomes inevitable
- Market conditions change
- Team motivation declines
- Scope confusion grows
The 5-day advantage:
- Forces ruthless prioritization
- Maintains urgency and focus
- Enables rapid iteration
- Limits technical debt accumulation
- Creates real shipping deadlines
Constraints breed creativity. 5 days breeds MVPs that actually ship.
The 5-Day Framework
Day 1: Scope and Strip (Planning Day)
Morning: Define the core hypothesis Afternoon: Cut everything non-essential Evening: Technical architecture decisions
Day 2: Foundation (Backend Day)
Focus: Database, API, authentication basics Goal: Core data models and endpoints working No UI yet: Just API testing and data flow
Day 3: Core Feature (Logic Day)
Focus: The one thing that makes your product unique Goal: Main user workflow functioning end-to-end Basic UI: Functional, not pretty
Day 4: Interface (Frontend Day)
Focus: User interface that actually works Goal: Complete user journey from signup to core action Polish later: Ship functional, improve continuously
Day 5: Deploy and Test (Ship Day)
Morning: Production deployment Afternoon: End-to-end testing and bug fixes Evening: Share with first 10 users
Day 1: The Scoping Session
The One-Hypothesis Rule
Start with your assumption: "I believe that [target customer] will [take specific action] because [specific reason]."
Examples:
- ✅ "Freelance designers will pay $29/month for instant client approval workflows because approval delays kill momentum"
- ✅ "Restaurant managers will use daily profit tracking because they currently have no visibility into real-time margins"
- ❌ "Small businesses need better project management" (too vague)
- ❌ "People want to be more productive" (not specific enough)
The Feature Elimination Process
List everything you think you need:
Example: Client Approval Tool
□ User registration/login
□ File upload system
□ Approval workflow
□ Comments and feedback
□ Version control
□ Email notifications
□ Client billing integration
□ Analytics dashboard
□ Mobile app
□ API access
□ White-label options
□ Team management
Apply the 5-day filter:
Keep (Essential for testing hypothesis):
- ✅ User registration (simple email/password)
- ✅ File upload (basic, no fancy preview)
- ✅ Approval workflow (approve/reject buttons)
- ✅ Email notifications (simple alerts)
Cut (Nice-to-have):
- ❌ Comments and feedback (can be email for now)
- ❌ Version control (file naming convention works)
- ❌ Analytics dashboard (Google Analytics sufficient)
- ❌ Mobile app (responsive web works)
Cut (Future phases):
- ❌ Client billing integration (manual invoicing works)
- ❌ API access (no integration needs yet)
- ❌ White-label options (prove core first)
- ❌ Team management (single user sufficient)
Technical Stack Decisions (30 minutes max)
Use what you know, not what's trendy:
Frontend: React/Vue if you know it, HTML/CSS if you don't Backend: Node.js/Python/Rails - whatever's familiar Database: PostgreSQL/MySQL - avoid NoSQL complexity for MVPs Hosting: Vercel/Netlify for frontend, Railway/Render for backend Auth: Clerk/Auth0 - don't build authentication yourself
The wrong decision: Spending Day 1 researching the "best" tech stack The right decision: Using familiar tools to build faster
Day 2: Backend Foundation
Database Schema (First 2 hours)
Start with the core entities:
-- Users table (basic auth)
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR UNIQUE NOT NULL,
password_hash VARCHAR NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
-- Projects table (main entity)
CREATE TABLE projects (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
name VARCHAR NOT NULL,
status VARCHAR DEFAULT 'draft',
created_at TIMESTAMP DEFAULT NOW()
);
-- Files table (what gets approved)
CREATE TABLE files (
id SERIAL PRIMARY KEY,
project_id INTEGER REFERENCES projects(id),
filename VARCHAR NOT NULL,
file_url VARCHAR NOT NULL,
status VARCHAR DEFAULT 'pending', -- pending, approved, rejected
created_at TIMESTAMP DEFAULT NOW()
);
Avoid over-engineering:
- No complex relationships yet
- No optimization (indexes can wait)
- No audit trails or soft deletes
- Basic data types only
API Endpoints (Remaining 6 hours)
Focus on CRUD operations:
// Essential endpoints only
POST /auth/register
POST /auth/login
GET /projects
POST /projects
GET /projects/:id
POST /projects/:id/files
PUT /files/:id/status
Don't build:
- Complex filtering/searching
- Batch operations
- File processing/thumbnails
- Advanced authentication (just basic JWT)
Testing (API only)
Manual testing with Postman/Insomnia:
- Can create users and log in
- Can create projects and upload files
- Can change file approval status
- All endpoints return proper errors
No unit tests yet: Ship first, test later
Day 3: Core Feature Implementation
The Single User Journey
Map the critical path:
- User uploads file to project
- System sends approval request to client
- Client clicks approve/reject link
- System notifies user of decision
- User sees updated status
Build this flow completely before anything else
File Upload Implementation
Simple, not scalable:
// Basic file upload - no fancy features
app.post("/projects/:id/files", upload.single("file"), async (req, res) => {
const file = req.file
// Save to local storage or basic cloud storage
const fileUrl = await saveFile(file)
// Create database record
const fileRecord = await db.query(
"INSERT INTO files (project_id, filename, file_url) VALUES ($1, $2, $3) RETURNING *",
[req.params.id, file.originalname, fileUrl]
)
// Send approval email immediately
await sendApprovalEmail(fileRecord.id)
res.json(fileRecord)
})
What we're NOT building:
- File type validation (accept everything for now)
- File size limits (beyond basic server limits)
- Preview generation
- Multiple file uploads
- File versioning
Approval Workflow
Dead simple approach:
// Approval endpoint - accessible via email link
app.get("/approve/:fileId/:token", async (req, res) => {
const { fileId, token } = req.params
// Verify token (simple approach)
if (token !== generateSimpleToken(fileId)) {
return res.status(400).send("Invalid approval link")
}
// Update file status
await db.query("UPDATE files SET status = ? WHERE id = ?", ["approved", fileId])
// Notify user
await sendStatusEmail(fileId, "approved")
res.send("File approved! The designer has been notified.")
})
// Same for reject
app.get("/reject/:fileId/:token", async (req, res) => {
// Similar implementation for rejection
})
Simple token generation:
function generateSimpleToken(fileId) {
// Not cryptographically secure, but fine for MVP
return Buffer.from(`${fileId}-${process.env.SECRET_KEY}`).toString("base64")
}
Day 4: Functional Interface
The Brutally Simple UI
HTML/CSS that works:
<!-- Project dashboard -->
<div class="container">
<h1>Your Projects</h1>
<button onclick="createProject()">New Project</button>
<div id="projects">
<!-- Projects loaded via JavaScript -->
</div>
</div>
<!-- File upload -->
<div class="upload-area">
<input type="file" id="fileInput" />
<button onclick="uploadFile()">Upload for Approval</button>
</div>
<!-- Status display -->
<div class="file-status">
<span class="status pending">Pending Approval</span>
<span class="status approved">✓ Approved</span>
<span class="status rejected">✗ Rejected</span>
</div>
Basic styling (1-2 hours max):
.container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.upload-area {
border: 2px dashed #ccc;
padding: 40px;
text-align: center;
}
.status {
padding: 5px 10px;
border-radius: 3px;
}
.status.approved {
background: #d4edda;
color: #155724;
}
.status.rejected {
background: #f8d7da;
color: #721c24;
}
.status.pending {
background: #fff3cd;
color: #856404;
}
JavaScript Functionality (No Framework)
Keep it vanilla and functional:
// Project creation
async function createProject() {
const name = prompt("Project name:")
if (!name) return
const response = await fetch("/projects", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name }),
})
if (response.ok) {
loadProjects() // Refresh list
}
}
// File upload
async function uploadFile() {
const fileInput = document.getElementById("fileInput")
const file = fileInput.files[0]
if (!file) return
const formData = new FormData()
formData.append("file", file)
const response = await fetch(`/projects/${currentProjectId}/files`, {
method: "POST",
body: formData,
})
if (response.ok) {
alert("File uploaded! Approval email sent.")
loadFiles() // Refresh file list
}
}
User Authentication (Minimal)
Simple login form:
<form id="loginForm">
<input type="email" placeholder="Email" required />
<input type="password" placeholder="Password" required />
<button type="submit">Login</button>
</form>
Basic session handling:
// Store JWT in localStorage (not secure, but functional)
async function login(email, password) {
const response = await fetch("/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password }),
})
if (response.ok) {
const { token } = await response.json()
localStorage.setItem("token", token)
showDashboard()
}
}
Day 5: Deploy and Ship
Morning: Production Deployment
Choose the simplest deployment:
- Frontend: Netlify/Vercel (drag and drop)
- Backend: Railway/Render (Git deploy)
- Database: Planet Scale/Supabase (managed)
Environment variables checklist:
DATABASE_URL=postgresql://...
JWT_SECRET=your-secret-key
EMAIL_API_KEY=your-email-service-key
FILE_STORAGE_KEY=your-storage-key
Don't optimize yet:
- No CDN setup
- No caching
- No load balancing
- No monitoring beyond basic logs
Afternoon: End-to-End Testing
Test the complete user journey:
- ✅ User can register and log in
- ✅ User can create a project
- ✅ User can upload a file
- ✅ Email is sent to intended recipient
- ✅ Client can approve/reject via email link
- ✅ User receives notification of decision
- ✅ Status updates correctly in dashboard
Bug triage rules:
- Fix immediately: Anything breaking the core flow
- Fix before sharing: UI bugs affecting usability
- Log for later: Nice-to-have improvements
Evening: First User Testing
Share with 10 people:
- 5 potential customers (ideal users)
- 3 friends/colleagues (honest feedback)
- 2 strangers (unbiased perspective)
Ask specific questions:
- "Can you complete [core action] without help?"
- "What's confusing about this process?"
- "Would you pay $X/month for this?"
- "What's the biggest thing missing?"
- "How often would you use this?"
Scope Creep: The 5-Day Killer
Common Scope Creep Triggers
"This would be easy to add..."
- Extra form fields
- Additional user types
- More file formats
- Extra notification channels
"Users will expect this..."
- Advanced search
- Bulk operations
- Mobile optimization
- Real-time updates
"It's industry standard to have..."
- User roles and permissions
- Advanced security features
- Comprehensive reporting
- Integration capabilities
The Anti-Scope Creep Protocol
When tempted to add features:
- Stop and document: Write it down for next iteration
- Ask the core question: Does this prove/disprove my hypothesis?
- Estimate truthfully: How many hours would this really take?
- Remember the goal: Ship something testable, not something perfect
The 5-day rule: If you can't ship it without this feature, your scope is too big.
Post-Launch: The Next 5 Days
Days 6-10: Iteration Based on Feedback
Focus on:
- Critical bugs that prevent core usage
- One-click improvements (copy changes, button placement)
- Most requested feature (if it fits the hypothesis)
Ignore:
- Feature requests that change core value proposition
- Technical debt that doesn't affect users
- Scaling concerns (unless you have 100+ active users)
Week 2: Decide the Direction
Three possible outcomes:
1. Hypothesis Confirmed (Users love it)
- Double down on core feature
- Improve UI/UX based on usage patterns
- Start building sustainable infrastructure
2. Hypothesis Partially Confirmed (Mixed feedback)
- Pivot slightly based on strongest positive feedback
- A/B test variations of core feature
- Focus on specific user segment that responded best
3. Hypothesis Rejected (Users don't engage)
- Kill it fast
- Document learnings
- Start next 5-day MVP based on learnings
FAQ
Q: What if my idea is too complex for 5 days? A: Your scope is too big. Find the smallest testable version of your hypothesis.
Q: Can I use this framework for hardware products? A: Adapt it to hardware: Day 1-2 for design, Day 3-4 for prototyping, Day 5 for testing with users.
Q: What if users expect more features? A: Users who really need your solution will use a basic version. Users who demand features first weren't real customers anyway.
Q: How do I handle technical debt from 5-day sprints? A: Refactor incrementally as you validate product-market fit. Don't optimize prematurely.
Ready to scope your 5-day MVP?
We use this framework to ship testable MVPs in one week, not one month. No feature creep, no over-engineering.
Quick Build ($750) • Full Sprint ($7,500)
Internal links:
Ready to build your MVP?
Stop overthinking architecture. Start with the smallest version that proves your hypothesis works.