DEV Community

huangyongshan46-a11y
huangyongshan46-a11y

Posted on • Originally published at github.com

I built an AI-native SaaS starter kit for Next.js 16 — here's what I learned

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();
  },
});
Enter fullscreen mode Exit fullscreen mode

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;
  },
},
Enter fullscreen mode Exit fullscreen mode

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:

  1. checkout.session.completed — user just subscribed
  2. invoice.payment_succeeded — subscription renewed
  3. 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:

  1. Most developer tools are dark mode
  2. It's easier to add light mode later than the reverse
  3. 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)