Every time I start a new SaaS project, I spend the first 2-3 weeks on the same things: authentication, Stripe billing, email, a dashboard layout, and now — AI integration. The actual product doesn't get touched until week 3.
So I built LaunchKit — a production-ready SaaS foundation that handles all of this out of the box.
But this isn't just another boilerplate post. I want to share the specific architectural decisions and lessons learned, because some of them go against conventional wisdom.
Why "AI-native" matters
Most existing SaaS boilerplates (ShipFast, Supastarter, MakerKit) were built in 2023. If they have AI features at all, it's a basic chat page bolted on as an afterthought.
In 2026, almost every new SaaS product has some AI component. The chat interface, streaming responses, conversation persistence, and plan-based usage limits shouldn't be something you wire up yourself — they should be part of the foundation.
LaunchKit's AI chat is a first-class feature:
// src/app/api/ai/chat/route.ts — Streaming AI responses
const stream = new ReadableStream({
async start(controller) {
const reader = response.body!.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split("\n").filter(l => l.startsWith("data: "));
for (const line of lines) {
const data = line.replace("data: ", "");
if (data === "[DONE]") { controller.close(); return; }
const parsed = JSON.parse(data);
const content = parsed.choices?.[0]?.delta?.content;
if (content) controller.enqueue(new TextEncoder().encode(content));
}
}
controller.close();
},
});
The API route is provider-agnostic — swap OpenAI for Anthropic or Google by changing one fetch call.
Auth.js v5 — the right way
I see a lot of boilerplates still using NextAuth v4. Auth.js v5 is a significant rewrite with better TypeScript support and App Router integration.
Key decisions:
- JWT sessions (not database sessions) — faster, no DB query per request
- Prisma adapter — user data still persists to PostgreSQL
- Multiple providers — email/password + Google + GitHub, all wired
- Role-based access — USER and ADMIN roles baked into the JWT
callbacks: {
async jwt({ token }) {
if (!token.sub) return token;
const user = await db.user.findUnique({
where: { id: token.sub },
select: { role: true },
});
if (user) token.role = user.role;
return token;
},
},
Stripe billing — the parts nobody shows you
Every Stripe tutorial shows you how to create a checkout session. Nobody shows you the webhook handler that actually makes billing work in production.
LaunchKit handles the three webhook events that matter:
-
checkout.session.completed— user just subscribed -
invoice.payment_succeeded— subscription renewed -
customer.subscription.deleted— user canceled
The billing page isn't just "here are your plans" — it shows current plan status, feature comparison, upgrade flow, and payment history.
The Prisma schema
The full schema is opinionated but extensible:
- User — core user model with role enum
- Account — OAuth provider accounts
- Session — session tokens
- Subscription — Stripe subscription state (synced via webhooks)
- Conversation — AI chat conversations
- Message — individual chat messages
Every model has createdAt / updatedAt timestamps. The subscription model uses enums for status and plan type — no magic strings.
UI decisions
I went with a dark-first design because:
- Most developer tools are dark mode
- It's easier to add light mode later than the reverse
- Dark UIs photograph better (Product Hunt, Twitter, README screenshots)
The component library is intentionally small: Button, Input, Card, Badge. Four components with variants cover 90% of a SaaS UI. No need for a full design system on day one.
The stack, and why each piece
| Technology | Why |
|---|---|
| Next.js 16 | App Router is stable, RSC reduces client JS, great DX |
| TypeScript (strict) | Catch bugs at compile time, better autocomplete |
| Tailwind CSS v4 | Utility-first is fastest for building custom UIs |
| Auth.js v5 | Official Next.js auth, great provider ecosystem |
| Prisma | Best TypeScript ORM, great migrations |
| PostgreSQL | Industry standard, works everywhere |
| Stripe | No real alternative for SaaS billing |
| Resend | Modern email API, React Email templates |
| OpenAI | Fastest to integrate, easy to swap |
Try it
The source code is on GitHub (MIT license):
github.com/huangyongshan46-a11y/launchkit-saas
Full package with documentation: Get LaunchKit on Gumroad ($49 launch price)
Clone it, run npm install && npm run dev, and you'll have a working SaaS app in under 5 minutes.
Happy to answer any questions in the comments.
Top comments (0)