Vibe Coding 2026: Build a SaaS with Claude Code Without Writing Most of the Code

Vibe Coding 2026: Build a SaaS with Claude Code Without Writing Most of the Code

Andrej Karpathy coined the term "vibe coding" in early 2025 to describe a new mode of software development: you describe your intent, an AI agent writes the code, and you steer rather than type. A year later, the tooling has matured enough that a solo developer can ship a functioning SaaS MVP in a single day using Claude Code as their pair programmer.

This is a practical vibe coding tutorial. By the end you will have a working link-shortener SaaS — FastAPI backend, React frontend, Stripe payments, JWT auth — and a clear mental model for when to let Claude Code run and when to grab the wheel yourself.


1. What Vibe Coding Is (and Isn't)

Vibe coding is not "AI writes everything while you sleep." You are still the architect. The division of labour looks like this:

Your job

  • High-level decisions: which endpoints, which data model, which third-party services
  • Context engineering: telling Claude Code what conventions and constraints to follow
  • Review: reading generated code for correctness and security issues
  • Testing: verifying the app actually works as intended

Claude Code's job

  • Boilerplate: project scaffolding, config files, dependency setup
  • Implementation: turning a well-described requirement into working code
  • Debugging: iterating on error messages until tests pass
  • Refactoring: restructuring code you review and approve

The productivity gain comes from eliminating the mechanical typing that consumes most of a developer's day, not from removing judgment from the process.


2. What We're Building: A Simple Link Shortener SaaS

The project is small enough to finish in one session but covers every layer of a real SaaS product:

  • Backend: FastAPI + SQLite (trivially swappable for Postgres)
  • Frontend: React with shadcn/ui components
  • Payments: Stripe Checkout, $5/month subscription
  • Auth: JWT-based login and signup

Free users get 10 shortened links per day. Paid users get unlimited. This is a simple but realistic business model that exercises the most common SaaS integration points.


3. Setup: Install Claude Code

Claude Code runs in your terminal and operates on your local files. Install it with:

npm install -g @anthropic-ai/claude-code

Authenticate once with your Anthropic API key:

claude login

Then open your project directory and start a session:

mkdir linkshort && cd linkshort
claude

Claude Code can read and write files, run shell commands, and maintain context across a conversation. It works best when you give it a clear project-level specification before asking it to write any code.


4. Context Engineering First (the Secret to Vibe Coding Success)

The single biggest determinant of vibe coding quality is the quality of the context you provide before writing a line of code. Claude Code reads a CLAUDE.md file in your project root and uses it as persistent instructions for the entire session.

Create this file first. Every minute spent on it saves ten minutes of corrections later.

Here is a real CLAUDE.md for this project:

# LinkShort — Project Context

## Stack
- Backend: Python 3.12, FastAPI, SQLAlchemy (SQLite in dev, Postgres in prod), Alembic
- Frontend: React 18, TypeScript, Vite, shadcn/ui, TanStack Query
- Auth: JWT (python-jose), bcrypt for password hashing
- Payments: Stripe Checkout Sessions

## Code Style
- Python: Black formatter, type hints everywhere, no bare `except`
- TypeScript: strict mode enabled, prefer named exports
- Tests: pytest for backend (aim for 80% coverage), Vitest for frontend

## What NOT to Do
- Do not use global state in FastAPI (use dependency injection)
- Do not store secrets in code; read from environment variables only
- Do not run database migrations automatically on startup
- Do not use `any` type in TypeScript without a comment explaining why
- Do not write raw SQL unless SQLAlchemy ORM cannot express the query

## Project Structure
backend/
  app/
    main.py
    models.py
    schemas.py
    routers/
    services/
frontend/
  src/
    components/
    pages/
    hooks/

This file tells Claude Code what you care about before it touches a single file. It also acts as a checklist when you review generated code.


5. Vibe Coding the Backend

The First Prompt

With CLAUDE.md in place, start with a concrete, scoped prompt:

Create a FastAPI app following the project structure in CLAUDE.md.
Implement two endpoints:
- POST /shorten — accepts a URL, returns a short code
- GET /r/{code} — redirects to the original URL

Use SQLite with SQLAlchemy. Add a User model and Link model.
Links belong to a user. Store created_at and click_count on each link.

Claude Code will scaffold backend/, generate the models, write the router, and create a requirements.txt. This takes about 90 seconds and produces roughly 300 lines of code you would otherwise type by hand.

What to Review

After generation, read these specific sections:

  1. The SQLAlchemy models — verify column types, nullable constraints, and that the foreign key relationship is correct.
  2. The router — check that the 404 case for unknown short codes is handled and that URL validation rejects clearly malformed input.
  3. The requirements — confirm you recognise every dependency. Unknown packages are a red flag.

Do not skip the review step because the code looks plausible. Claude Code occasionally generates code that compiles but has subtle logic errors, especially around edge cases like empty inputs or concurrent writes.

Iterating

Once the basic endpoints work, add constraints with follow-up prompts:

Add rate limiting to /shorten. Free users (is_subscribed=False) are limited
to 10 links per day. Count links created today in the database.
Return HTTP 429 with a descriptive message when the limit is exceeded.
Add a test for this in tests/test_links.py.

The prompt → code → review loop is the core of the vibe coding workflow. Keep prompts scoped to one feature. Long, multi-feature prompts produce harder-to-review code.


6. Vibe Coding the Frontend

Building the UI

Start the frontend session with a scoped prompt:

Create a React + TypeScript + Vite app in frontend/.
Use shadcn/ui. Implement one page with:
- A text input for the URL to shorten
- A Button that calls POST /shorten
- A table showing the user's links (short code, original URL, click count, created date)
Use TanStack Query for data fetching. Show a loading state and error state.

Claude Code will initialise the Vite project, install shadcn/ui, and generate the component. The result will be functional but unstyled beyond shadcn defaults.

Refining the UI

Follow up with targeted style and UX prompts:

Add shadcn/ui Button and Input components to the shorten form.
Show a toast notification when a link is created successfully.
Add a copy-to-clipboard button in the links table.

Keep UI prompts small and visual. It is faster to describe one interaction at a time and review the result than to request an entire design in one shot.


7. Adding Stripe Payments (the Tricky Part)

Stripe integrations have enough surface area that you need to engineer the prompt carefully rather than being vague.

Add Stripe Checkout to the backend.
- New endpoint: POST /billing/checkout — creates a Stripe Checkout Session
  for a $5/month subscription (price ID from env var STRIPE_PRICE_ID).
  Return the session URL.
- New endpoint: POST /billing/webhook — handles Stripe webhooks.
  On checkout.session.completed, set user.is_subscribed=True.
  On customer.subscription.deleted, set user.is_subscribed=False.
- Read STRIPE_SECRET_KEY and STRIPE_WEBHOOK_SECRET from environment variables.
- Add stripe to requirements.txt.
Do not hardcode any keys. Do not auto-redirect; return the URL to the frontend.

The frontend prompt follows the same pattern:

Add a "Upgrade to Pro — $5/month" button to the dashboard.
On click, call POST /billing/checkout and redirect window.location to the returned URL.

After generation, manually review the webhook handler before running it. Verify that the webhook signature is validated using stripe.Webhook.construct_event, which prevents replay attacks. This is security-critical code and the place where a missed review has the highest cost.


8. When to Intervene Manually

Vibe coding has failure modes. Knowing them in advance prevents expensive mistakes.

Security code: always review auth and payments manually. Password hashing, JWT signing, Stripe webhook validation — these are the sections where a subtle error means data breaches or billing fraud. Read this code line by line, every time.

Complex business logic with state machines. If your requirement involves multiple states and transitions (subscription → trial → cancelled → reactivated), Claude Code tends to produce code that handles the happy path but misses edge-case transitions. Map the state machine yourself first, then describe each transition explicitly in your prompt.

Database migrations. Never let Claude Code run alembic upgrade head against a production database. Generate the migration file, read it, and run it manually. One destructive migration cannot be undone with a prompt.

When tests fail repeatedly. If Claude Code cannot fix a failing test after two or three iterations, stop and diagnose the root cause yourself. Letting an agent iterate blindly on a misunderstood failure tends to produce increasingly convoluted workarounds rather than a correct fix.


9. Deploying the SaaS

Railway and Render both support one-command deploys from a Git repository with environment variable configuration in the dashboard.

For Railway:

railway login
railway init
railway up

Set your environment variables (DATABASE_URL, SECRET_KEY, STRIPE_SECRET_KEY, STRIPE_PRICE_ID, STRIPE_WEBHOOK_SECRET) in the Railway dashboard. Railway will detect the FastAPI app via the requirements.txt and start it with uvicorn.

For the frontend, vite build produces a static dist/ directory that deploys to any CDN (Cloudflare Pages, Vercel, Netlify) in one push.

Before deploying, ask Claude Code to do a final sweep:

Review the codebase for obvious security issues:
hardcoded secrets, missing input validation, SQL injection risks,
unauthenticated endpoints that should require auth.
List any findings.

Read the output critically and act on anything flagged.


10. FAQ

How much does this cost in API credits? A full session building this project typically uses $3–$8 in Claude API credits, depending on how much iteration you do. This is negligible compared to the time saved.

Can I use Claude Code with an existing codebase? Yes. Create a CLAUDE.md that describes the existing conventions and point Claude Code at specific files. It works better on well-structured codebases where the intent is clear from the code itself.

What happens when Claude Code generates broken code? Paste the error message back into the session with a brief description of what you expected. Claude Code usually fixes compilation and runtime errors on the first or second attempt. If it cannot, the root cause is almost always an unclear or contradictory requirement — fix the prompt, not the code.

Is vibe coding appropriate for production systems? With disciplined review, yes. The code Claude Code generates is not structurally different from code a human writes. The risk comes from reviewing too quickly, not from AI authorship itself. Apply the same standards you would to a code review from a junior developer: check correctness, security, and edge cases before merging.

Should I commit the generated code as-is? Treat it like any other code: run the tests, read the diff, commit what you understand and trust. The commit history is yours regardless of who typed the characters.


Vibe coding in 2026 is a genuine productivity multiplier, not a shortcut around understanding your system. Claude Code handles the mechanical work so you can spend your time on the decisions that actually require judgment. The developers getting the most out of it are not the ones who prompt and ship — they are the ones who review carefully, iterate quickly, and know exactly when to take the keyboard back.

Leonardo Lazzaro

Software engineer and technical writer. 10+ years experience in DevOps, Python, and Linux systems.

More articles by Leonardo Lazzaro