DEV Community

Cover image for I Built a Next.js SaaS Boilerplate So You Don't Have To - 3 Month Journey
Muhammad Zubair
Muhammad Zubair

Posted on • Edited on

I Built a Next.js SaaS Boilerplate So You Don't Have To - 3 Month Journey

๐ŸŽ‰ UPDATE: This article got noticed by the official @thepracticaldev Twitter account!

Thanks for the support, Dev.to community! ๐Ÿ™Œ

๐Ÿ”ฅ EARLY BIRD SPECIAL: First 10 buyers get $99 instead of $149!

Use code EARLYBIRD at checkout. Limited spots!

Get it here โ†’


After spending 3 months building, debugging, and deploying, I finally launched FreelanceHub - a production-ready Next.js SaaS boilerplate.

๐Ÿค” Why I Built This

I kept rebuilding the same features across different projects:

  • Authentication flows (email, OAuth, sessions)
  • Payment processing (Stripe, webhooks, subscriptions)
  • Database setup (schema, migrations, queries)
  • Client management (CRUD operations)
  • Modern UI components

Every project took 2-3 months just to get the foundation working. I realized I could package everything into a reusable starter kit.


๐Ÿš€ What's Included

Authentication

  • Clerk integration (email, OAuth, magic links)
  • Protected routes
  • User profile management
  • Session management

Payments

  • Stripe checkout + subscriptions
  • Webhook handling
  • Customer portal
  • Multiple pricing tiers

Database

  • PostgreSQL with Prisma ORM
  • Type-safe queries
  • Migration scripts
  • Optimized schema

UI/UX

  • Beautiful dark theme
  • shadcn/ui components
  • Fully responsive design
  • Loading states & error handling

Features

  • Client CRM with CRUD
  • Time tracking system
  • Dashboard with analytics
  • Settings & profile management

๐Ÿ’ป Tech Stack

  • Framework: Next.js 16 with App Router
  • Language: TypeScript
  • Styling: Tailwind CSS + shadcn/ui
  • Database: PostgreSQL + Prisma
  • Auth: Clerk
  • Payments: Stripe
  • Deployment: Netlify (but works on Vercel, Railway, etc.)

๐Ÿ˜ค The Hard Lessons

1. Vercel + Clerk Edge Runtime Issues

Ran into major compatibility problems with Clerk middleware on Vercel's Edge runtime. After days of debugging, switched to Netlify and everything worked perfectly.

Takeaway: Not all hosting platforms handle middleware the same way!

2. Stripe Webhooks Are Tricky

Testing webhooks locally was painful until I discovered Stripe CLI. Game changer for development.

stripe listen --forward-to localhost:3000/api/stripe/webhooks
Enter fullscreen mode Exit fullscreen mode

3. Database Migrations in Production

Learned the hard way that Prisma needs prisma generate in the build process on CI/CD platforms. Added to build script:

"build": "prisma generate && next build"
Enter fullscreen mode Exit fullscreen mode

4. useSearchParams Needs Suspense

Next.js 16's stricter rendering rules caught me. Had to wrap client components using useSearchParams() in Suspense boundaries.


๐ŸŽฏ What Makes It Different

It's production-ready, not just a template:

  • โœ… Actually deployed and tested
  • โœ… Handles edge cases
  • โœ… Includes error boundaries
  • โœ… Proper loading states
  • โœ… TypeScript throughout
  • โœ… Comprehensive documentation

๐Ÿ“Š Live Demo

Check it out: FreelanceHub Demo

The demo showcases:

  • Responsive landing page
  • Feature sections
  • Pricing tiers
  • FAQ section

๐Ÿค“ Technical Deep Dive

Project Structure

โ”œโ”€โ”€ app/                    # Next.js 16 App Router
โ”‚   โ”œโ”€โ”€ api/               # API routes
โ”‚   โ”œโ”€โ”€ dashboard/         # Protected pages
โ”‚   โ””โ”€โ”€ (public)/          # Public pages
โ”œโ”€โ”€ components/            # React components
โ”œโ”€โ”€ lib/                   # Utilities & configs
โ”œโ”€โ”€ prisma/               # Database schema
โ””โ”€โ”€ public/               # Static assets
Enter fullscreen mode Exit fullscreen mode

