✦ Personal Edition · Full Stack + AI · macOS · 2026

AI Dev Handbook
2026 Edition

Everything you need to design, build, secure, deploy, and monetize professional web applications — from first setup on your Mac to a production SaaS with paying customers.

13Core Chapters
A→ZComplete Guide
macOSInstall Guides
2026Up to Date
Before Everything

Prompting Masterclass for Web App Development

Your prompts are the single biggest lever on the quality of what AI produces for you. A vague prompt gets vague code. A structured, specific prompt gets production-ready code on the first try. This chapter teaches you exactly how to think and write prompts like a professional.

💡
What you will learn: The anatomy of a great prompt, the 7 power techniques professionals use, real before/after examples with the exact mistakes beginners make, and ready-to-use prompt templates for every web dev task — UI, database, auth, payments, debugging.

Why Your Prompts Matter More Than You Think

AI models like Claude and ChatGPT are not search engines. They do not look up answers — they generate responses based on the exact context you give them. The model's output quality is directly proportional to the quality of your input.

❌ Basic Prompt
"make me a login page"

Result: Generic form with inline CSS, no error handling, no TypeScript, no Supabase, no redirect after login. You have to ask 5 follow-up questions to fix it.

✓ Professional Prompt
"Build a login page component for Next.js 14 App Router. Stack: TypeScript + Tailwind CSS + Supabase Auth. Include: email + password fields, Google OAuth button, error state display, loading spinner on submit, redirect to /dashboard on success. Design: Apple-minimal, no gradients, shadcn/ui Card component."

Result: Production-ready code on the first try. Correct imports, proper error handling, loading states, right redirect, matching your exact stack.

🧰 The Anatomy of a Perfect Dev Prompt

Every great developer prompt has the same six ingredients. You do not need all six every time — but knowing them lets you add the right ones for the right task.

  1. ROLE

    Tell the AI who to be

    Set the expertise level and perspective. "Act as a senior Next.js developer" or "You are an expert in Supabase RLS policies". This primes the model to use the right vocabulary, make senior-level decisions, and skip beginner explanations.

    Examples
    Act as a senior full-stack developer specialising in Next.js and Supabase. Act as a UI/UX designer who writes production React code. Act as a security engineer reviewing authentication code. You are an expert in Stripe webhook handling and subscription billing.
  2. TASK

    State exactly what you want built

    One sentence, one clear deliverable. Avoid combining multiple unrelated tasks. "Build a user profile edit form" not "make me a profile thing and also fix the login and add dark mode".

    Examples
    Build a user profile edit form component. Write a Supabase RLS policy for the orders table. Create a Stripe checkout API route for monthly subscriptions. Design a responsive sidebar navigation component.
  3. STACK

    Specify your exact technology stack

    This is the most commonly forgotten ingredient. Without it, the AI guesses — and it might give you class components when you want hooks, or JavaScript when you need TypeScript.

    Stack Declaration Template
    Stack: - Framework: Next.js 14 App Router - Language: TypeScript - Styling: Tailwind CSS + shadcn/ui - Backend: Supabase (PostgreSQL + Auth) - State: React hooks only (no Redux) - Package manager: npm
  4. SPEC

    List the specific requirements

    Bullet points work best. Each requirement is a feature, a behaviour, or a constraint. Be precise: instead of "good error handling" say "show an inline red error message below the field that caused it".

    Requirements Format
    Requirements: - Email and password fields with HTML5 validation - Password strength indicator (weak/medium/strong) - Show/hide password toggle button - Loading spinner on the submit button during API call - Inline error message from Supabase (e.g. "Invalid credentials") - On success: redirect to /dashboard using Next.js router - On mobile: full-width button, larger touch targets (44px min)
  5. DESIGN

    Describe the visual direction

    Reference real products you like as shorthand. "Apple, Linear, Stripe" tells Claude more than "clean and modern". Add constraints: "no gradients", "dark mode required", "border-radius 12px", "monochrome colour palette".

    Design Direction Examples
    Design: Apple Human Interface Guidelines aesthetic. Ultra-clean, lots of whitespace, no decorative elements. Use system font stack. No gradients. Subtle borders only. Design: Stripe Dashboard inspired. Dark sidebar, white main area, data-dense but not cluttered. Accent colour: #0072CE. Dark mode supported. Design: Linear.app style. Near-black background, minimal chrome, keyboard-first feel. Monospace font for code/data. Micro-animations on hover.
  6. OUTPUT

    Specify the output format

    Tell the AI what to give you: a single file, multiple files, explanation only, code only, or code with comments. This prevents getting a wall of text when you just needed the function.

    Output Format Instructions
    Output: Single TypeScript file. No explanation needed, code only. Output: Separate files for component, types, and API route. Show each. Output: Just the SQL migration. No explanation. Output: Code with inline comments explaining each decision. Output: First explain your approach in 3 sentences, then give the code.
Prompting Techniques

7 Power Techniques That Get Better Code

These are the specific patterns that separate developers who get great AI output from those who get generic output. Each one is immediately usable.

1

Give Context About Your Existing Code

The most powerful thing you can do is tell the AI what already exists. Paste your current code, your file structure, or your database schema. Without this, the AI invents assumptions that conflict with your project.

❌ Without context
"Add a logout button to my navbar" // AI guesses your auth library, // your navbar structure, your styling. // Output probably doesn't match.
✓ With context
"Here is my current Navbar component: [paste code] I use Supabase Auth. The logout function should call supabase.auth.signOut() then redirect to /login using Next.js router.push(). Add a logout button matching the existing button style."
💡
In Cursor: You do not need to paste code manually — Cursor reads your entire codebase automatically. In Claude.ai, paste the relevant file(s) at the top of your message before the instruction.
2

Use "Before / After" Framing for Edits

When asking for modifications, show what exists now and describe what you want it to become. This eliminates ambiguity completely.

Before / After Template
I have this component that currently does [X]: [paste existing code] I want to change it so that: - Instead of [old behaviour], it should [new behaviour] - Add [new feature] - Keep everything else exactly the same Do not rewrite the whole component, only change what is needed.
⚠️
"Do not rewrite the whole component" is a powerful instruction. Without it, AI often replaces your entire 200-line component to fix a 3-line issue, breaking things you did not want touched.
3

