What you're looking at
This is a free preview of the Startup Boilerplate Bundle—a production-ready SaaS starter kit for technical founders. Below you'll find excerpts from the README, the project directory tree, and a real NextAuth.js configuration snippet.
The full bundle includes 9 deliverables covering everything you need to ship your first SaaS product:
- Authentication system (OAuth + email)
- Stripe payments & subscriptions
- 60+ polished UI components
- Database schema & migrations
- API route patterns & middleware
- Email templates (transactional)
- Admin dashboard scaffolding
- Testing setup (unit + E2E)
- Deploy configs (Vercel & Docker)
README
README.mdProject Overview
The Startup Boilerplate Bundle is a full-stack SaaS starter built with Next.js 14 (App Router). It gives technical founders a production-grade codebase so you can skip months of scaffolding and start building your actual product on day one.
Authentication, payments, database models, UI components, and deployment pipelines are pre-wired and tested. Every file is documented with inline comments explaining the why behind each decision.
Tech Stack
Quick Start
- Clone the repo and install dependencies with pnpm install
- Copy .env.example to .env.local and fill in your API keys
- Run pnpm db:push to initialize the database schema
- Run pnpm dev to start the development server on localhost:3000
- Visit /api/auth/signin to test OAuth sign-in
git clone https://github.com/your-org/saas-boilerplate.git cd saas-boilerplate pnpm install cp .env.example .env.local pnpm db:push pnpm dev
Project Structure
directory treeA clean, modular layout designed for scalability. Every directory has a single responsibility.
saas-boilerplate/ ├── app/ │ ├── (auth)/ │ │ ├── login/page.tsx │ │ ├── register/page.tsx │ │ └── layout.tsx │ ├── (dashboard)/ │ │ ├── overview/page.tsx │ │ ├── settings/page.tsx │ │ ├── billing/page.tsx │ │ └── layout.tsx │ ├── api/ │ │ ├── auth/[...nextauth]/route.ts │ │ ├── webhooks/stripe/route.ts │ │ └── trpc/[trpc]/route.ts │ ├── layout.tsx │ ├── page.tsx │ └── globals.css ├── components/ │ ├── ui/ # 60+ reusable UI components │ ├── forms/ # Form components with Zod validation │ ├── layouts/ # Page layout wrappers │ └── providers/ # Context providers (theme, auth, etc.) ├── lib/ │ ├── auth.ts # NextAuth config (shown below) │ ├── prisma.ts # Prisma client singleton │ ├── stripe.ts # Stripe client + helpers │ └── utils.ts # Shared utility functions ├── prisma/ │ ├── schema.prisma # Database models │ └── migrations/ # SQL migration history ├── emails/ # React Email templates ├── tests/ │ ├── unit/ # Vitest unit tests │ └── e2e/ # Playwright E2E tests ├── .env.example ├── docker-compose.yml ├── tailwind.config.ts ├── tsconfig.json └── package.json
Auth Setup
lib/auth.tsNextAuth.js v5 configuration with Google and GitHub OAuth providers, Prisma session adapter, and JWT callbacks for role-based access control.
import NextAuth from "next-auth" import { PrismaAdapter } from "@auth/prisma-adapter" import Google from "next-auth/providers/google" import GitHub from "next-auth/providers/github" import { prisma } from "@/lib/prisma" export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: PrismaAdapter(prisma), session: { strategy: "jwt" }, providers: [ Google({ clientId: process.env.GOOGLE_CLIENT_ID!, clientSecret: process.env.GOOGLE_CLIENT_SECRET!, allowDangerousEmailAccountLinking: true, }), GitHub({ clientId: process.env.GITHUB_CLIENT_ID!, clientSecret: process.env.GITHUB_CLIENT_SECRET!, }), ], callbacks: { // Attach user ID and role to the JWT token async jwt({ token, user }) { if (user) { token.id = user.id // Fetch role from database on first sign-in const dbUser = await prisma.user.findUnique({ where: { id: user.id }, select: { role: true }, }) token.role = dbUser?.role ?? "user" } return token }, // Expose user ID and role in client-side session async session({ session, token }) { if (session.user) { session.user.id = token.id as string session.user.role = token.role as string } return session }, // Redirect to dashboard after successful sign-in async redirect({ url, baseUrl }) { if (url.startsWith(baseUrl)) return url if (url.startsWith("/")) return `${baseUrl}${url}` return `${baseUrl}/dashboard/overview` }, }, pages: { signIn: "/login", error: "/login?error=true", }, })
Ready to skip the scaffolding?
Get the full Startup Boilerplate Bundle with all 9 deliverables—auth, payments, 60+ UI components, database models, email templates, tests, and deploy configs.
Get the full Startup Boilerplate Bundle — $79 One-time purchase · Lifetime updates · MIT license