Skip to main content

Pick a SaaS Boilerplate Based on Your Business Model

·StarterPick Team
saas-boilerplatebusiness-modeldecision-guideindie-hacker2026

TL;DR

Most developers pick a boilerplate based on the tech stack. The better approach: pick it based on your business model. A B2B SaaS with organizations and seats needs Supastarter's multi-tenancy. A B2C subscription app with a landing page and PaymentSheet needs ShipFast's simplicity. A marketplace needs Stripe Connect — and almost no boilerplate ships with that. Match the boilerplate to the billing and user model, not just the framework.

Key Takeaways

  • B2C subscriptions (individual users paying monthly): ShipFast, Next SaaS Starter, T3 Stack
  • B2B SaaS (companies buying seats): Supastarter, Makerkit, Bedrock — multi-tenancy required
  • Usage-based billing: no boilerplate ships this pre-built — add Stripe Meters manually
  • Marketplace / two-sided: Stripe Connect — you'll customize any boilerplate significantly
  • Freemium: any starter with feature flags — add PostHog or LaunchDarkly
  • Open core (free OSS + paid features): T3 Stack or Epic Stack as the base

The Business Model Matrix

Business Model       → Required Features           → Best Boilerplate
─────────────────────────────────────────────────────────────────────
B2C subscription    → User auth, Stripe            → ShipFast, Next SaaS Starter
B2B per-seat        → Orgs, members, RLS           → Supastarter, Makerkit
B2B usage-based     → Stripe Meters, usage tracking → T3 Stack (add meters)
Marketplace         → Stripe Connect, escrow        → Build custom (or fork Epic Stack)
Freemium            → Feature flags, plan limits    → Any + PostHog
One-time purchase   → Simple checkout               → ShipFast (simpler billing)
Open core           → Public repo + auth gate       → T3 Stack or Epic Stack
Agency/services     → Multi-project dashboard       → Custom (no boilerplate fits)

Model 1: B2C Subscription

Characteristics:

  • Individual users (not companies) pay you directly
  • Credit card on file, monthly/annual billing
  • Users don't invite teammates
  • Support volume is critical (one bad experience = churn)

What you need from a boilerplate:

  • Clean auth flow (magic link, Google are highest converting)
  • Stripe subscriptions + webhooks
  • Email notifications
  • Fast landing page (conversion matters)
  • Basic dashboard

What you DON'T need:

  • Organizations or team management
  • Role-based permissions
  • Multi-tenant database isolation
  • Seat counting

Best choices:

// ShipFast: Stripe checkout in ~50 lines
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

// ShipFast's apiCheckout.ts — already written for you:
export const createCheckout = async (priceId: string, userId: string) => {
  const session = await stripe.checkout.sessions.create({
    line_items: [{ price: priceId, quantity: 1 }],
    mode: 'subscription',
    success_url: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard?success=true`,
    cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing`,
    client_reference_id: userId,
    customer_email: userEmail,
  });
  return session.url;
};

Recommendation: ShipFast for simplicity, Next SaaS Starter for free.


Model 2: B2B Per-Seat SaaS

Characteristics:

  • Companies (organizations) are your customers, not individuals
  • Admins invite team members (seats)
  • Billing is per seat × per month
  • Users have different roles (admin, member, viewer)

What you need:

  • Organization model (orgs own resources, not individual users)
  • Invitation system (invite by email, accept invite flow)
  • Role-based permissions (admin vs member)
  • Per-seat billing with Stripe
  • Row Level Security (data isolation between orgs)

What's wrong with B2C boilerplates for B2B:

// ❌ B2C pattern (data owned by user):
// Resources belong to individual users
const todos = await db.todo.findMany({
  where: { userId: session.user.id }
});

// ✅ B2B pattern (data owned by organization):
// Resources belong to the org, users are members
const todos = await db.todo.findMany({
  where: {
    organizationId: session.user.activeOrganizationId,
    // AND: user must be a member of this org (enforced by RLS or application logic)
  }
});

Building this from a B2C boilerplate takes 2-3 weeks. Supastarter ships it:

// Supastarter's organization model (pre-built):
// app/dashboard/settings/members/page.tsx

// Invite a member:
const { error } = await supabase.functions.invoke('send-invitation', {
  body: {
    email: inviteeEmail,
    organizationId: currentOrg.id,
    role: 'member', // 'admin' | 'member' | 'viewer'
  }
});

// RLS policy (pre-written by Supastarter):
// CREATE POLICY "members can read org resources"
// ON resources FOR SELECT
// USING (
//   organization_id IN (
//     SELECT organization_id FROM memberships
//     WHERE user_id = auth.uid()
//   )
// );

Recommendation: Supastarter ($299) or Makerkit ($299+) — the multi-tenancy foundation saves weeks.


Model 3: Usage-Based Billing

Characteristics:

  • Customers pay per API call, per GB processed, per message sent, per seat-hour
  • Complex billing that varies month to month
  • Need accurate usage tracking + metering

The bad news: no boilerplate ships usage-based billing pre-built. Stripe Meters (the modern Stripe solution) is too new and too specific to be in generic starters.