Step-By-Step Thinking for Complex Tasks

For multi-step implementations (like setting up Stripe billing), ask the AI to plan first, then implement. This prevents it from rushing into code that misses steps.

Think-First Template
I need to add Stripe subscription billing to my Next.js app. Before writing any code, think through and list: 1. Every file I will need to create or modify 2. The exact sequence of operations 3. Any environment variables needed 4. Potential failure points Then implement each step one at a time, waiting for my confirmation before moving to the next step.
4

Provide Negative Constraints (What NOT to Do)

Telling AI what to avoid is just as important as telling it what to do. This prevents common AI bad habits like over-engineering, adding unwanted dependencies, or changing things you did not ask about.

Negative Constraints Examples
// Stop AI from over-engineering: "Do NOT use Redux or Zustand. Use React useState only." "Do NOT add any new npm packages. Use only what is already installed." "Do NOT use class components. Functional components with hooks only." "Do NOT add comments explaining what every line does." "Do NOT change any existing styling. Only add the new button." "Do NOT use any CSS-in-JS. Tailwind classes only." "Do NOT create a separate context or custom hook for this. Keep it simple."
5

Reference Real Products for Design Direction

Describing visual style in abstract terms ("clean", "modern", "professional") gives AI nothing to work with. Naming real products it has seen is the most precise design language that exists.

What You WantHow to Say It
Clean, minimal white UI"Apple Human Interface Guidelines aesthetic. Linear.app style."
Data-dense dashboard"Stripe Dashboard. Vercel Dashboard. GitHub style."
Dark developer tool"Linear.app dark mode. Raycast. Warp terminal aesthetic."
Bold, colourful SaaS"Notion. Figma. Loom landing page style."
Enterprise / corporate"Salesforce Lightning. Microsoft Fluent Design."
Aviation / operations"Boeing EFB style. Aviator-dark. High-contrast data readability."
6

The Debugging Prompt Formula

When something is broken, structure your debug prompt with four elements: what you expected, what actually happened, the error message, and the relevant code. Miss any one and you get a generic unhelpful answer.

Debug Prompt Template
I have a bug. Here is all the context: EXPECTED: [what you thought would happen] ACTUAL: [what actually happened] ERROR: [paste the exact error message from console] RELEVANT CODE: [paste only the specific function/component that is broken] WHAT I ALREADY TRIED: - [attempt 1] - [attempt 2] Stack: Next.js 14, TypeScript, Supabase Auth.
💡
"What I already tried" is the most underused part of a debug prompt. It stops AI from suggesting the same things you just tried, saving multiple round-trips.
7

Iterate in Layers, Not All at Once

Beginners try to get everything in one prompt. Professionals build in layers: structure first, then logic, then styling, then edge cases. Each layer is a separate prompt. This produces much better results at each stage.

Layered Prompting Example — Building a Data Table
// Layer 1: Structure only "Build a React data table component for flight routes. Columns: Route, Departure, Arrival, Status, Revenue. TypeScript. Tailwind. No styling yet, just the structure and data shape." // Layer 2: Add functionality "Now add: click-to-sort on every column header, a search input that filters all columns, and pagination (20 rows per page)." // Layer 3: Add styling "Now style it: Stripe Dashboard aesthetic, alternating row backgrounds, hover highlight, status column as colour-coded pills (green=on-time, yellow=delayed, red=cancelled)." // Layer 4: Edge cases "Now handle: empty state with a friendly message, loading skeleton while data fetches, error state if the API fails."

📄 Copy-Paste Prompt Templates for Every Dev Task

Fill in the brackets and send. These are structured to get production-ready results on the first try.

🎨 UI Component Prompt

Template — Copy & Fill In
Act as a senior React developer. Build a [COMPONENT NAME] component for [YOUR APP NAME]. Stack: Next.js 14 App Router, TypeScript, Tailwind CSS, shadcn/ui. Requirements: - [Requirement 1] - [Requirement 2] - [Requirement 3] - Fully accessible (ARIA labels, keyboard navigation) - Dark mode support using Tailwind dark: prefix Design: [Apple / Linear / Stripe / your reference] aesthetic. Clean, minimal. No gradients. Subtle shadows only. Do NOT: add new dependencies, use class components, or change any existing files. Output: Single .tsx file. Code only, no explanation.

🗄 Database Schema Prompt

Template — Copy & Fill In
Act as a senior PostgreSQL and Supabase expert. Design the database schema for [FEATURE NAME]. Context: I am building [BRIEF APP DESCRIPTION]. Existing tables: [list any tables you already have] Requirements: - [What data needs to be stored] - [What relationships exist] - [What queries will be common] Output: 1. SQL CREATE TABLE statements with correct types 2. Indexes for likely query patterns 3. Row-Level Security (RLS) policies for each table 4. Brief explanation of any important design decisions Do NOT use any Supabase-specific extensions I haven't mentioned.

🔐 Auth Feature Prompt

Template — Copy & Fill In
Act as a Next.js and Supabase Auth expert. Implement [AUTH FEATURE: e.g. Google OAuth login / 2FA setup / password reset]. My current setup: - Next.js 14 App Router - Supabase Auth already initialised - Client: @supabase/ssr createBrowserClient - Existing auth: [email/password already working / first auth feature] Requirements: - [Specific behaviour needed] - Error handling for all failure cases - Loading states on buttons - Redirect to /dashboard on success Output: All files needed, with exact file paths shown. Do NOT create new npm packages. Use @supabase/ssr only.

💳 Stripe Integration Prompt

Template — Copy & Fill In
Act as a Stripe and Next.js integration expert. Implement [FEATURE: e.g. subscription checkout / webhook handler / customer portal]. My setup: - Next.js 14 App Router, TypeScript - stripe npm package already installed - STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET in .env.local - Supabase for the user database (table: profiles, columns: id, stripe_customer_id, plan, subscription_status) Requirements: - [Specific Stripe feature needed] - Proper error handling and HTTP status codes - TypeScript types for all Stripe objects Output: API route file(s) with full implementation. Show the client-side code to trigger it too.