Key Features Implementation

Authentication Flow:

  • Clerk handles all auth UI
  • Middleware protects routes
  • User data synced to database

Payment Flow:

  • Stripe Checkout for subscriptions
  • Webhooks update user plan in DB
  • Customer portal for management

Database Schema:

  • User โ†’ Clients (one-to-many)
  • Client โ†’ TimeEntries (one-to-many)
  • Prisma relations handle cascading

๐Ÿ’ก What I'd Build Next

If I continue developing this:

  1. Invoice generation (PDF exports)
  2. Email notifications (Resend integration)
  3. Team collaboration features
  4. API for third-party integrations
  5. Mobile app (React Native?)

๐Ÿ™ Feedback Welcome

I'd love to hear your thoughts:

  • Is the tech stack solid?
  • What features would you add?
  • Any architecture improvements?

Also curious about pricing. I set it at $149 (one-time payment). Too high? Too low? Fair?


๐Ÿ”— Links


๐Ÿ’ฌ Let's Discuss!

Questions for the community:

  • Have you built a SaaS boilerplate? What stack did you use?
  • What's your biggest pain point when starting new projects?
  • Would you pay for a starter kit to save time?

Drop a comment - I'd love to hear your thoughts! ๐Ÿ‘‡

๐ŸŽ‰ Final Thoughts

Building this taught me more than any tutorial ever could. The deployment issues, payment integration challenges, and edge cases forced me to really understand the stack.

If you're building a SaaS and want to skip the boring setup part, check it out! And if you have questions about the implementation, happy to answer in the comments! ๐Ÿš€


๐ŸŽ Early Bird Special

First 10 developers: $99 (Save $50!)

Use code: EARLYBIRD at checkout

After 10 spots โ†’ $149

Get it: https://zubairian6541.gumroad.com/l/vhtfwp

Spots remaining: 10/10 โšก


Thanks for reading! Follow me for more dev content! โœจ

Top comments (3)

Collapse
 
nedcodes profile image
Ned C

three months on a boilerplate is real commitment. the auth + payments + email combo is always the part that takes longest because every provider has its own quirks.

curious about the App Router patterns you settled on. did you go with Server Components for most pages and only use client components for interactive pieces? thats the pattern ive seen work best but a lot of boilerplates still mix the two in weird ways.

also, how are you handling the caching strategy? revalidatePath vs revalidateTag vs time-based has been one of the trickier decisions in App Router projects for me.

Collapse
 
muhammadzubair profile image
Muhammad Zubair

Great questions! Really appreciate the thoughtful engagement ๐Ÿ™

Server vs Client Components:

You nailed it - I use Server Components by default for most pages, only dropping to client when absolutely needed (forms, modals, interactive state).

Pattern I settled on:

  • Page routes = Server Components (data fetching, auth checks)
  • Interactive widgets = Client Components (marked with 'use client')
  • Shared layouts = Server (sidebar, headers stay server-side)

The biggest win was keeping data fetching in Server Components and passing props down. Keeps the client bundle tiny.

Caching Strategy:

This was tricky! Here's what I landed on:

  • revalidatePath: For user actions (CRUD operations on clients, time entries)
  • revalidateTag: For related data (when updating a client, revalidate all client lists)
  • Time-based: Dashboard stats (revalidate every 60s, don't need instant updates)

Example:

// After creating a client
revalidatePath('/dashboard/clients')
revalidateTag('client-list')
Enter fullscreen mode Exit fullscreen mode

Still iterating on this though - it's one of those things that looks simple but has edge cases everywhere ๐Ÿ˜…

The Auth + Payments combo:

You're so right about provider quirks! Clerk's middleware + Stripe webhooks took me a WEEK to get right. The webhook signature verification alone...

Are you working on something similar? Would love to hear what patterns you're using!

Also - I'm looking for 3 beta testers if you're interested in diving deeper: dev.to/muhammadzubair/looking-for-...

Thanks again for the detailed comment! ๐Ÿš€

Collapse
 
muhammadzubair profile image
Muhammad Zubair

Quick update: Getting great feedback!

Anyone have questions about the implementation?
Happy to do a deep dive on any part of the stack! ๐Ÿš€