What to do:

// Add Stripe Meters to any boilerplate:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

// Track usage event:
export async function trackApiCall(customerId: string) {
  // Report usage to Stripe Billing Meter:
  await stripe.billing.meterEvents.create({
    event_name: 'api_call',
    payload: {
      stripe_customer_id: customerId,
      value: '1', // 1 API call
    },
  });
}

// Create usage-based subscription:
await stripe.subscriptions.create({
  customer: customerId,
  items: [{
    price: 'price_api_calls_per_unit', // Price with billing_scheme=per_unit
  }],
});

// In your API route:
export async function POST(req: Request) {
  const user = await getUser(req);
  await trackApiCall(user.stripeCustomerId);
  // ... handle actual API request
}

Starting boilerplate for usage-based: T3 Stack — clean foundation, add meters yourself. Don't pay $299 for Supastarter's multi-tenancy if you don't need it.


Model 4: Marketplace / Two-Sided

Characteristics:

  • Buyers and sellers (or creators and consumers)
  • You take a platform fee
  • Payments flow through you to sellers
  • Stripe Connect required for payouts

The reality: No major boilerplate ships Stripe Connect pre-built. It's complex, highly variable, and requires understanding of connected accounts vs standard accounts.

// Stripe Connect setup (you'll add this yourself):
const account = await stripe.accounts.create({
  type: 'express', // or 'standard', 'custom'
  country: 'US',
  capabilities: {
    card_payments: { requested: true },
    transfers: { requested: true },
  },
});

// Payment with platform fee:
const paymentIntent = await stripe.paymentIntents.create({
  amount: 5000,              // $50.00 total
  currency: 'usd',
  application_fee_amount: 500, // $5.00 platform fee (10%)
  transfer_data: {
    destination: seller.stripeAccountId,
  },
});

Recommendation: Start with T3 Stack or Epic Stack (clean, customizable), add Connect yourself. Budget 2-3 weeks for the Connect integration — it's complex regardless of boilerplate.


Model 5: Freemium

Characteristics:

  • Free tier with feature limits (3 projects, 100 API calls/month)
  • Upgrade prompt when limits hit
  • Need to enforce limits reliably
// Feature gate pattern in any boilerplate:
// middleware or server action check

export async function checkProjectLimit(userId: string) {
  const user = await db.user.findUnique({
    where: { id: userId },
    include: { projects: true, subscription: true },
  });

  const plan = user?.subscription?.plan ?? 'free';
  const limits = {
    free: 3,
    pro: 100,
    enterprise: Infinity,
  };

  if (user!.projects.length >= limits[plan as keyof typeof limits]) {
    throw new Error('PLAN_LIMIT_EXCEEDED');
  }
}

// In your tRPC/API route:
export const createProject = protectedProcedure
  .input(createProjectSchema)
  .mutation(async ({ ctx, input }) => {
    await checkProjectLimit(ctx.session.user.id);
    return ctx.db.project.create({ data: input });
  });

Any boilerplate supports this pattern. The sophistication is in your limit enforcement logic, not the boilerplate.

Recommendation: ShipFast (add limit checks manually) or Makerkit (has plan configuration built-in).


Quick Reference: Business Model → Boilerplate

You're building...                    Get this boilerplate:

Simple B2C subscription              ShipFast ($199) — fast
Simple B2C, no budget                Next SaaS Starter (free)
B2B with teams and orgs             Supastarter ($299) — multi-tenancy
B2B, complex features               Makerkit ($299+) — plugin system
Usage-based billing                  T3 Stack (free) + add Stripe Meters
Marketplace/two-sided                T3 Stack or Epic Stack (free) + Stripe Connect
Dev tool / API product               T3 Stack + tRPC
Content + SaaS hybrid                Makerkit (blog built-in) or T3+Contentlayer
Full open source                     Open SaaS (free, Wasp) or T3 Stack

Need multi-language from day 1:      Supastarter (i18n built-in)
Team is Rails/Python:                Laravel Spark, Wave, or djaodjin
Team is SvelteKit:                   SvelteShip or Indie Kit
Enterprise (SOC2, SSO, audit log):   Bedrock ($499+)

The 15-Minute Evaluation Framework

Before buying any boilerplate, answer these 5 questions:

  1. Who pays? (individual users or companies/teams) → Individual = need simple Stripe subscriptions → Teams = need multi-tenancy

  2. How do they pay? (monthly flat / per seat / per usage) → Flat = any boilerplate → Per seat = needs seat counting + billing → Usage = add Stripe Meters manually

  3. What's the launch timeline? → < 1 week = ShipFast (fastest) → 1-4 weeks = any major boilerplate → 1+ month = build what you need

  4. What's the long-term complexity? → Simple = free boilerplate, grow later → Complex from day 1 = invest in Supastarter/Makerkit foundation

  5. What's your team's framework expertise? → Strong Next.js = ShipFast/Supastarter → Strong Remix = Epic Stack/SaaSrock → Strong SvelteKit = SvelteShip/Indie Kit


Find the right boilerplate for your business model at StarterPick.

Comments