🐞 Debug Prompt

Template — Copy & Fill In
I have a bug in my [Next.js / Supabase / Stripe] code. EXPECTED: [what should happen] ACTUAL: [what is happening instead] ERROR MESSAGE: [paste exact error from browser console or terminal] CODE: [paste the smallest possible section of code that shows the problem] WHAT I TRIED: - [thing 1] - [thing 2] My stack: Next.js 14, TypeScript, Supabase, Tailwind. Node version: [run: node --version]

💡 Real Before & After — Rasika's Own Prompts Improved

Here is the exact transformation from a basic prompt to a professional one, using the kind of requests you have been sending.

Example 1 — Requesting a UI Redesign
BASIC
"I'm not happy with this, can you re do it, make it look better"
PROFESSIONAL
"Redesign this component. Keep the same data and functionality.

Issues with current design:
- Cards feel too cramped
- Status colours are hard to read
- No visual hierarchy

Direction: Stripe Dashboard style. White cards, more padding, status as colour-coded pills, section headers in uppercase 11px grey. Dark mode must work."
Example 2 — Adding a Feature
BASIC
"add payment gateway integration"
PROFESSIONAL
"Add Stripe subscription billing to my Next.js app.

Stack: Next.js 14, TypeScript, Supabase (profiles table has stripe_customer_id column already).

Need:
1. /api/stripe/checkout POST route that creates a Checkout Session for price_xxx
2. /api/stripe/webhook POST route handling checkout.session.completed and subscription.deleted
3. A Subscribe button component

Do NOT change my existing Supabase auth setup. Output all three files separately."
Example 3 — Fixing a Bug
BASIC
"it doesn't work, please fix"
PROFESSIONAL
"My login redirect is broken.

EXPECTED: After signIn(), redirect to /dashboard
ACTUAL: Page stays on /login, no error shown
ERROR: None in console. Network tab shows 200 response from Supabase.

CODE: [paste the signIn function]

TRIED: router.push() — no redirect. window.location.href — also nothing.

Stack: Next.js 14 App Router, @supabase/ssr."

⚡ Prompting Quick Reference

Bookmark this. Check it before you send any prompt to Claude or ChatGPT.

👤

Set the Role

"Act as a senior Next.js developer" before every technical prompt

🔧

Name Your Stack

Always say: Next.js 14, TypeScript, Tailwind, Supabase, shadcn/ui

📋

List Requirements

Bullet points, not paragraphs. One requirement per line

🚫

Add Constraints

"Do NOT add packages / rewrite existing code / use class components"

🎨

Name a Design Ref

Apple, Linear, Stripe, Vercel, Notion — not "clean and modern"

📄

Specify Output Format

"Code only" / "Show all files separately" / "Explain first, then code"

🔄

Paste Existing Code

Always paste what you have. Never describe it abstractly

🔒

One Task Per Prompt

Do not mix UI + auth + database in one message. Split them

📈

Build in Layers

Structure → Logic → Styling → Edge cases. Four prompts, not one

🎯
The one rule that changes everything: After writing your prompt, ask yourself — "If I handed this to a new freelance developer with no other context, would they know exactly what to build?" If the answer is no, add more detail. If yes, send it.
Read This First

Which App Do You Use to Build?

First question every new AI developer asks: do you build inside Claude.ai? Inside ChatGPT? Do you need a separate coding app? Here is the direct, honest answer.

⚠️
Neither ChatGPT nor Claude.ai is a full development environment. They are AI assistants that generate code you paste elsewhere. For actual app development you need a real code editor. The right one in 2025 is Cursor Pro. Each tool has a specific job — read on.

🤖 ChatGPT — chatgpt.com

🔗 chatgpt.com

No dedicated dev environment. GPT-4o writes code you paste into Cursor. OpenAI has a "Codex" CLI tool in beta but it is not a full IDE. ChatGPT Canvas lets you iterate on code in a side panel — handy but still not a real editor with file management.

❌ Not an IDE⚡ Use for planning & architecture

🎨 Claude.ai — You are here

🔗 claude.ai

Claude.ai is where you design UI, generate React components, write copy, and prototype ideas. The Artifacts panel previews HTML and React in real time — ideal for prototyping and visual iteration. But you cannot run servers, manage project files, or commit to GitHub from here.

⚡ Design & Prototype here❌ Not an IDE

💻 Cursor Pro — Your Main IDE

🔗 cursor.com

Built on VS Code with AI built in at every layer. Agent mode reads your entire codebase and edits multiple files at once. This is where you write code, run your local server, connect to Supabase, commit to GitHub, and deploy to Vercel. Use this every day.

✓ Full IDE✓ AI Agent✓ Use daily

📄 VS Code — Free Alternative

🔗 code.visualstudio.com

The free version of Cursor without the built-in AI. Add GitHub Copilot as an extension for AI assistance. Good for learning but less powerful than Cursor's Agent mode. Start with Cursor if budget allows.

⚡ Free alternative to Cursor

✓ The Correct Daily Workflow

All three AI tools work together. Here is how they connect:

🤖 ChatGPT
Plan architecture, design database schema, brainstorm features, write tests
🎨 Claude.ai
Generate UI components, landing pages, copy, prototype in Artifacts, refine visuals
💻 Cursor Pro
Paste generated code, implement features end-to-end, run app, debug, commit
📦 GitHub
Version control — every push to main triggers automatic Vercel deploy
🌍 Vercel
Live production URL, SSL, CDN, preview deployments for every PR
💡
The daily loop: Claude.ai on one screen to generate a component or get help. Cursor on the other screen to paste, run, iterate. Push to GitHub when a feature works. Vercel deploys automatically in 30 seconds.
Chapter 1

Complete macOS Developer Setup

Clean installation of every tool you need, in the correct order. Open Terminal with Cmd+Space → Terminal → Enter and copy-paste each command below.

Step 1 — Homebrew (macOS Package Manager)

Homebrew lets you install developer tools with one command. Install this first, before everything else.

