Architecture Decisions
ADR-0002: Convex as Backend Platform
Decision to use Convex as the backend platform for real-time, type-safe data management
Status
Accepted
Date: 2025-02-03
Context
Our SaaS products (CalNexus, Lexilink, Qript) require a full-stack backend with:
- Real-time sync for collaborative features (calendar, link sharing)
- Authentication with multiple providers (Google, email, magic links)
- Database with TypeScript type safety
- Serverless functions for business logic
- File storage for user uploads
- Scheduled jobs for background tasks (calendar sync, reminders)
- Fast iteration for a small team (2-3 developers)
Key constraints:
- Limited backend expertise — focus on product, not infrastructure
- Need production-ready auth out of the box
- Must scale to thousands of users without ops overhead
- TypeScript everywhere (frontend and backend)
- Cost-effective for early-stage products
Decision
We chose Convex as our backend platform for all apps. Convex provides:
- Type-safe database with automatic TypeScript codegen
- Real-time subscriptions via reactive queries
- Built-in authentication (
@convex-dev/auth) - Serverless functions (queries, mutations, actions)
- File storage with automatic CDN
- Scheduled functions (cron jobs)
- Zero ops — no servers, databases, or deployments to manage
Integration approach:
// Shared Convex patterns across all apps
import { api } from "@/convex/_generated/api"
import { useQuery, useMutation } from "convex/react"
// Type-safe queries
const events = useQuery(api.calendar.listEvents, { userId })
const createEvent = useMutation(api.calendar.createEvent)
Consequences
Positive
- Incredibly fast development: No backend setup, instant API generation
- Type safety end-to-end: Schema changes propagate automatically to frontend
- Real-time by default: Live updates without WebSocket boilerplate
- Built-in auth:
@convex-dev/authhandles OAuth, magic links, sessions - Zero ops: No servers to manage, automatic scaling, built-in backups
- Great DX: Hot reload, time-travel debugging, dashboard
- Generous free tier: Cost-effective for early products
Negative
- Vendor lock-in: Convex is proprietary, migration would be difficult
- Limited query flexibility: No SQL, no complex joins (must denormalize)
- Pricing uncertainty: Future costs as we scale are unclear
- New ecosystem: Fewer community resources than Firebase/Supabase
- Action limitations: Long-running tasks must be split up (5min timeout)
Neutral
- Different mental model: Reactive queries require thinking differently than REST/GraphQL
- Schema migrations: Handled via TypeScript, but must be carefully planned
- Testing: Convex’s test harness is good but requires learning
Alternatives Considered
Alternative 1: Supabase (PostgreSQL + Realtime)
- Description: Open-source Firebase alternative with Postgres
- Pros: PostgreSQL is a mature, powerful SQL database; self-hosting option available; large community
- Cons: More complex setup (migrations, schemas, row-level security); realtime is less polished than Convex
- Why not chosen: Too much backend complexity for our small team
Alternative 2: Firebase (Google)
- Description: Google’s BaaS platform with Firestore
- Pros: Battle-tested at massive scale; rich ecosystem of tools
- Cons: Firestore queries are limited and expensive; no TypeScript type safety; auth is clunky with Next.js
- Why not chosen: Poor TypeScript support and Firestore limitations
Alternative 3: Custom API (Next.js API Routes + Prisma + Postgres)
- Description: Build our own backend with traditional stack
- Pros: Complete control; no vendor lock-in; familiar patterns
- Cons: Must build auth, real-time, storage, scheduling ourselves; requires managing infrastructure
- Why not chosen: Too much work for a small team, slows product iteration
Alternative 4: PlanetScale + tRPC + NextAuth
- Description: Modern self-built stack with best-in-class tools
- Pros: Type-safe APIs with tRPC; excellent DB with PlanetScale
- Cons: No built-in real-time; more setup and glue code; must manage multiple services
- Why not chosen: More complexity than we need right now
References
- Convex Documentation
- @convex-dev/auth — Auth integration
- Convex + Next.js guide
Notes
- Each app has its own Convex deployment (e.g.,
calnexus-production,lexilink-production) - Shared Convex patterns are documented in
packages/storage/andpackages/auth/ - We use Convex Actions for integrations with external APIs (Google Calendar, Stripe, email)
- Scheduled functions handle background tasks (calendar sync every 15min, reminder notifications)
- If we hit Convex limitations, we can add a separate API layer for specific features