That app idea in your head? The one with user accounts, a database, maybe payments? You've been putting it off because you don't know where to start—not just the coding, but the entire process.
The process matters more than the code. Once you understand the systematic approach, AI can help you implement each step.
The Tech Stack
Building web apps involves choosing from many technologies: programming languages (JavaScript, Python, PHP, Ruby), frameworks (Next.js, Django, Laravel, Ruby on Rails, Angular), and databases (PostgreSQL, MySQL, MongoDB). We're choosing the following stack because it's the most popular, has extensive learning resources, and is flexible enough to build almost any idea you can think of—from simple tools to complex SaaS applications.
| Technology | Purpose | Why This Choice |
|---|---|---|
| Next.js | Full-stack React framework | Frontend, backend API routes, and SSR in one framework |
| Supabase | PostgreSQL + Auth + APIs | Production-grade database with built-in auth and RLS |
| TypeScript | Type-safe JavaScript | Catches errors early; AI generates better TS code |
| Tailwind CSS | Utility-first CSS | Rapid UI development; AI excels at Tailwind |
| Shadcn/ui | Component library | High-quality, accessible components you own |
| Vercel or Netlify | Hosting | Seamless Next.js deployment with automatic CI/CD |
AI Coding Setup Options
The right AI coding setup is your secret weapon. It turns hours of work into minutes—writing components, debugging errors, and navigating unfamiliar codebases becomes almost effortless. Here are our recommended setups:
| Setup | Description | Monthly Cost |
|---|---|---|
| Cursor | AI-first code editor that integrates the most powerful LLMs from OpenAI, Anthropic, and Google. Great for most developers. | ~$20 |
| Claude Code + VS Code | Created by Anthropic, who currently have the best coding models. Claude Code benefits directly from Anthropic's cutting-edge coding capabilities. Best for terminal-comfortable developers. | ~$20 |
| Cursor + Claude Code | Combine both strengths: use Cursor with GPT or Gemini for planning and exploration, then Claude Code for implementation. Best for production apps and complex refactors. | ~$40 |
Recommendation
Start with Cursor—it's the easiest to get started with. Add Claude Code later when you need deeper codebase understanding or help with complex architectural decisions.
The 5-Step Workflow
Now that you have your tools ready, here's the systematic process we'll follow. Each step builds on the previous one—skip nothing, and you'll have a production-ready app.
Refine Idea
Setup Environment
Build Foundation
Build Features
Launch & Monitor
Refine Idea
Setup Environment
Build Foundation
Build Features
Launch & Monitor
| Phase | What You Do | Time Estimate |
|---|---|---|
| 1. Refine Idea | Define MVP with AI assistance | 1-2 hours |
| 2. Setup Environment | Install tools, create project, configure Supabase | 30-60 min |
| 3. Build Foundation | Layout, authentication, protected routes | 2-3 hours |
| 4. Build Features | Iterative development with Git workflow and deployments | Days to weeks |
| 5. Launch & Monitor | Custom domain, pre-launch checks, error tracking | 1-2 hours |
Key insight: Build one well-tested feature at a time. Deploy it. Move to the next.
Refine Your Idea
- Spend 1-2 hours refining with AI before coding
- Define exactly 3-5 MVP features
- Document your data model
- Create a realistic timeline
Most people skip this and jump straight into coding. Big mistake.
Define Your MVP
Open ChatGPT or Claude and have a real conversation:
After brainstorming, get specific:
Example MVP Breakdown
| Feature | Description |
|---|---|
| User authentication | Let users sign up and log in with Google OAuth or email/password. This is the foundation for everything else. |
| Create/edit/delete habits | Basic CRUD operations so users can manage their habit list. Keep it simple—name and optional description. |
| Mark habits complete | A simple toggle to mark a habit as done for today. This is the core interaction users will do daily. |
| 7-day history | Show the past week of completions so users can see their recent progress at a glance. |
| Streak counter | Display consecutive days completed. Streaks are the main motivator for habit apps. |
Build later: Advanced analytics, social features, custom reminders, mobile apps. Ship the MVP first, then add these based on user feedback.
Document Your Data Model
AI will provide something like:
| Table | Fields & Details | Relationships |
|---|---|---|
| users | Managed by Supabase Auth: id (uuid, PK), email (text, unique), created_at (timestamp) | One user → many habits, One user → many completions |
| habits | id (uuid, PK), user_id (uuid, FK → users.id), name (text, required, max 100 chars), description (text, optional), created_at (timestamp), updated_at (timestamp). Index on user_id. | Belongs to user, Has many completions |
| completions | id (uuid, PK), habit_id (uuid, FK → habits.id), user_id (uuid, FK → users.id), completed_at (date, required), created_at (timestamp). Unique constraint on (habit_id, completed_at). Indexes on habit_id and user_id. | Belongs to habit, Belongs to user |
Pro Tip: Extending User Profiles
Supabase Auth stores authentication data in a special auth.users table (email, password hash, OAuth tokens). You cannot modify this table directly.
If you need additional user information like usernames, bio, avatar URL, or social accounts, create a separate public.profiles table linked to auth.users via the same id. Then use a database trigger to automatically create a profile record whenever someone signs up.
This keeps auth data (managed by Supabase) separate from your custom user data (managed by you).
Save this document. You'll reference it constantly during development.
Set Up Your Environment
- Install Node.js, Git, Supabase CLI
- Create Next.js project with TypeScript
- Set up THREE Supabase environments (local, staging, production)
- Configure environment variables securely
Prerequisites
Before building anything, you need a few essential tools. Node.js runs your development server and manages packages. Git tracks code changes and connects to GitHub for version control. Your AI coding tool (Cursor or VS Code with Claude Code) writes most of the code. The Supabase CLI lets you run a local database and manage migrations. Finally, you'll need a GitHub account to store your code and connect to deployment platforms like Vercel or Netlify.
- Node.js v18+ installed from nodejs.org
- Git installed from git-scm.com
- A GitHub account (free at github.com)
- Your AI coding tool installed (Cursor or VS Code)
- Supabase CLI installed: npm install -g supabase
Create Your Project
Let's scaffold a new Next.js application with all the modern defaults we need.
Install Dependencies
We'll install the Supabase client libraries for database and authentication. For UI components, we recommend Shadcn/ui—it gives you beautifully designed, accessible components that you own and can customize. Feel free to use another UI library if you prefer.
Set Up Git
Version control is essential. Initialize Git and connect to a remote repository to keep your code safe and enable collaboration.
Supabase: Three Environments
We recommend setting up three separate database environments from the start. This keeps your development experiments isolated from real user data and gives you a safe place to test changes before they go live.
| Environment | Purpose | How to Create |
|---|---|---|
| Local | Development on your machine | supabase init then supabase start |
| Staging | Test before production | Create project at supabase.com |
| Production | Live app for real users | Create second project at supabase.com |
Environment Variables
Environment files store sensitive configuration like API keys and database URLs. You'll have one file per environment. While we're starting with Supabase credentials, you'll add other variables here as your app grows (API keys, feature flags, etc.)—more on this later.
Create three files in your project root:
| File | Purpose | Supabase URL |
|---|---|---|
.env.local | Local development | http://localhost:54321 |
.env.staging | Cloud testing | Your staging project URL |
.env.production | Live app | Your production project URL |
How to switch between environments
Local development (default):
- Next.js automatically uses
.env.localwhen you runnpm run dev - Your app connects to your local Supabase instance
Testing with staging database locally:
- Temporarily rename
.env.stagingto.env.local - Run
npm run devto test against your cloud staging database - Rename back to
.env.stagingwhen done
Deploying to Vercel or Netlify:
- Copy your environment variables to your hosting provider's dashboard
- We'll cover the full deployment workflow later in this guide
Never commit .env files to Git. Environment variables stay local or get added directly to your hosting provider.
Understanding Migrations
Critical concept
Migrations are version-controlled SQL files that define your database schema. They ensure everyone has the same database structure.
The workflow:
- Develop locally with local Supabase
- Create a migration file for schema changes
- Push migrations to staging, test
- Push migrations to production
Applying Migrations
Once you've created a migration file, you need to apply it to your databases.
Always test migrations on your local and staging environments before pushing to production. Database changes can be difficult to reverse.
Build Foundation: Layout & Auth
- Create responsive layout with navbar
- Implement authentication (Google OAuth + email/password)
- Set up protected routes with middleware
- Create first protected page (dashboard)
Create Layout Structure
Every page in your app will share a common layout—navbar, footer, and content area. Let's create this foundation first so all future pages automatically inherit it.

