Best Next.js Boilerplate with Stripe and Auth 2026
TL;DR
Every serious Next.js SaaS boilerplate includes Stripe and auth — but the depth varies enormously. Basic Stripe integration handles subscriptions. Production Stripe integration handles webhooks, failed payments, customer portals, proration, and per-seat billing. Here's how the top boilerplates actually compare on both dimensions.
Quick verdict:
- ShipFast — Stripe + LemonSqueezy + basic auth, minimal webhook handling
- Makerkit — Stripe or LS with full customer portal, Supabase Auth with SSR
- Supastarter — 5 payment providers, deepest Supabase Auth integration, RLS pre-written
- T3 Stack + Stripe — manual wiring, excellent type safety, no abstractions hiding the logic
- Next SaaS Starter — clean App Router Stripe + Auth.js baseline for free
Stripe Integration Depth Comparison
| Boilerplate | Price | Providers | Webhooks | Customer Portal | Per-Seat | Proration |
|---|---|---|---|---|---|---|
| ShipFast | $199 | Stripe + LS | Basic | ❌ | ❌ | ❌ |
| Makerkit | $299+ | Stripe or LS | Full | ✅ | Partial | ✅ |
| Supastarter | $299 | Stripe + LS + 3 more | Full | ✅ | ✅ | ✅ |
| T3 Stack | Free | DIY | DIY | DIY | DIY | DIY |
| Next SaaS Starter | Free | Stripe | Core | ❌ | ❌ | ❌ |
Auth Integration Depth Comparison
| Boilerplate | Auth Provider | SSR Pattern | OTP | Device Tracking | Session Rotation |
|---|---|---|---|---|---|
| ShipFast | NextAuth or Supabase | Older helpers | ❌ | ❌ | Basic |
| Makerkit | Supabase Auth | @supabase/ssr ✅ | ❌ | ❌ | Standard |
| Supastarter | Supabase Auth | @supabase/ssr ✅ | ✅ | ❌ | Standard |
| T3 Stack | Auth.js v5 | RSC-safe | ❌ | ❌ | Standard |
| Next SaaS Starter | Auth.js v5 | RSC-safe | ❌ | ❌ | Standard |
Why Stripe Integration Depth Matters
The gap between "Stripe Checkout session" and "production billing system" is the part no boilerplate marketing tells you about.
What every boilerplate does: Create a Stripe Checkout session, redirect to Stripe-hosted payment page, handle the checkout.session.completed webhook to update your user record.
What production billing requires:
customer.subscription.updated— plan changes, seat changesinvoice.payment_failed— retry logic, grace periods, user communicationcustomer.subscription.deleted— cancellation flow, access revocation- Customer portal integration — self-service plan changes
- Proration handling — when customers upgrade mid-cycle
- Per-seat billing — quantity updates when team members are added/removed
- Trial periods — free trial to paid conversion flows
Most cheap or free boilerplates handle only the first one. The rest is your problem.
ShipFast — Fast Setup, Basic Depth
Price: $199–299 | Stripe + LemonSqueezy
ShipFast gets you to a working checkout in under an hour. The Stripe integration is clean and direct — no abstractions hiding the logic:
// ShipFast Stripe checkout — explicit and readable:
export async function POST(req: Request) {
const { priceId, successUrl } = await req.json();
const session = await getServerSession(authOptions);
const stripeSession = await stripe.checkout.sessions.create({
mode: 'subscription',
payment_method_types: ['card'],
line_items: [{ price: priceId, quantity: 1 }],
success_url: successUrl,
customer_email: session?.user?.email,
metadata: { userId: session?.user?.id },
});
return Response.json({ url: stripeSession.url });
}
The webhook handler covers checkout.session.completed and customer.subscription.deleted. Failed payment handling and customer portal are manual additions. LemonSqueezy support is full — useful for non-US founders who need merchant-of-record tax handling.
Auth in ShipFast uses NextAuth.js (now Auth.js) or Supabase Auth, configurable at project setup. The Supabase option uses the older @supabase/auth-helpers-nextjs package rather than the current @supabase/ssr — functional but not the 2026-recommended pattern.
Best fit: Solo founders shipping B2C products who need working Stripe fast and don't need customer portals or per-seat billing.
Makerkit — Best Production Auth + Billing
Price: $299 core + plugins | Stripe or LemonSqueezy
Makerkit's billing module is more complete than ShipFast's without reaching the complexity of Supastarter's multi-provider system. The focus is correct implementation of the common cases: subscriptions, upgrades, cancellations, customer portal.
// Makerkit billing service — properly abstracted:
// packages/billing/stripe/src/services/stripe-billing.service.ts
export class StripeBillingService implements BillingService {
async createCheckoutSession(params: CreateCheckoutParams) {
const customer = await this.getOrCreateCustomer(params.userId);
return stripe.checkout.sessions.create({
customer: customer.id,
mode: 'subscription',
line_items: [{ price: params.priceId, quantity: 1 }],
success_url: params.successUrl,
allow_promotion_codes: true,
// Correct: pass customer ID, not email, for existing customers
});
}
async createCustomerPortalSession(userId: string) {
const customer = await this.getCustomer(userId);
return stripe.billingPortal.sessions.create({
customer: customer.stripeCustomerId,
return_url: `${env.APP_URL}/dashboard/billing`,
});
}
}
The BillingService interface means you can swap Stripe for LemonSqueezy by switching the implementation — your application code doesn't change. This abstraction is genuinely useful if you're uncertain about payment provider at the start.
Auth uses Supabase with @supabase/ssr — the correct 2026 pattern. Server components authenticate via the SSR client, client components use the browser client, and the middleware protects routes with the session from cookies rather than the deprecated getServerSession.
Best fit: Teams who need a full customer portal, correct auth SSR patterns, and might swap payment providers later.
Supastarter — Most Complete Integration
Price: $299 | Stripe + LemonSqueezy + Paddle + Polar + Chargebee
Supastarter's billing depth is the most complete of any boilerplate. Five payment providers through a unified abstraction layer. Per-seat billing integrated with the organization model — when a member joins a team, the Stripe subscription quantity updates automatically:
// Supastarter per-seat billing — automatic seat updates:
export async function addMemberToOrganization({
organizationId,
userId,
role,
}: AddMemberParams) {
await db.memberships.insert({ organizationId, userId, role });
// Automatically update Stripe seat count:
const subscription = await getOrganizationSubscription(organizationId);
if (subscription?.billingModel === 'per_seat') {
const seatCount = await db.memberships.count({ organizationId });
await stripe.subscriptions.update(subscription.stripeSubscriptionId, {
items: [{ id: subscription.stripeItemId, quantity: seatCount }],
proration_behavior: 'create_prorations',
});
}
}
Auth is Supabase Auth with OTP support (unique among these options), full SSR via @supabase/ssr, and pre-written RLS policies covering every database table. The RLS policies mean your data is secure at the database level — not just at the application level.
-- Supastarter RLS: only org members can read org data
CREATE POLICY "org_members_only"
ON subscriptions FOR SELECT
USING (
organization_id IN (
SELECT organization_id FROM memberships
WHERE user_id = auth.uid()
)
);
Best fit: B2B SaaS with organizations, per-seat billing, and deep Supabase integration requirements.
T3 Stack — Most Transparent Stripe Implementation
Price: Free | Any provider (manual setup)
T3 Stack doesn't include Stripe — you wire it yourself. The advantage: you understand exactly what your billing code does, nothing is hidden in abstractions, and TypeScript covers your Stripe integration the same way it covers everything else.
// T3 Stack + Stripe — example webhook handler you'd write:
// pages/api/webhooks/stripe.ts
import { stripe } from '~/server/stripe';
import { db } from '~/server/db';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const sig = req.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(
req.body,
sig!,
process.env.STRIPE_WEBHOOK_SECRET!
);
switch (event.type) {
case 'checkout.session.completed':
const session = event.data.object;
await db.user.update({
where: { id: session.metadata.userId },
data: { subscriptionStatus: 'active', stripeCustomerId: session.customer as string },
});
break;
// Handle other events yourself
}
res.json({ received: true });
}
For the auth side, T3 uses Auth.js v5 (NextAuth) with proper RSC support. The advantage over Supabase Auth: no external auth service dependency — your sessions live in your database.
Best fit: Developers who want full control and transparency over billing logic, or non-standard billing models that boilerplate abstractions would fight against.
What to Look for Beyond the Basics
Idempotency: Stripe webhooks can fire multiple times for the same event. A production implementation handles this — Supastarter and Makerkit do. ShipFast's basic handler does not.
Failed payment grace period: When a payment fails, you shouldn't immediately revoke access. A 3–7 day grace period with email reminders recovers 15–25% of failing subscriptions. Only Supastarter handles this out of the box.
Trial management: Free-to-paid conversion requires trialing status tracking, trial expiry emails, and proper webhook handling for customer.subscription.trial_will_end. Commercial boilerplates cover this; free ones don't.
Stripe Customer Portal: Letting customers manage their own subscription (upgrade, downgrade, cancel) without your support involvement is table stakes for B2B. Makerkit and Supastarter include this. ShipFast doesn't.
Decision Framework
Fastest working checkout today → ShipFast ($199)
Full billing + correct auth SSR patterns → Makerkit ($299+)
Per-seat billing + multi-tenancy + 5 providers → Supastarter ($299)
Full control over billing code → T3 Stack + wire it yourself
Free baseline with correct patterns → Next SaaS Starter
For deeper billing comparisons, see Stripe vs LemonSqueezy for SaaS boilerplates and how ShipFast, Makerkit, and Supastarter handle Stripe webhooks. Browse boilerplates filtered by Stripe support in the StarterPick directory.