mickasmt/next-saas-stripe-starter

Open-source SaaS Starter with User Roles & Admin Panel. Built using Next.js 14, Prisma, Neon, Auth.js v5, Resend, React Email, Shadcn/ui, Stripe, Server Actions.

2,978 stars TypeScript 9 components

Creates authenticated SaaS applications with user management, billing, and marketing pages

Users enter through marketing pages, authenticate via Auth.js with OAuth or email, access role-based dashboards, manage subscriptions through Stripe integration, and interact with MDX-powered content. Server actions handle mutations while Next.js App Router manages routing and rendering.

Under the hood, the system uses 2 feedback loops, 3 data pools, 3 control points to manage its runtime behavior.

A 9-component fullstack. 190 files analyzed. Data flows through 6 distinct pipeline stages.

How Data Flows Through the System

Users enter through marketing pages, authenticate via Auth.js with OAuth or email, access role-based dashboards, manage subscriptions through Stripe integration, and interact with MDX-powered content. Server actions handle mutations while Next.js App Router manages routing and rendering.

  1. Landing page visit — Next.js renders marketing pages from app/(marketing) with static content, pricing tables, and CTAs that link to authentication flows
  2. User authentication — UserAuthForm collects credentials, Auth.js validates against providers or database, creates session with Prisma adapter, and middleware protects subsequent requests [FormData → AuthSession]
  3. Dashboard routing — Middleware checks session validity, extracts user role from database, and routes to appropriate dashboard (user/admin) while protecting sensitive areas [AuthSession]
  4. Subscription management — generateUserStripe checks current plan via getUserSubscriptionPlan, creates Stripe checkout or portal session based on status, and redirects to Stripe-hosted pages [User → StripeSession]
  5. Content rendering — Contentlayer transforms MDX files into Post objects during build, components query these objects, and Mdx component renders content with custom React components
  6. Profile updates — Form submissions trigger server actions like updateUserName, which validate ownership against session, sanitize inputs with Zod, update Prisma database, and revalidate affected pages [FormData]

Data Models

The data structures that flow between stages — the contracts that hold the system together.

User lib/user.ts
Prisma User model with id: string, email: string, name: string, role: UserRole enum (USER|ADMIN), emailVerified: Date?, stripeCustomerId: string?, subscriptions: Subscription[]
Created during registration, updated via server actions, queried for session management and billing operations
AuthSession auth.ts
Auth.js session object with user: { id, email, name, role }, expires: string timestamp, sessionToken: string
Generated on login, persisted in database, validated on each protected request, expires automatically
StripeSession actions/generate-user-stripe.ts
Stripe session object with url: string, customer: string, mode: 'subscription'|'payment', line_items with price_id and quantity
Created when user upgrades subscription, redirects to Stripe, webhook confirms completion
Post contentlayer.config.ts
Contentlayer Post type with title: string, description: string, date: string, authors: string[], image: string, slug: string, body: MDX content
Generated from MDX files during build, static at runtime, includes blur data URLs for images
FormData actions/update-user-name.ts
Zod-validated objects like { name: string } for user updates, { email: string } for newsletter, { role: UserRole } for admin operations
Validated on client, processed by server actions, persisted to database with revalidation

Hidden Assumptions

Things this code relies on but never validates. These are the things that cause silent failures when the system changes.

critical Contract unguarded

The priceId parameter is a valid Stripe price ID that exists in the connected Stripe account and is currently active

If this fails: If an invalid or archived price ID is passed, Stripe checkout session creation fails with cryptic error, breaking subscription flow with no clear error message to user

actions/generate-user-stripe.ts:generateUserStripe
critical Contract weakly guarded

The userId parameter matches session.user.id exactly as strings, but different systems might represent user IDs with different formats (UUID vs string vs number)

If this fails: Authorization check fails silently if ID formats don't match, allowing potential unauthorized updates or blocking legitimate users from updating their own profiles

actions/update-user-name.ts:updateUserName
critical Environment unguarded

Stripe API keys are configured for the correct environment (test vs production) and have necessary permissions for both checkout sessions and billing portal operations

If this fails: Mixed environment keys cause payment processing failures - test keys in production block real payments, production keys in development can create actual charges during testing

actions/generate-user-stripe.ts:stripe
warning Temporal unguarded

Stripe subscription status is eventually consistent with local database, but the code doesn't handle the delay between webhook processing and subscription queries

If this fails: User sees stale subscription status after payment, potentially showing upgrade prompts for already-paid users or blocking access to features they've purchased

lib/subscription.ts:getUserSubscriptionPlan
critical Contract weakly guarded

Auth.js session always includes user.id and user.email when user is authenticated, but session shape depends on provider configuration and database state

If this fails: Missing user.id or user.email causes undefined errors in subscription management and server actions, breaking core functionality for users with incomplete profiles

auth.ts:session.user
warning Domain unguarded

Local font files (CalSans-SemiBold.woff2, GeistVF.woff2) exist in the fonts directory and are properly licensed for the deployment domain

