Build a SaaS in a Weekend: Vibe Coding 2026
How to Build a SaaS in a Weekend with Vibe Coding + a Boilerplate in 2026
"Ship in a weekend" has been the indie hacker rallying cry for years. It used to be aspirational. In 2026, with the right boilerplate and an AI coding agent, it's a legitimate sprint methodology — not a shortcut, but a structured approach that lets a single developer ship a working SaaS product with auth, billing, and a core feature in 48 hours.
This guide is the actual weekend plan: what to buy, what tools to use, what to build on Friday, Saturday, and Sunday, and what "done" means by Sunday night.
TL;DR
Start with ShipFast or Open SaaS as your foundation. Use Cursor or Claude Code as your AI pair programmer. Ship one clearly-defined core feature — not a platform, not a suite. Saturday is for features, Sunday is for polish. By Sunday night, you should have a landing page, auth, Stripe billing, and one working feature a customer can pay for.
What You Need Before Friday Evening
The Boilerplate Decision
Your boilerplate choice determines how much Friday setup time you spend on infrastructure vs your product. The two best options for a weekend sprint:
ShipFast ($199) — fastest to clone-and-go. Single Next.js app, NextAuth, Stripe, Resend, Tailwind. No monorepo complexity. If you've never used it before, you'll have a working local environment in 45 minutes.
Open SaaS (free) — more features out of the box (admin dashboard, background jobs, analytics) but more complex to configure. Better if you've used it before or have 3+ hours for Friday setup.
For a first weekend sprint, ShipFast's simplicity wins even at $199. The goal of the weekend isn't to learn the boilerplate — it's to build your product.
The AI Coding Agent
Cursor is the most popular choice in 2026 for vibe coding. The Tab completion and Composer features handle first drafts of features effectively when your codebase has good TypeScript types (which both recommended boilerplates do).
Claude Code (Anthropic's terminal-based agent) is better for multi-file refactors and following CLAUDE.md context files. Open SaaS ships with an AGENTS.md file specifically for Claude Code.
Windsurf (formerly Codeium) is a strong alternative to Cursor with similar capabilities at a lower price point.
Pick one and stick with it for the weekend. Switching agents mid-sprint costs time.
The Product Requirement
Write this before Friday evening: one sentence describing what a customer can do with your product that they'll pay for.
Not: "An AI tool for marketers" Yes: "Generate SEO-optimized blog posts from a URL in under 60 seconds for $29/month"
Not: "A project management tool" Yes: "Track freelance client projects and auto-generate invoices when tasks are marked complete"
The sentence must be concrete enough that you can build it in two days. "AI content generator" requires the entire weekend to define scope. "Generate 5-bullet LinkedIn posts from a pasted URL for $9/month" is buildable in 6 hours.
Friday Evening: Environment and Foundation (3–4 hours)
Hour 1: Clone and Configure
# Clone ShipFast
git clone https://github.com/your-shipfast-copy.git my-saas
cd my-saas
npm install
# Configure environment
cp .env.example .env.local
Open .env.local and fill in:
NEXTAUTH_SECRET=generate-with-openssl-rand-hex-32
GOOGLE_ID=your-google-oauth-client-id
GOOGLE_SECRET=your-google-oauth-client-secret
MONGODB_URI=your-mongodb-atlas-uri
# OR
DATABASE_URL=your-postgres-uri
RESEND_API_KEY=your-resend-key
EMAIL_FROM=noreply@yourdomain.com
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
NEXTAUTH_URL=http://localhost:3000
Services to set up on Friday:
- Google OAuth: console.cloud.google.com → New project → OAuth client ID (15 min)
- MongoDB Atlas or Neon Postgres: free tier, create database (10 min)
- Resend: resend.com → free tier → API key (5 min)
- Stripe test mode: stripe.com → activate test mode → get keys (5 min)
npm run dev
# Should be running at localhost:3000
First sanity check: sign in with Google, confirm session persists, confirm you reach the dashboard. If this doesn't work, fix it before Saturday.
Hour 2: Set Your Stripe Product
In Stripe test mode, create the product and pricing:
# Use Stripe CLI to create a product (or do it in the dashboard)
stripe products create --name "My SaaS Pro" --description "One product, one price"
stripe prices create \
--unit-amount 2900 \
--currency usd \
--recurring interval=month \
--product prod_xxxx
Update the price ID in config.ts (or wherever ShipFast stores pricing):
// config.ts
export const config = {
stripe: {
plans: [
{
priceId: "price_xxxx", // your Stripe price ID
name: "Pro",
price: 29,
description: "Everything you need",
features: ["Feature 1", "Feature 2", "Feature 3"],
},
],
},
};
Test the full billing flow:
- Sign in
- Click upgrade
- Use Stripe test card:
4242 4242 4242 4242, any future date, any CVC - Confirm you land on the success page
- Check Stripe dashboard for the test payment
If billing doesn't work on Friday night, fix it. Billing is the one non-negotiable foundation.
Hour 3: Configure Your AI Agent
Create a .cursorrules (for Cursor) or CLAUDE.md (for Claude Code) that describes your product:
# CLAUDE.md
## Project
[Your product name] — [one-sentence description from your product requirement above]
## Tech Stack
- Next.js 15 App Router
- TypeScript
- Tailwind CSS + shadcn/ui
- NextAuth v5 (authentication)
- Prisma + Postgres (or Mongoose + MongoDB)
- Stripe (billing)
- Resend (email)
## Current Sprint Goal
Build [the specific feature from your product requirement].
## Key Files
- app/(dashboard)/dashboard/page.tsx — main authenticated view
- app/api/ — API routes
- lib/db.ts — database client
- models/ — data models
## Rules
- Always use TypeScript with explicit types
- Use server components where possible; client components only when needed
- All API routes must check authentication
- Use existing UI components from components/ui/ — don't add new ones
- Don't add new dependencies without asking
This context file is what makes AI-assisted coding work well in your boilerplate. Without it, the AI doesn't know your stack and generates generic code that doesn't integrate with your existing auth/db/ui patterns.
Hour 4: Design the Data Model
Before Saturday's feature work, write the schema for your core feature:
// schema.ts (Drizzle) or schema.prisma (Prisma)
// Example: blog post generator SaaS
export const generations = pgTable("generations", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
userId: text("user_id").notNull().references(() => users.id),
inputUrl: text("input_url").notNull(),
output: text("output"),
status: text("status").notNull().default("pending"), // pending | processing | complete | error
createdAt: timestamp("created_at").defaultNow(),
tokensUsed: integer("tokens_used"),
});
Ask Cursor to generate the migration:
"Generate a Drizzle migration for this schema and the TypeScript types for creating and reading generations"
Run the migration before Saturday. Schema migrations mid-sprint cause context-switching you can't afford.
Saturday: Build Your Core Feature (8–10 hours)
Saturday is the single most important day. The goal: a working end-to-end feature that a subscribed user can use.
Morning Session (4 hours): Backend
Session 1 (2 hours): Build the API route for your core feature.
Use Cursor Composer or Claude Code with a specific prompt. Don't ask it to "build the feature" — that's too broad. Give it one specific piece:
"In
app/api/generate/route.ts, create a POST route that:
- Validates the user is authenticated (use the existing auth from
lib/auth.ts)- Checks the user has an active Stripe subscription (check the
subscriptionfield in the user model)- Accepts
{ url: string }in the request body- Fetches the URL content using fetch()
- Calls OpenAI GPT-4o to generate a blog post outline from the content
- Saves the result to the
generationstable- Returns
{ id: string, output: string }Match the TypeScript patterns used in the existing API routes."
Review what it generates. The most common issues:
- It forgets to check authentication → add the auth check
- It uses
anytypes → fix to proper types - It doesn't handle errors → add try/catch
- It makes up imports that don't exist → fix to real imports
Session 2 (2 hours): Build any background processing if your feature requires it.
For async features (generation takes >5 seconds), add a queue-based pattern:
// If using Inngest (included in MakerKit):
export const generateContent = inngest.createFunction(
{ id: "generate-content" },
{ event: "app/generation.requested" },
async ({ event }) => {
const { generationId, url } = event.data;
// ... long-running processing
}
);
Afternoon Session (4 hours): Frontend
Session 3 (2 hours): Dashboard UI
Prompt Cursor with the specific UI you need:
"In
app/(dashboard)/dashboard/page.tsx:
- Show a list of the user's past generations from the API
GET /api/generations- Add a form at the top with a URL input and a 'Generate' button
- When submitted, POST to
/api/generateand show a loading state- On success, add the new generation to the top of the list
- Each generation shows the input URL, a truncated preview of the output, and a 'Copy' button Use the existing shadcn/ui components: Card, Input, Button, Textarea"
Important: specify existing components. If you let the AI pick, it'll invent new component patterns that don't match your boilerplate's style.
Session 4 (2 hours): Polish, edge cases, and integration testing
Walk through your full user flow manually:
- Sign up as a new user → should land on dashboard
- Try to use the feature without subscribing → should see upgrade prompt
- Subscribe → should unlock the feature
- Use the feature → should work end-to-end
- Check usage limits if applicable → should block at limit
Fix every broken step before Sunday.
Sunday: Landing Page, Polish, and Deploy (6–8 hours)
Sunday is about making the product presentable to real users, not building more features.
Morning Session (3 hours): Landing Page
The ShipFast landing page template is already in your repo. Update it for your product:
// components/landing/Hero.tsx — update copy
const hero = {
headline: "Generate SEO Blog Posts From Any URL in 60 Seconds",
subheadline: "Paste a URL, get a complete 1,500-word blog post draft.
Optimized for SEO, ready to publish.",
cta: "Start Free — 3 Posts Included",
};
What to focus on in the landing page:
- One clear headline stating what the product does (not "AI-powered" — what does it do?)
- The specific output/result the user gets
- Social proof if you have any (even beta testers' quotes)
- Pricing table with your Stripe product
- A "how it works" section (3 steps maximum)
Ask Cursor to add any missing sections by referencing ShipFast's existing component patterns.
Midday Session (2 hours): Staging Deploy and Testing
Deploy to Vercel (staging environment):
# Deploy to Vercel
vercel --prod
# or push to main branch if you've configured Vercel GitHub integration
# Update environment variables in Vercel dashboard
# Critical: NEXTAUTH_URL must be your Vercel URL, not localhost
Test every flow on staging with real Stripe test cards. The transition from localhost to a real URL catches:
- NEXTAUTH_URL misconfigurations
- Stripe webhook URLs (update in Stripe dashboard to point to Vercel URL)
- OAuth redirect URIs (add Vercel URL to Google OAuth console)
# Set up Stripe webhook for staging
stripe listen --forward-to https://your-app.vercel.app/api/stripe/webhook
Afternoon Session (2 hours): Go Live
Switch to production environment variables:
# Production stripe keys
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_live_...
# Set up production Stripe webhook:
# Stripe Dashboard → Webhooks → Add endpoint
# URL: https://your-domain.com/api/stripe/webhook
# Events: checkout.session.completed, customer.subscription.updated,
# customer.subscription.deleted
Do the final manual walkthrough on production:
- Create a real account (use your own email)
- Make a real $1 payment (use a real card — charge yourself $1)
- Verify the feature works in production
- Verify the Stripe webhook fires correctly (check Stripe dashboard)
Final Hour: Announce
Post on X/Twitter, Indie Hackers, and relevant Reddit communities (r/SaaS, r/indiehackers, r/webdev):
"Built [Product Name] in a weekend — [one-sentence description]. Free trial included, $29/month after. Would love feedback: [URL]"
The launch matters as much as the product. A working product nobody knows about ships Monday right back into obscurity.
What "Done" Looks Like at Sunday 11pm
Working:
- Landing page with your product's value proposition
- Email/password and Google sign-in
- Stripe checkout — user can pay
- One core feature that works end-to-end for a paying user
- Stripe Customer Portal — user can cancel their subscription
- Basic transactional email (welcome email, receipt)
- Deployed to production with a real domain
Not required this weekend:
- Admin dashboard
- Analytics
- Multiple features
- Mobile optimization (fix next week)
- Blog
- Documentation
The best SaaS products started as one-feature tools. Basecamp, Notion, and Linear all shipped with a single core workflow. Scope control is the skill the weekend sprint teaches.
Common Weekend Fail Modes
Scope creep on Saturday: You're 3 hours in and adding a second feature because the first one "feels too small." Stop. Finish the first feature completely before adding anything.
Perfectionism on Sunday: The UI isn't good enough, so you spend 4 hours on animations. Ship the ugly version. Users care about function.
Auth issues blocking everything: Test auth on Friday night. If sign-in is broken, fix it before sleeping. Auth problems multiply throughout the weekend.
Deploying for the first time on Sunday: The environment variable configuration for production almost always has at least one issue. Deploy to staging on Saturday afternoon.
See the best boilerplates for vibe coding for the full AI-optimized boilerplate list, or browse all Next.js starters on StarterPick. Read ShipFast review 2026 if you're choosing your foundation.