🔗 brew.sh
Terminal
# Install Homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Apple Silicon Macs only — add Homebrew to PATH echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" # Verify brew --version

Step 2 — Node.js via nvm

nvm lets you switch Node versions between projects. Install nvm, then use it to install Node.

🔗 nodejs.org 🔗 nvm on GitHub
Terminal
# Install nvm curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash # Reload shell source ~/.zshrc # Install latest LTS version of Node nvm install --lts nvm use --lts # Verify node --version # v20.x or higher npm --version # 10.x or higher

Step 3 — Git

macOS includes an old version of Git. Install the latest via Homebrew and configure your identity.

🔗 git-scm.com
Terminal
brew install git git config --global user.name "Rasika Fernando" git config --global user.email "your@email.com" git config --global init.defaultBranch main git --version

Step 4 — Cursor Pro (Your IDE)

Download the macOS app. This is your primary development environment.

🔗 cursor.com — Download for Mac
Setup
# 1. Download .dmg from cursor.com # 2. Move Cursor.app to /Applications # 3. Open Cursor → sign in or create account # 4. Recommended: Pro plan ($20/mo) # 5. Install CLI: Cmd+Shift+P → "Shell Command: Install 'cursor'" # Open any project from Terminal: cursor my-project/ # Essential keyboard shortcuts: # Cmd+K → AI inline edit (selected code) # Cmd+L → Open AI chat panel # Cmd+I → Agent mode (multi-file) # Tab → Accept AI suggestion # Esc → Reject AI suggestion
💡
First-time Cursor setup: Settings → Models → enable Claude Sonnet (for UI) and GPT-4o (for logic). You can switch models per conversation depending on the task. Cursor also has its own cursor-small model included in the subscription.

Step 5 — GitHub CLI + SSH Key

🔗 github.com — Create account 🔗 GitHub CLI
Terminal
# Install GitHub CLI brew install gh # Login (opens browser) gh auth login # Generate SSH key ssh-keygen -t ed25519 -C "your@email.com" # Press Enter for all prompts # Copy public key to clipboard pbcopy < ~/.ssh/id_ed25519.pub # Go to github.com → Settings → SSH Keys → New SSH Key # Paste. Now git push works without a password. # Test it ssh -T git@github.com

Step 6 — Vercel CLI

🔗 vercel.com — Create account 🔗 Vercel CLI docs
Terminal
npm install -g vercel vercel login # Deploy any Next.js project: cd my-project vercel # preview deploy vercel --prod # production deploy

Step 7 — Supabase CLI

🔗 supabase.com — Create account 🔗 CLI docs
Terminal
brew install supabase/tap/supabase supabase login # Start local Supabase (full PostgreSQL + Auth + Storage) supabase init supabase start # Local dashboard: http://localhost:54323 # Sync with remote project supabase db pull # pull remote schema supabase db push # push local changes to remote

Step 8 — Stripe CLI (Payment Testing)

🔗 stripe.com — Create account 🔗 Stripe CLI docs
Terminal
brew install stripe/stripe-cli/stripe stripe login # Forward webhooks to your local server stripe listen --forward-to localhost:3000/api/stripe/webhook # In another terminal tab — trigger test events stripe trigger checkout.session.completed stripe trigger customer.subscription.deleted stripe trigger invoice.payment_failed

Step 9 — Create First Next.js Project

🔗 nextjs.org/docs
Terminal
npx create-next-app@latest my-app # Answer the prompts: # TypeScript? Yes # ESLint? Yes # Tailwind CSS? Yes # src/ directory? No # App Router? Yes ← important # Import alias? Yes (@/*) cd my-app # Install core dependencies npm install @supabase/supabase-js @supabase/ssr npm install stripe @stripe/stripe-js npm install @simplewebauthn/browser @simplewebauthn/server # Start dev server npm run dev # Open http://localhost:3000 # Open in Cursor cursor .
Chapter 2

Full Stack Architecture

How every layer of your app connects. Every piece here is covered in detail in the chapters below.

👤 User
Browser / PWA
Mobile App
🎨 Frontend
Next.js 14
React
TypeScript
Tailwind CSS
🌍 Deploy
Vercel CDN
Edge Functions
GitHub CI/CD
🗄 Backend
Supabase
PostgreSQL
Row-Level Security
Storage
🔐 Auth
Email + Password
Google OAuth
Passkeys
2FA TOTP
💳 Payments
Stripe Checkout
Webhooks
Customer Portal
🤖 AI Layer
OpenAI API
Claude API
pgvector
Chapter 3

Your Professional Tech Stack

Every tool, its official site, its cost, and exactly why it is in the stack.

🤖

ChatGPT (GPT-4o)

Architecture, database design, debugging logic, test writing. Use when you need strong reasoning about how to structure something.

🔗 chatgpt.com
Free tier$20/mo Plus
🎨

Claude (Sonnet 4.5)

Premium UI generation, React components, landing pages, copy writing. Live preview in Artifacts. Best frontend code quality of any model.

🔗 claude.ai
Free tier$20/mo Pro
💻

Cursor Pro

AI-first code editor. Agent mode edits multiple files at once. Your daily driver for all coding, debugging, and git operations.

🔗 cursor.com
Free hobby$20/mo Pro

Next.js 14

React framework with App Router, server components, API routes, image optimisation, and edge rendering. Standard for modern full-stack apps.

🔗 nextjs.org 🔗 Docs
Free / Open Source
🗄

Supabase

PostgreSQL + Auth + Storage + Realtime from one dashboard. Open-source. Free tier handles your first app completely.

🔗 supabase.com 🔗 Docs
Free tier$25/mo Pro
🌍

Vercel

Zero-config deploy from GitHub. Every PR gets a preview URL. Custom domains, analytics, edge functions. Most personal apps are free.

🔗 vercel.com 🔗 Docs
Free hobby$20/mo Pro
📦

GitHub

Version control and CI/CD. Every push to main auto-deploys via Vercel. Free for unlimited public and private repos.

🔗 github.com 🔗 Docs
Free
💳

Stripe

Industry standard payments. Subscriptions, one-time, Apple Pay, Google Pay. No monthly fee — pay only when you earn money.

