Why Convex
Reactive by default
Every Convex query auto-updates on the client when underlying data changes. No polling, no websocket plumbing, no
refetch calls. Build a chat or a dashboard, and it’s live without effort.End-to-end TypeScript
The schema is TypeScript. Queries return typed results. Your React component consumes the same types. No DTO mapping, no codegen, no client/server drift.
Serverless functions, no infra
Queries, mutations, actions, and scheduled functions run on Convex’s managed runtime. No containers to ship, no databases to provision.
Native primitives for hard things
File storage, vector search, full-text search, scheduled jobs, transactional mutations — all first-class, not bolted on.
The four function types
Queries
Read data. Reactive — clients subscribe and get updates automatically. Cannot mutate data.
Mutations
Write data, transactionally. ACID guarantees. Cannot call third-party APIs.
Actions
Call third-party APIs, run long-running work. Use
process.env. Can run mutations and queries internally.Scheduled functions
Cron-style or one-shot delayed execution. Common for retries, cleanups, reminders.
A minimal example
The schema:convex/schema.ts
convex/tasks.ts
convex/tasks.ts
components/TaskList.tsx
toggle runs, every connected client viewing the same query updates immediately. No refetch, no manual invalidation.
How vly uses Convex
vly maps app concepts onto Convex concepts: When you ask vly to “send an email when a task is assigned,” vly creates a Convex action (because actions can call external APIs), wires it into the assignment mutation, and adds the API key to your environment.When you’ll edit Convex code
Most of the time, you won’t — vly handles it. But there are good reasons to drop into Code mode and edit a Convex file directly:Adding an index for performance
Adding an index for performance
A query is slow. You add
.index("by_field", ["fieldName"]) to the schema, then re-prompt or hand-edit the query to use it. See Indexes.Tweaking validation
Tweaking validation
Convex schema validators (
v.string(), v.optional(...), v.union(...)) define what data shapes are allowed. Tightening or loosening these by hand is sometimes faster than prompting.Custom action logic
Custom action logic
Calling a third-party API with non-trivial logic — retries, custom serialization, complex auth flows. Hand-edit the action.
Reading the migration history
Reading the migration history
convex/_generated/ shows the current schema state; the schema files show your authored intent. When debugging schema drift, read both. See Migrations.Limits
Convex isn’t infinite. The current limits:Next
Convex deep dive
The full reference: schema, queries, mutations, actions, search, storage.
Real-time sync
How Convex’s reactive sync works under the hood.
Data modeling patterns
Schema patterns for the most common app shapes.