Set Up Authentication
Supabase offers many authentication methods—OAuth providers (Google, GitHub, etc.), Magic Links, email/password, and more. To keep things simple, we recommend:
- Google Login — The most popular option. Users click one button and they're in. No passwords to manage.
- Magic Link (optional) — For users who prefer email. They enter their email, receive a link, click it, and they're logged in. No password needed.
If you want the simplest setup, use Google Login only. Adding Magic Links requires configuring an email service (like Resend) to send the login links. We avoid traditional email/password authentication—it opens the door to security issues like weak passwords, credential stuffing, and password reset vulnerabilities.
Configure Supabase Auth
- Enable Google OAuth and configure with your Google Cloud credentials
- Enable Magic Link if you want email-based login (requires email service setup)
- Configure Site URL and Redirect URLs for all environments (local, staging, production)
Create Auth Pages
With Google and Magic Link, you only need a simple login page—no separate signup or password reset flows to build. Users are automatically created in Supabase on their first login.

Protect Routes with Middleware
Next.js middleware runs before every request, making it the perfect place to check authentication. If a user tries to access a protected page without being logged in, they'll be redirected to the login page.
Test Authentication
Before moving on, verify that authentication works end-to-end. This is one of those things you want to get right early—debugging auth issues later is painful.
Google OAuth doesn't work with local Supabase. To test Google Login, connect to your cloud staging instance by renaming .env.staging to .env.local temporarily. Magic Links also require a cloud instance with email configured.
- Google OAuth → completes flow and redirects to dashboard
- Magic Link (if enabled) → email received, clicking link logs you in
- Log out → clears session and redirects to home or login
- Log back in → works correctly
- Access /dashboard when logged out → redirects to /login
Check Supabase Studio to verify users are being created—use your cloud dashboard at supabase.com/dashboard when testing with staging, or localhost:54323 for local testing.
Build Features Iteratively
- Set up Git workflow and connect to Vercel or Netlify
- Use feature branches for each new feature
- Follow the 7-step feature cycle
- Build, test manually, write automated tests, deploy
Git Workflow
Before diving into features, let's establish a Git workflow that works with our two Supabase environments (staging and production).
Branch Strategy
We use two long-lived branches, each connected to its own database:
main (production) ← dev (staging) ← feature branches
↓ ↓
Prod Supabase Staging Supabase
main— Production code, deployed with production Supabasedev— Staging code, deployed with staging Supabase- Feature branches — Your work in progress, tested locally
For each feature:
- Create a feature branch from
dev - Build and test locally with local Supabase
- Merge to
devand test on staging with cloud staging Supabase - When stable, merge
devtomainfor production release
Set Up Vercel or Netlify
Before building features, connect your repository to a hosting provider. You only need one project — it automatically handles staging vs production deployments.
- Create account at vercel.com or netlify.com
- Import your GitHub repository
- Framework preset: Next.js (auto-detected)
- Deploy — your app is now live at a temporary URL
How Environment Variables Work
Vercel and Netlify assign environment variables by deployment type, not branch name:
| Branch | Deployment Type | Environment Variables |
|---|---|---|
main | Production | Production env vars → production Supabase |
dev, feature branches, PRs | Preview | Preview env vars → staging Supabase |
Configure Environment Variables
Add your Supabase credentials separately for Preview (staging) and Production:
| Variable | Preview Value | Production Value |
|---|---|---|
NEXT_PUBLIC_SUPABASE_URL | Staging project URL | Production project URL |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Staging publishable key | Production publishable key |
SUPABASE_SECRET_KEY | Staging secret key | Production secret key |
In Vercel: Settings → Environment Variables → Add each variable and select which environments it applies to.
In Netlify: Site settings → Environment variables → Create variable with different values per deploy context.
Never commit environment variables to Git. Always configure them in your hosting provider's dashboard.
The result:
devbranch → Preview URL (your-app-git-dev.vercel.app) → staging Supabasemainbranch → Production URL (yourapp.com) → production Supabase
Same codebase, different configs, fully isolated.
The Feature Development Cycle
For every feature, follow this process:
| Step | What You Do | Time |
|---|---|---|
| 1 | Plan feature & data model | 10-30 min |
| 2 | Create database migration | 5-15 min |
| 3 | Create API routes | 15-30 min |
| 4 | Implement UI | 1-3 hours |
| 5 | Manual testing | 15-30 min |
| 6 | Write tests | 30-60 min |
| 7 | Deploy | 10-15 min |
Plan
Migration
API Routes
UI
Manual Tests
Write Tests
Deploy
Plan
Migration
API Routes
UI
Manual Tests
Write Tests
Deploy
Example: Building Habits CRUD
Let's walk through the cycle with our first real feature—the ability to create, read, update, and delete habits. This is the core of our app.
Step 1: Plan Feature & Data Model
Before writing code, get clear on what you're building. Spend 10-30 minutes thinking through the user experience and data requirements.
Feature scope:
- Users can create habits with a name and optional description
- Users see all their habits in a list
- Users can edit or delete any habit
- Each user only sees their own habits (data isolation)
Data model — habits table:
| Field | Type | Notes |
|---|---|---|
| id | uuid | Primary key, auto-generated |
| user_id | uuid | Foreign key to auth.users |
| name | text | Required, max 100 chars |
| description | text | Optional, max 500 chars |
| created_at | timestamp | Auto-generated |
| updated_at | timestamp | Auto-updated |
Step 2: Create Migration
Now translate your data model into a database migration. This creates the actual table in your database.
supabase migration new create_habits_table
Step 3: Create API Routes
With the database ready, create the API endpoints that your frontend will call. These handle all the business logic and database operations.
Step 4: Implement UI
Now build the user interface. This is where users actually interact with your feature—make it intuitive and responsive.

