Best Convex Boilerplates for SaaS in 2026
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)
| Feature | Convex | Supabase + Prisma | Firebase |
|---|---|---|---|
| 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 tier | 1M function calls/month | 500MB database | 1GB storage |
| Pricing (paid) | $25/month | $25/month | Pay-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
| Starter | Price | Auth | Billing | Org Support | Stack |
|---|---|---|---|---|---|
| Convex Ents SaaS | Free | Clerk | Stripe | ✅ | Next.js + Convex |
| RSK | Free | Clerk | Polar.sh | ❌ | RR7 + Convex |
| nextjs-starter-kit-convex | Free | Custom | Stripe | ✅ | Next.js + Convex |
| Midday Convex port (v1.run) | Free | Better Auth | Polar.sh | ✅ | Next.js + Convex |
| Convex AI template | Free | NextAuth | ❌ | ❌ | Next.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
Check out this boilerplate
View Convex Ents SaaS Starter on StarterPick →