🔗 stripe.com 🔗 Docs
2.9% + 30¢ per txn

Upstash Redis

Serverless Redis for caching, rate limiting, and session storage. Charged per request, scales to zero. Perfect caching layer above Supabase.

🔗 upstash.com 🔗 Docs
Free tier · Pay per use
Chapter 4

Using AI Tools Effectively

The developer who ships fastest knows exactly what to ask each AI, and what not to ask it.

🤖 Right AI for the Right Task

TaskBest ToolWhy
Plan database schemaChatGPTStrong relational reasoning
Design a dashboard UIClaudeCleanest Apple-like UI output
Implement a featureCursor AgentEdits multiple files at once
Write unit testsChatGPTGood at structured repetitive code
Landing page copyClaudeMore natural, persuasive writing
Debug runtime errorsCursor TabSees your actual code in context
Complex SQL queriesChatGPTExcellent SQL reasoning
React component from scratchClaudeConsistent, accessible output

Prompting ChatGPT for Architecture

Example Prompt
Act as a senior SaaS architect. Building a photography client portal: - Users upload images - Clients view galleries & approve shots - Invoice auto-generated on approval Design: 1. PostgreSQL schema with RLS 2. Next.js 14 API route structure 3. Supabase Auth strategy 4. Storage approach Be specific. Production-ready.

Prompting Claude for UI

Example Prompt
Build a React dashboard component. Design: Apple, Linear, Stripe aesthetic. Stack: React + TypeScript + Tailwind CSS. Requirements: - Sidebar with Tabler outline icons - 4 KPI stat cards at the top - Data table with sort + filter - Full dark mode support - No gradients, ultra clean Use shadcn/ui components where possible.

💻 Cursor Pro — Agent Mode Workflow

Agent mode reads your full codebase and implements features across multiple files at once.

  1. 1

    Open project: cursor my-project/

    Cursor indexes your entire codebase for AI context. The more context it has, the better its suggestions.

  2. 2

    Open Agent with Cmd+I

    Different from Cmd+L (chat). Agent can create, edit, and delete files. Chat only suggests changes you apply manually.

  3. 3

    Write a specific feature request

    Good example: "Add a profile page at /app/profile/page.tsx that fetches user data from Supabase profiles table, shows avatar/name/email, and has an edit form with optimistic updates and toast notifications on save"

  4. 4

    Review every diff before accepting

    Cursor shows colour-coded diffs of every file change. Read each one. Accept good changes with ✓, reject or edit bad ones.

  5. 5

    Test and commit

    npm run dev → test manually in browser → git add . && git commit -m "feat: user profile page"

🔗 How to Connect All Tools — Real Example

The exact sequence from idea to live paying product, using every tool at the right moment.

  1. 1

    ChatGPT → database schema

    Prompt ChatGPT to design your tables. Copy the output SQL.

    ChatGPT Output → supabase/migrations/001_init.sql
    CREATE TABLE profiles ( id UUID REFERENCES auth.users PRIMARY KEY, full_name TEXT, avatar_url TEXT, stripe_customer_id TEXT, plan TEXT DEFAULT 'free', created_at TIMESTAMPTZ DEFAULT NOW() ); ALTER TABLE profiles ENABLE ROW LEVEL SECURITY; CREATE POLICY "Own data only" ON profiles FOR ALL USING (auth.uid() = id);
  2. 2

    Supabase → run the migration

    Paste SQL in Supabase Dashboard → SQL Editor → Run. Or via CLI: supabase db push

  3. 3

    Claude.ai → generate the UI component

    Prompt Claude for a React profile card. See it live in the Artifacts panel. Copy the code.

  4. 4

    Cursor Agent → wire component to data

    Paste the component into components/ProfileCard.tsx. Then in Agent mode:

    Cursor Agent Prompt
    I pasted a ProfileCard component into components/ProfileCard.tsx Wire it up to Supabase: - Fetch the current user's profile from 'profiles' - Add TypeScript types for the profile object - Show a skeleton loader while fetching - Show an error state if fetch fails - Connect the edit button to an edit modal
  5. 5

    GitHub + Vercel → ship it

    git push origin main → Vercel detects the push → builds → deploys to production URL in ~30 seconds. No manual steps.

  6. 6

    Stripe → add billing

    Create products in Stripe Dashboard. Implement Checkout API route in Cursor. Test with stripe trigger checkout.session.completed. Switch to live keys to accept real payments.

Chapter 5

Database Strategy

Choosing the wrong database type is the most common early mistake. Here is exactly when to use what.

Database Types Compared

TypeBest ForToolsScale
Relational SQLStructured data, relationships, transactionsPostgreSQL (Supabase)100M+ rows
Document NoSQLFlexible schemas, nested JSONMongoDB, FirestoreGood; joins costly
Vector DBAI similarity search, embeddingsPinecone, pgvectorBillions of vectors
Key-Value CacheSessions, rate limiting, countersRedis, UpstashMillions ops/sec
Time-SeriesMetrics, analytics, IoTTimescaleDBTrillions of points
For 95% of SaaS apps: Start with PostgreSQL via Supabase. It handles relational data, JSON, full-text search, and even AI vector search with the pgvector extension. Add specialised databases only when you hit a real bottleneck.

📊 Large-Scale Database Patterns

Indexing Strategy

Single biggest performance win for tables with millions of rows.

PostgreSQL
-- Index foreign keys CREATE INDEX idx_orders_user_id ON orders(user_id); -- Composite for common filters CREATE INDEX idx_orders_status_date ON orders(status, created_at DESC); -- Partial index (active records only) CREATE INDEX idx_active_users ON users(email) WHERE deleted_at IS NULL;

Cursor Pagination

Never use OFFSET on large tables — it scans all previous rows.

Supabase
// ❌ SLOW on large tables SELECT * FROM posts LIMIT 20 OFFSET 10000; // ✓ FAST — cursor pagination const { data } = await supabase .from('posts') .select('*') .gt('id', lastSeenId) .order('id') .limit(20)

Redis Caching