Step 5: Manual Testing
Before automating anything, click through the feature yourself. Find and fix obvious bugs now—it's faster than debugging failing tests later.
- Page loads without errors
- Create habit → appears in list
- Edit habit → changes persist
- Delete habit → removed from list
- Form validation works (empty name rejected)
- Loading states show during operations
- Error messages display when operations fail
Step 6: Write Tests
Once everything works manually, write tests to lock in the behavior. Tests catch regressions when you add new features later.
One-Time Setup
Install the testing libraries (you only do this once per project):
npm install -D vitest @testing-library/react @testing-library/jest-dom jsdom
npm install -D @playwright/test
npx playwright install
| Library | Purpose |
|---|---|
| Vitest | Fast unit test runner, compatible with Jest syntax |
| Testing Library | Utilities for testing React components by user behavior |
| jest-dom | Custom matchers like toBeInTheDocument(), toHaveTextContent() |
| jsdom | Simulates a browser environment for unit tests |
| Playwright | Runs E2E tests in real browsers (Chrome, Firefox, Safari) |
Unit Tests
Unit tests verify individual pieces work correctly in isolation. They're fast and run without a browser.
Expected output: Test files in __tests__/ or *.test.ts files next to your API routes. Each test mocks Supabase responses and verifies your route handlers return correct data and status codes.
E2E Tests
E2E (end-to-end) tests simulate real users clicking through your app in an actual browser. They're slower but catch integration issues.
Expected output: Test files in e2e/ or tests/ folder. Playwright launches a real browser, navigates to your app, fills forms, clicks buttons, and asserts the UI updates correctly.
Running Tests
npm run test # Unit tests (fast, no browser)
npx playwright test # E2E tests (launches browser)
Tests as safety nets
Build first, test to lock it in. Tests ensure future changes don't break existing features.
Step 7: Deploy
Feature complete and tested locally? Time to ship it.
Merge to dev (deploys to staging):
# First, push migration to staging database
npx supabase link --project-ref <staging-ref> && npx supabase db push
# Then merge and push
git checkout dev && git merge feature/habits-crud && git push origin dev
Test on your staging URL. Once it works, promote to production:
Merge dev to main (deploys to production):
# First, push migration to production database
npx supabase link --project-ref <prod-ref> && npx supabase db push
# Then merge and push
git checkout main && git merge dev && git push origin main
Always push database migrations BEFORE merging code that depends on them.
Launch & Monitor
- Set up your custom domain
- Complete the pre-launch checklist
- Add error tracking and analytics
- Ship your MVP to real users
You've built features, tested them on staging, and deployed to production. Now it's time to launch properly.
Custom Domain
Connect your own domain to make your app feel professional.
- Purchase a domain (Namecheap, Google Domains, Cloudflare, etc.)
- In Vercel or Netlify: Settings → Domains → Add your domain
- Update DNS records as instructed (usually CNAME or A record)
- Wait for SSL certificate to provision (automatic, usually minutes)
- Verify both
yourapp.comandwww.yourapp.comwork
Pre-Launch Checklist
Before announcing to the world, verify these basics:
- All core features work on production
- Authentication flow is smooth (sign up, log in, log out)
- Mobile experience is usable
- Error states show helpful messages (not blank screens)
- Favicon and meta tags are set for social sharing
- Environment variables are set correctly in production
Monitoring
Once your app is live, you need visibility into errors and user behavior. These tools have free tiers for small apps.
Error tracking — Know when things break before your users tell you:
Analytics — Understand how users interact with your app:
Don't over-engineer monitoring at launch. Start with error tracking (Sentry) so you know when things break. Add analytics once you have users and questions about their behavior.
Advanced Topics
Once you've shipped your MVP and have users, add these features as needed.
Working Effectively with AI
Be Specific
Give Context
Iterate
Verify
Be Specific
Give Context
Iterate
Verify
AI Strengths vs Your Judgment
AI excels at
- Boilerplate code & CRUD operations
- TypeScript types and interfaces
- UI components with Tailwind
- Standard patterns (auth, pagination)
- Debugging specific errors
- Database schema design
- Test generation
You decide
- Product decisions (what features, when)
- Business logic specific to your domain
- Performance optimization choices
- Security beyond standard practices
- Architecture decisions
- User experience tradeoffs
Project Rules Files
Most AI coding tools let you store project context in a rules file. This gives the AI knowledge about your stack, conventions, and patterns—so you don't have to repeat yourself in every prompt.
| Tool | File Location | Purpose |
|---|---|---|
| Claude Code | CLAUDE.md in project root | Project context, commands, conventions |
| Cursor | .cursor/rules/*.md | Modular rules for different concerns |
What to include in your rules file:
- Tech stack and versions (Next.js 15, React 19, Supabase, etc.)
- Code style preferences (named exports, TypeScript strict mode)
- File structure conventions (
components/[feature]-ui/) - Common commands (
npm run dev,npx supabase db reset) - Project-specific patterns (how you handle auth, API routes)
- Things to avoid (no
anytypes, no inline styles)
Start simple, iterate
Begin with basic stack info and add rules as you notice repeated corrections. A good rules file evolves with your project.
Effective Prompting
The golden rule
Be specific about what you want, include relevant context, and tackle one thing at a time.
| Instead of... | Try... |
|---|---|
| "Add pagination" | "Add cursor-based pagination to GET /api/habits using Supabase. Page size 20. Return next_cursor." |
| "This doesn't work" + entire file | "This fetch returns undefined. Here's the function: [snippet]. Error: [exact error]." |
| "Build complete auth with OAuth, 2FA, password reset" | Start with basic auth → add OAuth → add password reset (one at a time) |
What You've Learned
You now understand:
- The complete workflow from idea to production
- How to use AI assistants effectively for each phase
- The importance of testing and systematic deployment
- Database migrations and version-controlled schemas
- Three-environment strategy (local, staging, production)
- Iterative feature development with proper validation
More importantly: You have a repeatable process. Every app follows this pattern.
Next Steps
Pick a project that matches your current skill level and build it end-to-end using this guide.
🌱 Start Simple
- Todo app with categories
- Bookmark manager with tags
- Expense tracker with budgets
🌿 Medium Complexity
- Time tracking with projects
- Recipe manager with meal planning
- Workout logger with stats
🌳 More Advanced
- SaaS tool for a niche problem
- Marketplace (buyers/sellers)
- Real-time collaborative tool
Now go build something real
You know the process. You have the tools. The difference between people who ship and people who don't isn't talent—it's starting, then following through systematically.
Last updated: December 2024