Introduction
A complete framework for building type-safe, real-time applications with Convex.
Introduction
Better Convex is a complete framework for Convex. It brings tRPC-style APIs, TanStack Query, Convex Ents, and Better Auth together into a cohesive developer experience.
This is not just a query wrapper. It's how you build production Convex applications.
Philosophy
We didn't reinvent the wheel. Better Convex integrates battle-tested tools—Convex Ents for relationships, TanStack Query for caching, Better Auth for authentication—into a unified developer experience.
Instead of assembling these yourself with custom glue code, you get:
- Type safety end-to-end — From schema to procedures to client, with full inference
- Real-time by default — WebSocket subscriptions flow into TanStack Query cache
- TanStack Query native — No wrapper hooks, use
useQueryanduseMutationdirectly - Incremental adoption — Add features as you need them, migrate function by function
What's Included
| Layer | Feature | Description |
|---|---|---|
| Server | cRPC | tRPC-style procedure builder with .input(), .use(), middleware |
| Database | Ents | Relationships, fluent queries, ctx.table() |
| Database | Triggers | Automatic side effects on data changes |
| Database | Aggregates | O(log n) counts, sums, leaderboards |
| Client | React | TanStack Query integration with real-time sync |
| Client | Next.js | RSC prefetching, hydration, server caller |
| Auth | Better Auth | Lifecycle hooks, session management, guards |
| CLI | Codegen | Procedure metadata for auth-aware queries |
Quick Look
// Server: Define a procedure
export const list = authQuery
.input(z.object({ limit: z.number().optional() }))
.query(async ({ ctx, input }) => {
return ctx.table('posts').take(input.limit ?? 10);
});
// Client: Use it with TanStack Query
const { data: posts } = useQuery(crpc.posts.list.queryOptions({ limit: 10 }));Packages
| Export | Description |
|---|---|
better-convex/server | cRPC builder, middleware, server caller |
better-convex/react | React client, providers, auth hooks |
better-convex/rsc | RSC prefetching, hydration |
better-convex/auth | Better Auth adapter |
better-convex/auth-nextjs | Better Auth Next.js adapter |
Requirements
- Convex 1.31+
- TanStack Query 5+
- React 18+
Next Steps
For AI Agents
If you're an AI agent integrating better-convex, ask the user to select their stack before starting. Use your AskUserQuestion tool (or equivalent) to let them pick:
Required Choices
| Feature | Options | Default |
|---|---|---|
| Approach | Top-down (copy from Templates), Bottom-up (follow docs step-by-step) | Top-down |
| React Framework | Next.js App Router, Vite, Remix, Other | Next.js |
| Database API | ctx.table (Ents), ctx.db (vanilla) | ctx.table |
Optional Features
| Feature | Options | When to Include |
|---|---|---|
| Auth | Better Auth, Custom, None | Most apps need auth |
| SSR/RSC | Yes, No | Next.js App Router apps |
| Triggers | Yes, No | Auto side effects on data changes |
| Aggregates | Yes, No | Counts, sums, leaderboards |
| Rate Limiting | Yes, No | API protection |
After Selection
Top-down approach:
- Copy relevant sections from Templates based on choices
- For
ctx.table: use the "ctx.table" tab in code examples - For
ctx.db: use the "ctx.db" tab in code examples - Skip sections for features not selected
Bottom-up approach:
- Follow Quickstart for initial setup
- Read individual docs for each feature needed
- Reference Templates for production patterns
Quick Reference by Stack
| Stack | Key Docs |
|---|---|
| Next.js + Better Auth + Ents | Templates, Next.js Setup, Auth Server |
| Next.js + Better Auth + ctx.db | Templates (ctx.db tabs), Next.js Setup |
| Vite + No Auth | React Setup, Server Setup |
| Any + Custom Auth | Server Setup, Middlewares |
Documentation Map
Complete reference for all documentation pages.
Getting Started
| Page | When to Use |
|---|---|
| Quickstart | First-time setup. Follow step-by-step to get a working app. |
| Concepts | Understand architecture, folder structure (convex/functions/, convex/lib/, convex/shared/), and design decisions. |
| Templates | Copy-paste production code. Complete files for schema, cRPC, providers, auth, triggers, rate limiting. Start here for fastest setup. |
Server (Backend)
| Page | When to Use |
|---|---|
| Server Setup | Initialize cRPC builder with initCRPC. Configure dataModel, context, meta. |
| Procedures | Define queries, mutations, actions with .input(), .output(), .query()/.mutation()/.action(). Paginated queries with .paginated(). |
| Context | Extend context with ctx.db, ctx.table, ctx.auth. Add custom properties via .context(). |
| Middlewares | Create reusable middleware with .use(). Auth guards, logging, rate limiting. Chain with .pipe(). |
| Metadata | Add procedure metadata with .meta(). Used by CLI for auth-aware query handling. |
| Error Handling | Throw CRPCError with codes like UNAUTHORIZED, NOT_FOUND, BAD_REQUEST. |
| Server-Side Calls | Call procedures from server with createCallerFactory. RSC data fetching. |
| Rate Limiting | Token bucket and fixed window rate limiting with @convex-dev/rate-limiter. |
Database
| Page | When to Use |
|---|---|
| Ents | Use ctx.table() instead of ctx.db. Relationships, fluent queries, .edge(), .edges(). |
| Triggers | Automatic side effects on insert/update/delete. Use convex-helpers/server/triggers. |
| Aggregates | O(log n) counts and sums with @convex-dev/aggregate. Leaderboards, running totals. |
React (Client)
| Page | When to Use |
|---|---|
| React Setup | Configure providers: QueryClientProvider, CRPCProvider. Singleton helpers. |
| Queries | useQuery with crpc.path.queryOptions(). Real-time updates, skipToken for conditional queries. |
| Mutations | useMutation with crpc.path.mutationOptions(). Toast patterns, optimistic updates. |
| Infinite Queries | useInfiniteQuery with crpc.path.infiniteQueryOptions(). Cursor-based pagination. |
| Type Inference | inferApiInputs, inferApiOutputs for tRPC-style type extraction. |
| Error Handling | Handle CRPCClientError on client. Error boundaries, toast notifications. |
Next.js
| Page | When to Use |
|---|---|
| Next.js Setup | Configure convexBetterAuth for RSC. Server caller factory, JWT caching. |
| RSC | Server components with prefetch, preloadQuery, HydrateClient. SSR data fetching. |
Auth (Better Auth)
| Page | When to Use |
|---|---|
| Auth Overview | Architecture overview. When to use Better Auth vs other auth solutions. |
| Auth Server | Complete Better Auth setup: schema, adapters, HTTP routes, helpers. |
| Auth Client | useAuth, Authenticated/Unauthenticated components. |
| Auth Triggers | User lifecycle hooks: beforeCreate, onCreate, onDelete. |
Reference
| Page | When to Use |
|---|---|
| CLI | better-convex dev for codegen. Procedure metadata generation. |
| Migration | Migrate from vanilla Convex. Function-by-function upgrade guide. |
| Comparison | Compare with tRPC, Convex hooks, other patterns. |
Common Workflows
New project setup:
- Quickstart → basic setup
- Templates → copy production files
- Concepts → understand folder structure
Add authentication:
- Auth Server → configure Better Auth
- Auth Client → use auth in components
- Middlewares → protect procedures
Add database features:
- Ents → relationships with
ctx.table() - Triggers → automatic side effects
- Aggregates → counts and sums
Server components (RSC):
- Next.js Setup → configure caller
- RSC → prefetch and hydrate