Skip to main content

Best Convex Boilerplates for SaaS in 2026

·StarterPick Team
convexsaasboilerplatereal-timetypescriptdatabase2026

Convex is not a traditional database. It's a backend-as-a-service platform where you write TypeScript functions that run server-side, and your React components subscribe to those functions' return values in real-time — no polling, no WebSocket code, no cache invalidation logic. When the data changes on the server, all subscribed clients update automatically.

For SaaS products, this changes how you think about building features. A dashboard that shows "users online right now" isn't a complex WebSocket engineering problem — it's a Convex query that multiple clients subscribe to. A collaborative document editor isn't a complex synchronization challenge — it's Convex mutations with automatic conflict resolution.

In 2026, a growing set of SaaS boilerplates have adopted Convex as their primary backend, replacing the Supabase/Prisma/PostgreSQL stack. Here's what's available.

Why Convex for SaaS

// Traditional stack: database query + API route + cache
// lib/api/users.ts
export async function getUser(userId: string) {
  return await prisma.user.findUnique({ where: { id: userId } });
}
// app/api/users/[id]/route.ts — API route to expose it
// hooks/useUser.ts — React Query fetch + cache + stale invalidation
// 3 files, cache management, manual refetch on update

// Convex approach: one function, live updates
// convex/users.ts
export const getUser = query({
  args: { userId: v.id('users') },
  handler: async (ctx, { userId }) => {
    return await ctx.db.get(userId);
  },
});

// React component
function UserProfile({ userId }) {
  const user = useQuery(api.users.getUser, { userId });
  // Automatically re-renders when user data changes server-side
  // No polling, no manual invalidation, no API route
  return <div>{user?.name}</div>;
}

Convex vs Traditional Stack (SaaS Specific)

FeatureConvexSupabase + PrismaFirebase
Real-time subscriptions✅ Automatic✅ Realtime API✅ onSnapshot
TypeScript types✅ First-class✅ With Prisma⚠️ Generated
Schema migrations✅ Automatic✅ Via Prisma
Full-text search✅ Built-in✅ pg_trgm⚠️ Limited
File storage✅ Built-in✅ Storage
Background jobs✅ Scheduled functions❌ (need pg_cron)✅ Functions
Rate limiting✅ Built-in
Caching✅ Automatic query cache
Self-host❌ Managed only
Free tier1M function calls/month500MB database1GB storage
Pricing (paid)$25/month$25/monthPay-per-use

Convex's key limitation: it's managed-only — you can't self-host Convex. If data residency or vendor lock-in is a hard requirement, Convex isn't the right choice. For most indie hackers and early-stage startups, the productivity gain outweighs the managed dependency.


Quick Comparison

StarterPriceAuthBillingOrg SupportStack
Convex Ents SaaSFreeClerkStripeNext.js + Convex
RSKFreeClerkPolar.shRR7 + Convex
nextjs-starter-kit-convexFreeCustomStripeNext.js + Convex
Midday Convex port (v1.run)FreeBetter AuthPolar.shNext.js + Convex
Convex AI templateFreeNextAuthNext.js + Convex

1. Convex Ents SaaS Next.js Starter — Best Official Option

Price: Free | Creator: Convex team | Stack: Next.js + Convex + Clerk

The official Convex team's SaaS starter using Convex Ents — a relationship management layer that makes working with related data (users → teams → projects) significantly cleaner than raw Convex queries.

What's included:

  • Organization/team management with configurable roles
  • Member invitation via email (Resend integration)
  • Clerk authentication with session sync to Convex
  • shadcn/ui with responsive layout
  • Dark mode
  • TypeScript throughout
  • Deployment to Vercel

Convex Ents makes relations easy:

// convex/schema.ts — Define relationships with Ents
import { defineEnt, defineEntSchema } from 'convex-ents';
import { v } from 'convex/values';

export const schema = defineEntSchema({
  organizations: defineEnt({
    name: v.string(),
    slug: v.string(),
  })
    .edges('members', { to: 'organizationMembers' })
    .edges('projects', { to: 'projects' }),

  users: defineEnt({
    clerkId: v.string(),
    email: v.string(),
    name: v.optional(v.string()),
  })
    .edges('memberships', { to: 'organizationMembers' })
    .index('by_clerk_id', ['clerkId']),

  organizationMembers: defineEnt({
    role: v.union(v.literal('owner'), v.literal('admin'), v.literal('member')),
  })
    .edge('organization', { to: 'organizations' })
    .edge('user', { to: 'users' }),

  projects: defineEnt({
    name: v.string(),
    description: v.optional(v.string()),
  })
    .edge('organization', { to: 'organizations' }),
});
// convex/organizations.ts — Clean relationship queries with Ents
import { query, mutation } from './_generated/server';
import { v } from 'convex/values';