🔗 upstash.com
Next.js + Upstash
import { Redis } from '@upstash/redis' const redis = new Redis({ url: process.env.UPSTASH_URL, token: process.env.UPSTASH_TOKEN, }) export async function getStats(userId) { const cached = await redis.get(`stats:${userId}`) if (cached) return cached const stats = await queryDB(userId) // Cache for 5 minutes await redis.setex( `stats:${userId}`, 300, stats) return stats }

Connection Pooling

Serverless functions create a new DB connection per request. Use Supabase's PgBouncer pooler to avoid hitting connection limits.

.env.local
# Supabase Dashboard: # Settings → Database # → Connection Pooling # Copy the POOLER string (not Direct) DATABASE_URL= "postgresql://postgres.xxx: [password]@aws-0-region .pooler.supabase.com:6543 /postgres?pgbouncer=true"
Chapter 6

Authentication System A→Z

Complete implementation: registration, login, logout, Google OAuth, 2FA TOTP, and Passkeys using Supabase Auth.

👤 Register
✉ Verify Email
🔑 Login
🛡 2FA
✓ Authenticated
🚪 Logout

Install & Configure

Terminal
npm install @supabase/supabase-js \ @supabase/ssr
.env.local
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGci...
lib/supabase.ts
import { createBrowserClient } from '@supabase/ssr' export function createClient() { return createBrowserClient( process.env .NEXT_PUBLIC_SUPABASE_URL!, process.env .NEXT_PUBLIC_SUPABASE_ANON_KEY! ) }

Register / Login / Google / Logout

Auth Actions (client component)
const supabase = createClient() // REGISTER await supabase.auth.signUp({ email, password, options: { emailRedirectTo: `${location.origin}/auth/callback` } }) // LOGIN await supabase.auth.signInWithPassword({ email, password }) // GOOGLE OAUTH // First: Supabase Dashboard → Auth → Providers → Google // Add Client ID + Secret from console.cloud.google.com await supabase.auth.signInWithOAuth({ provider: 'google', options: { redirectTo: `${location.origin}/auth/callback` } }) // LOGOUT await supabase.auth.signOut() router.push('/login')

Auth Callback Route (required for OAuth & email confirm)

app/auth/callback/route.ts
import { NextResponse } from 'next/server' import { createServerClient } from '@supabase/ssr' import { cookies } from 'next/headers' export async function GET(request: Request) { const code = new URL(request.url) .searchParams.get('code') if (code) { const supabase = createServerClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!, { cookies: { getAll() { return cookies().getAll() } } } ) await supabase.auth .exchangeCodeForSession(code) } return NextResponse.redirect( new URL('/dashboard', request.url)) }

🛡 2FA (TOTP) + Passkeys (WebAuthn)

TOTP — Google Authenticator / Authy

Supabase MFA
// Enroll — returns QR code const { data } = await supabase.auth.mfa.enroll({ factorType: 'totp' }) // Display data.totp.qr_code as img // User scans with authenticator app // Verify the 6-digit code const { data: ch } = await supabase.auth.mfa .challenge({ factorId: data.id }) await supabase.auth.mfa.verify({ factorId: data.id, challengeId: ch.id, code: userCode6Digits })

Passkeys — Face ID / Touch ID

🔗 simplewebauthn.dev
Client — Register Passkey
import { startRegistration } from '@simplewebauthn/browser' // 1. Get options from server const opts = await fetch('/api/passkey/options') .then(r => r.json()) // 2. Prompt Face ID / Touch ID const cred = await startRegistration(opts) // 3. Verify on server await fetch('/api/passkey/verify', { method: 'POST', body: JSON.stringify(cred) }) // User can now login with biometrics
Chapter 7

Stripe Payments — Complete Integration

Subscriptions, one-time payments, webhooks, and customer portal from scratch.

💡
Setup: stripe.com → create account → Dashboard → Developers → API Keys → copy secret key. Then: npm install stripe @stripe/stripe-js. Add STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET to .env.local.
🛒 Subscribe
🔗 Checkout Session
💳 Stripe page
✓ Success
🔔 Webhook
📦 DB updated

Checkout Session API Route