If this fails: Missing font files cause layout shifts and render text with fallback fonts, breaking visual design; unlicensed fonts create legal liability in production

assets/fonts/index.ts
warning Scale weakly guarded

User names follow standard length and character restrictions, but different cultures have vastly different name formats (single names, very long compound names, non-Latin scripts)

If this fails: Schema validation blocks users with legitimate names that don't fit Western assumptions, creating accessibility barriers and failed registrations

lib/validations/user.ts:userNameSchema
info Resource unguarded

Build process has sufficient memory and time to process all MDX files, and content directory structure remains stable during build

If this fails: Large content repos cause build timeouts or memory exhaustion; changing directory structure during CI builds creates inconsistent deployments

contentlayer.config.ts
critical Ordering weakly guarded

Session validation happens before route protection, but middleware execution order depends on Next.js internals and can be affected by edge runtime constraints

If this fails: Race conditions in session validation can allow unauthorized access to protected routes or redirect authenticated users to login pages

middleware.ts:auth check
critical Contract unguarded

Stripe customer ID stored in database is always valid and still exists in Stripe, but customers can be deleted from Stripe console while database references remain

If this fails: Billing portal creation fails with 'customer not found' error, trapping paid users who can't manage their subscriptions or cancel recurring billing

actions/generate-user-stripe.ts:subscriptionPlan.stripeCustomerId

System Behavior

How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.

Data Pools

User Database (database)
Neon PostgreSQL stores user profiles, sessions, subscriptions, and role assignments with Prisma ORM providing type-safe queries
Content Cache (file-store)
Build-time generated content objects from MDX files cached for fast rendering of blog posts and documentation
Session Store (database)
Auth.js sessions persisted in database with automatic cleanup and secure token management

Feedback Loops

Delays

Control Points

Technology Stack

Next.js 14 (framework)
Full-stack React framework providing App Router, Server Components, and Server Actions for the entire application
Auth.js v5 (framework)
Authentication system handling OAuth providers, session management, and user verification with database persistence
Prisma (database)
Type-safe ORM connecting to Neon PostgreSQL for user data, sessions, and subscription management
Stripe (library)
Payment processing for subscription management, checkout sessions, and customer billing portal access
Contentlayer (library)
Transforms MDX files into type-safe content objects for blog posts, documentation, and guides
Tailwind CSS (library)
Utility-first styling system powering the design system and responsive layouts across all pages
Shadcn/ui (library)
React component library providing consistent UI elements with Radix UI primitives and Tailwind styling
React Hook Form (library)
Form state management and validation library working with Zod schemas for type-safe form handling
Zod (library)
Schema validation for form inputs, API responses, and data transformation with TypeScript inference
Resend (library)
Email delivery service for authentication verification emails and transactional messaging

Key Components

Explore the interactive analysis

See the full architecture map, data flow, and code patterns visualization.

Analyze on CodeSea

Related Fullstack Repositories

Frequently Asked Questions

What is next-saas-stripe-starter used for?

Creates authenticated SaaS applications with user management, billing, and marketing pages mickasmt/next-saas-stripe-starter is a 9-component fullstack written in TypeScript. Data flows through 6 distinct pipeline stages. The codebase contains 190 files.

How is next-saas-stripe-starter architected?

next-saas-stripe-starter is organized into 6 architecture layers: Route Groups, Authentication Layer, Database Layer, Payment System, and 2 more. Data flows through 6 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.

How does data flow through next-saas-stripe-starter?

Data moves through 6 stages: Landing page visit → User authentication → Dashboard routing → Subscription management → Content rendering → .... Users enter through marketing pages, authenticate via Auth.js with OAuth or email, access role-based dashboards, manage subscriptions through Stripe integration, and interact with MDX-powered content. Server actions handle mutations while Next.js App Router manages routing and rendering. This pipeline design reflects a complex multi-stage processing system.

What technologies does next-saas-stripe-starter use?

The core stack includes Next.js 14 (Full-stack React framework providing App Router, Server Components, and Server Actions for the entire application), Auth.js v5 (Authentication system handling OAuth providers, session management, and user verification with database persistence), Prisma (Type-safe ORM connecting to Neon PostgreSQL for user data, sessions, and subscription management), Stripe (Payment processing for subscription management, checkout sessions, and customer billing portal access), Contentlayer (Transforms MDX files into type-safe content objects for blog posts, documentation, and guides), Tailwind CSS (Utility-first styling system powering the design system and responsive layouts across all pages), and 4 more. This broad technology surface reflects a mature project with many integration points.

What system dynamics does next-saas-stripe-starter have?

next-saas-stripe-starter exhibits 3 data pools (User Database, Content Cache), 2 feedback loops, 3 control points, 3 delays. The feedback loops handle polling and retry. These runtime behaviors shape how the system responds to load, failures, and configuration changes.

What design patterns does next-saas-stripe-starter use?

5 design patterns detected: Route Group Organization, Server Action Pattern, Session-based Authorization, Content-as-Code, Progressive Enhancement Forms.

Analyzed on April 20, 2026 by CodeSea. Written by .