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/auth handles 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

Notes

  • Each app has its own Convex deployment (e.g., calnexus-production, lexilink-production)
  • Shared Convex patterns are documented in packages/storage/ and packages/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
HanseNexus 2026