export const getOrganizationWithMembers = query({
  args: { slug: v.string() },
  handler: async (ctx, { slug }) => {
    const org = await ctx.table('organizations')
      .filter(q => q.eq(q.field('slug'), slug))
      .first();

    if (!org) return null;

    // Ents handles the join automatically
    const members = await org.edge('members');
    const membersWithUsers = await Promise.all(
      members.map(async (member) => ({
        ...member,
        user: await member.edge('user'),
      }))
    );

    return { ...org, members: membersWithUsers };
  },
});

2. RSK (React Starter Kit) — Best Free Convex SaaS Stack

Price: Free (MIT) | Stack: React Router v7 + Convex + Clerk + Polar.sh

RSK pairs Convex with React Router v7 (Remix's successor), Clerk for auth, and Polar.sh for billing — the most modern combination available in a free starter.

// RSK: Real-time dashboard with Convex
// app/routes/dashboard.tsx
import { useQuery } from 'convex/react';
import { api } from '~/convex/_generated/api';

export default function Dashboard() {
  // Live subscription — updates when any user's data changes
  const metrics = useQuery(api.dashboard.getMetrics, {
    organizationId: currentOrgId,
  });

  // No loading spinners needed for real-time updates
  // metrics updates automatically when server data changes

  return (
    <div>
      <MetricCard title="Active Users" value={metrics?.activeUsers ?? 0} />
      <MetricCard title="MRR" value={metrics?.mrr ?? 0} />
    </div>
  );
}

3. nextjs-starter-kit-convex (acelords) — Most Batteries Included

Price: Free (MIT) | Stack: Next.js + Convex + Stripe + AI playground

This community starter is notable for including an AI playground — a pre-built chat interface using Convex for message history and streaming. It covers:

  • Dashboard with sidebar navigation
  • Authentication routes
  • Marketing landing page
  • API routes
  • AI chat playground (Convex + OpenAI)
  • Stripe billing setup
// AI chat with Convex message history
// convex/messages.ts
export const list = query({
  args: { conversationId: v.id('conversations') },
  handler: async (ctx, { conversationId }) => {
    return await ctx.db
      .query('messages')
      .withIndex('by_conversation', (q) =>
        q.eq('conversationId', conversationId)
      )
      .order('asc')
      .collect();
  },
});

export const send = mutation({
  args: {
    conversationId: v.id('conversations'),
    content: v.string(),
    role: v.union(v.literal('user'), v.literal('assistant')),
  },
  handler: async (ctx, args) => {
    return await ctx.db.insert('messages', {
      ...args,
      createdAt: Date.now(),
    });
  },
});

4. v1.run (Midday Convex Port) — Most Complete Free Stack

Price: Free (MIT) | Stack: Next.js + Convex + Better Auth + Polar.sh (Turborepo)

v1.run is a Turborepo monorepo modeled after Midday (a well-architected open-source finance app), ported to use Convex instead of Supabase. It's the most architecturally complete free Convex starter with:

  • Turborepo monorepo with apps/web, apps/api, packages/*
  • Convex for all data storage, background functions, file storage
  • Better Auth for authentication (no Clerk dependency)
  • Polar.sh billing
  • React Email + Resend for transactional email
  • Internationalization (next-intl)
  • Sentry error tracking pre-configured
  • OpenPanel analytics

Convex Patterns Every SaaS Needs

Background jobs (scheduled functions):

// convex/crons.ts — Scheduled functions for SaaS
import { cronJobs } from 'convex/server';
import { internal } from './_generated/api';

const crons = cronJobs();

// Daily job: send trial expiring emails
crons.daily(
  'send-trial-expiring-emails',
  { hourUTC: 9, minuteUTC: 0 },
  internal.emails.sendTrialExpiringEmails
);

// Weekly job: generate usage reports
crons.weekly(
  'generate-usage-reports',
  { dayOfWeek: 'monday', hourUTC: 8, minuteUTC: 0 },
  internal.reports.generateWeeklyReports
);

export default crons;

File storage:

// Upload file → store in Convex storage → get URL
export const generateUploadUrl = mutation(async (ctx) => {
  return await ctx.storage.generateUploadUrl();
});

export const saveFile = mutation({
  args: {
    storageId: v.id('_storage'),
    filename: v.string(),
  },
  handler: async (ctx, { storageId, filename }) => {
    const url = await ctx.storage.getUrl(storageId);
    return await ctx.db.insert('files', {
      storageId,
      filename,
      url: url!,
      uploadedAt: Date.now(),
    });
  },
});

Choosing a Convex SaaS Boilerplate

Official recommended: Convex Ents SaaS Starter — maintained by the Convex team, uses Convex Ents for clean relationship management.

Modern free stack: RSK — React Router v7 + Convex + Clerk + Polar.sh, zero cost, MIT license.

Most features: nextjs-starter-kit-convex — includes AI playground and more complete feature set.

Best architecture: v1.run — Turborepo monorepo with production-grade structure.


Browse all Convex boilerplates at StarterPick.

Related: Best Boilerplates With Polar.sh Payments 2026 · Top AI SaaS Boilerplates 2026

Comments