app/api/stripe/checkout/route.ts
import Stripe from 'stripe' const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!) export async function POST(req: Request) { const { priceId } = await req.json() const user = await getAuthUser() // Get or create Stripe customer let customerId = await getStripeCustomerId(user.id) if (!customerId) { const c = await stripe.customers.create({ email: user.email, metadata: { supabase_user_id: user.id } }) customerId = c.id await saveCustomerId(user.id, customerId) } const session = await stripe.checkout.sessions.create({ customer: customerId, line_items: [{ price: priceId, quantity: 1 }], mode: 'subscription', success_url: `${process.env.APP_URL}/dashboard?ok=1`, cancel_url: `${process.env.APP_URL}/pricing`, subscription_data: { metadata: { supabase_user_id: user.id } } }) return Response.json({ url: session.url }) } // Client — redirect to Stripe const { url } = await fetch('/api/stripe/checkout', { method: 'POST', body: JSON.stringify({ priceId: 'price_xxx' }) }).then(r => r.json()) window.location.href = url

🔔 Webhooks

Without webhooks your database will not update when users pay or cancel. This is the most critical part.

app/api/stripe/webhook/route.ts
export async function POST(req: Request) { const sig = headers().get('stripe-signature')! const event = stripe.webhooks.constructEvent( await req.text(), sig, process.env.STRIPE_WEBHOOK_SECRET! ) switch (event.type) { case 'checkout.session.completed': await setUserPlan(userId, 'pro'); break case 'customer.subscription.deleted': await setUserPlan(userId, 'free'); break case 'invoice.payment_failed': await sendFailedEmail(email); break } return new Response('OK') }
Test locally: stripe listen --forward-to localhost:3000/api/stripe/webhook then in a second tab: stripe trigger checkout.session.completed
Chapter 8

GitHub & GitLab — Version Control + Upload Your App

GitHub and GitLab are where your code lives in the cloud. They act as the source of truth that every deployment platform (Cloudflare, Vercel, Netlify) pulls from. Here is how to upload your W5-PNL Generator and manage it properly.

🔗 github.com 🔗 gitlab.com 🔗 GitHub docs

GitHub vs GitLab — Which Should You Use?

FeatureGitHubGitLab
Popularity★ Industry standard, largest communityStrong in enterprise
Cloudflare integration✓ Direct built-in Connect GitHub button✓ Also supported, Connect GitLab button
Vercel integration✓ Native, one-click✓ Supported
Free private reposUnlimitedUnlimited
Built-in CI/CDGitHub ActionsGitLab CI/CD (more powerful)
Best forSolo devs, open source, most tutorialsTeams, self-hosted, advanced pipelines
💡
Recommendation: Use GitHub. It is what you see in the Cloudflare screenshot (Connect GitHub button). It has the largest ecosystem, most tutorials reference it, and it works natively with Cloudflare, Vercel, and Cursor. GitLab is equally valid but GitHub is easier to start with.

🚀 Upload Your W5-PNL Generator to GitHub — Step by Step

Your app currently runs on Cloudflare but its source code probably only exists on your computer. GitHub is where you store and version that code so Cloudflare can pull it automatically on every update.

  1. 1

    Create a GitHub account and new repository

    Go to github.com → Sign up (free) → New Repository → Name it w5-pnl-generator → Set to Private → Do NOT add README yet → Create repository.

  2. 2

    Open Terminal in your project folder

    In Finder, navigate to the folder containing your W5 HTML/JS files. Right-click the folder → New Terminal at Folder. Or: cd /path/to/your/w5-project

  3. 3

    Initialise Git and connect to GitHub

    Terminal — run once per project
    # Initialise git in your project folder git init # Stage all your files git add . # Create first commit git commit -m "initial commit: W5 PNL Generator" # Link to your GitHub repo # (copy this URL from GitHub after creating the repo) git remote add origin git@github.com:YourUsername/w5-pnl-generator.git # Push to GitHub git branch -M main git push -u origin main
  4. 4

    Verify on GitHub

    Go to github.com → your repo. You should see all your files listed. Every future change: git add . && git commit -m "description" && git push

Daily Git Workflow

Terminal — daily commands
# Make changes to your files, then: git add . git commit -m "feat: add new route calculation" git push # For bigger features, use branches: git checkout -b feat/new-feature # ...make changes... git add . git commit -m "feat: description" git push origin feat/new-feature # Open Pull Request on GitHub → merge → Cloudflare auto-deploys # Commit conventions: # feat: new feature e.g. "feat: add PDF export" # fix: bug fix e.g. "fix: calculation rounding error" # chore: config changes e.g. "chore: update dependencies"
Chapter 9

Cloudflare Workers & Pages

Your W5-PNL Generator already runs on Cloudflare. Here is exactly what Cloudflare is, what you are using, and how to connect your GitHub repo so deployments happen automatically.

🔗 cloudflare.com 🔗 Workers docs 🔗 Pages docs

What Is Cloudflare? Two Products You Need to Know

Cloudflare Workers

Serverless JavaScript that runs at the edge (in 300+ data centres worldwide). Like AWS Lambda but faster and with a very generous free tier. Your W5 app likely runs as a Worker or is served via Workers.

100K req/day free
📄

Cloudflare Pages

Static site and JAMstack hosting. Connects directly to GitHub/GitLab. Every git push auto-deploys. Every PR gets a preview URL. This is what the screenshot you shared is showing — Create a Worker in Pages.

Unlimited requests free500 builds/mo free

⚖ Cloudflare vs GitHub — They Are Not Competitors

This is the most important thing to understand: GitHub stores your code. Cloudflare runs your code. They work together, not against each other.

PlatformWhat It DoesYour Code Lives Here?Runs Your App?
GitHubStores, versions, and backs up your source code✓ Yes — source of truth✕ No
GitLabSame as GitHub, different platform✓ Yes (alternative)✕ No
CloudflareDeploys and serves your app to users globally✕ Pulls from GitHub✓ Yes — runs it
VercelAlternative to Cloudflare for deploying apps✕ Pulls from GitHub✓ Yes — runs it
💡
The relationship: You push code to GitHub → Cloudflare detects the push → Cloudflare automatically pulls and deploys the new version. GitHub is the source, Cloudflare is the delivery. You need both.

Should You Switch from Cloudflare to GitHub? Do You Need To?

Short answer: No, do not switch away from Cloudflare. Cloudflare is excellent — it is fast, reliable, and the free tier is extremely generous. What you should do is add GitHub as the source so Cloudflare pulls from it. This gives you version control + automatic deploys.
FeatureCloudflare PagesVercel
Free tierUnlimited requests, 500 builds/mo100GB bandwidth, fair usage
Edge network300+ locations worldwide~70 regions
Static site hostingExcellent — purpose-builtExcellent
Next.js full-stackSupported but some caveatsNative, zero-config
Serverless functionsWorkers (extremely fast cold starts)Vercel Functions
Custom domains + SSLFree, built into Cloudflare DNSFree
Best forStatic apps, single-page apps like W5Next.js full-stack apps
💡
Bottom line for W5-PNL Generator: Stay on Cloudflare Pages — it is the right tool for a single HTML file app. If you later build a full Next.js app with Supabase, switch that new project to Vercel. Use both platforms for the right things.

🔗 Connect GitHub to Cloudflare — Exactly as Shown in Your Screenshot

This is the screen you photographed: Create a Worker → Ship something new. Here is the exact step-by-step to link your GitHub W5 repo.

  1. 1

    First: push W5 to GitHub

    Complete the GitHub upload steps in Chapter 8 above. Your W5 files must be in a GitHub repo before Cloudflare can find them.

  2. 2

    Go to Cloudflare Dashboard → Workers & Pages

    Log in at dash.cloudflare.com → Left sidebar → Workers & PagesCreate button → Pages tab (for static sites like W5).

  3. 3

    Click "Connect GitHub" (as in your screenshot)

    Click the Connect GitHub button. Cloudflare opens GitHub's OAuth page. Click Authorize Cloudflare Pages. Select which repos to grant access to — choose your W5 repo (or all repos).

  4. 4

    Select your repository

    Back in Cloudflare, you will see your GitHub repos listed. Click on w5-pnl-generatorBegin setup.

  5. 5

    Configure build settings

    For a plain HTML file (no build step needed):

    Cloudflare Pages Build Settings
    Project name: w5-pnl-generator Production branch: main Framework preset: None Build command: (leave empty) Build output dir: / (or . for root) Root directory: / (leave as root)

    If your file is named index.html in the root, Cloudflare serves it automatically. If it is named W5-PNL_Generator_v10.html, either rename it to index.html or set the output path.

  6. 6

    Save & Deploy

    Click Save and Deploy. Cloudflare pulls your code from GitHub and deploys it. You get a URL like w5-pnl-generator.pages.dev.

  7. 7

    Every git push now auto-deploys

    From now on: edit your file locally in Cursor → git push → Cloudflare automatically detects the push and deploys the new version within 60 seconds. No manual uploads needed.

📄 Alternative: Upload Static Files Directly (No GitHub)

You also see "Upload your static files" in the screenshot. This is the simplest option but has no auto-deploy — you manually upload each time you update.

Cloudflare Wrangler CLI — alternative deploy method
# Install Wrangler (Cloudflare CLI) npm install -g wrangler # Login wrangler login # Deploy a static folder to Cloudflare Pages wrangler pages deploy ./my-folder --project-name w5-pnl-generator # Or deploy a single file directly: wrangler pages deploy . --project-name w5-pnl-generator
⚠️
Use GitHub instead. Direct upload is fine for a one-off test but has no version history, no rollback, and no auto-deploy. The GitHub connection gives you all of those for free.

🔗 Connect GitLab to Cloudflare (same process, different button)

The screenshot shows both Connect GitHub and Connect GitLab buttons side by side. If you use GitLab instead:

  1. 1

    Push your code to GitLab

    Same as GitHub: git remote add origin git@gitlab.com:YourUsername/w5-pnl-generator.git then git push -u origin main

  2. 2

    Click "Connect GitLab" on the Cloudflare screen

    Cloudflare opens GitLab's OAuth page. Authorize → select your repo → configure build settings (same as above). Everything else is identical to the GitHub flow.

💡
GitHub vs GitLab for Cloudflare: Both work identically. GitHub is recommended because it is more commonly used in tutorials and has broader community support. If you already have a GitLab account, use that — it works just as well.
Chapter 10

Vercel Deployment

Zero-config deployment connected to GitHub. Every push to main deploys automatically in 30 seconds.

🔗 vercel.com 🔗 Vercel docs
  1. 1

    Connect GitHub repo

    vercel.com → New Project → Import Git Repository → select repo. Vercel auto-detects Next.js — zero config needed.

  2. 2

    Add environment variables

    Project Settings → Environment Variables. Copy everything from .env.local here. Encrypted at rest.

  3. 3

    Push and watch it deploy

    git push origin main → Vercel builds → deploys. Every PR also gets its own preview URL.

  4. 4

    Add custom domain

    Project Settings → Domains. Vercel handles SSL certificates automatically via Let's Encrypt.

⚡ Performance Best Practices

Always use next/image

Auto resizes, compresses, serves WebP/AVIF. Never use a raw img tag.

Default to Server Components

Only add 'use client' for interactivity. Less JS shipped = faster pages.

Cache expensive queries

Use unstable_cache for reads. Call revalidatePath after mutations.

Analyse your bundle

Run npx @next/bundle-analyzer to see what is bloating your JS. Use dynamic imports for heavy libraries.

Chapter 11

Build These Projects

Practice everything in this handbook by building these in order. Each introduces new concepts and builds on the last.

📷

Photography Client Portal

Clients log in, view galleries, approve shots. Auto-invoice on approval. File uploads with Supabase Storage.

StorageAuthStripe
✈️

Airport Ops Dashboard

Real-time flight status for ground operations. Role-based access, shift handover notes, Realtime subscriptions.

RealtimeRBAC
🤖

AI Chat App

ChatGPT-style app with streaming responses, history in Supabase, multiple models, usage limits per tier.

OpenAI APIStripe
💼

W5 PNL Generator SaaS

Your existing tool as multi-tenant SaaS. Organisation accounts, team members, subscription billing, PDF export.

Multi-tenantTeams
Chapter 12

6-Month Learning Roadmap

Realistic month-by-month progression from zero to shipping paid products.

  1. Month 1

    Foundation — macOS Setup, Git, GitHub, Vercel

    Complete Chapter 1 of this handbook. Create your first repo, deploy a Next.js site to Vercel, build a portfolio site. The goal: a live URL you can share.

    GitGitHubVercelNext.js basics
  2. Month 2

    Frontend — React, TypeScript, Tailwind, Cursor Pro

    React hooks (useState, useEffect, useContext). TypeScript types. Tailwind utility classes. Master Cursor Agent mode. Build UI components from Claude.ai prompts.

    ReactTypeScriptTailwindCursor
  3. Month 3

    Full Stack — Next.js App Router, API Routes, Server Actions

    Server vs client components. API routes. Server Actions for form submissions. Dynamic routes. Connect your first Supabase database. Build a simple data-driven app.

    App RouterAPI RoutesServer Actions
  4. Month 4

    Backend — Supabase, Auth, Storage, RLS

    Full auth system (email, Google, 2FA). Row-Level Security policies. File uploads via Storage. Build the Photography Portal project end-to-end.

    SupabaseRLSAuthStorage
  5. Month 5

    Monetisation — Stripe, Subscriptions, Webhooks

    Stripe Checkout. Subscription tiers. Webhook handler. Customer Portal. Gate features behind plan. Take your first real payment from a customer.

    StripeWebhooksSubscriptions
  6. Month 6

    Launch — AI Features, Performance, Mobile

    Integrate OpenAI or Claude API for AI features. Optimise performance scores. Add React Native / Expo for mobile. Launch your SaaS publicly and acquire first customers.

    OpenAI APIReact NativeLaunch 🚀
🎯
The rule: Build something real every month. Do not spend month 2 still watching tutorials. Debug real errors in real projects — that is how you actually learn. Use ChatGPT, Claude, and Cursor to get unstuck. That is what they are for.