Convex Development Guide
Provide comprehensive Convex development guidance to avoid common mistakes and ensure code compiles on first try.
Priorities
- Compile + typecheck on first try
- Respect Convex's constraints (indexes, limits, auth, schedulers, file storage)
- Avoid expensive / subtle bugs (wrong indexes, misuse of actions, broken hooks)
Mental Model
Convex is a hosted backend with:
- Database: documents + indexes + full-text search
- Functions:
query,mutation,action, plus internal variants - Realtime queries:
useQueryon the client auto-subscribes - File storage, Auth (via
@convex-dev/auth), Scheduler (cron +runAfter)
Code layout:
- Backend:
convex/*.tsfiles - Client: React using
convex/react(useQuery,useMutation) - Generated API:
convex/_generated/apiexportsapi+internal
Quick Reference
Functions
- Import from
./_generated/server - Use
query({ args, handler })syntax - Always define
argsvalidators
Indexes (CRITICAL)
- Never use
.filter()- use.withIndex()instead - Never define
by_creation_timeindex (it's built-in) - Never include
_creationTimein custom index fields
Actions
- Add
"use node";at top for Node modules - Never use
ctx.db- usectx.runQuery/ctx.runMutation - Only actions support dynamic imports
Scheduler
- Auth does NOT propagate - use internal functions
- Use function references (
internal.file.fn), not the function itself
Migrations
- Install
@convex-dev/migrationscomponent - Modify schema to allow old+new values → run migration → update schema to require new values
- Use
migrations.define({ table, migrateOne })to define - Return object from
migrateOnefor auto-patch shorthand - Run via CLI:
npx convex run migrations:run '{fn: "migrations:myMigration"}' - Use
dryRun: trueto validate before committing
React Hooks
- Never call hooks conditionally
- Use
"skip"pattern:useQuery(api.foo, condition ? args : "skip") usePaginatedQueryreturns{ results, status, loadMore }for infinite scroll
Testing
- Use
convex-testwith Vitest - Pass
schematoconvexTest()for validation - Use
t.withIdentity()for auth testing
Reference Files
Load these as needed based on the task:
| Topic | File | When to use |
|---|---|---|
| Schema & Validators | schema-validators.md | Defining tables, validators, system fields |
| Functions | functions.md | Query/mutation/action patterns, calling functions |
| Indexes & Queries | indexes-queries.md | Database queries, indexes, search |
| Pagination | pagination.md | usePaginatedQuery, cursor-based pagination, infinite scroll |
| Actions & HTTP | actions-http.md | Actions, HTTP endpoints, external APIs |
| Scheduling | scheduling.md | Cron jobs, scheduled functions |
| File Storage | file-storage.md | Uploads, downloads, file metadata |
| Migrations | migrations.md | Online migrations, schema changes, data transformations |
| Limits | limits.md | Size limits, time limits, design constraints |
| Environment Variables | env-secrets.md | Secrets, API keys, environment setup |
| React Patterns | react-patterns.md | useQuery, useMutation, skip pattern |
| Auth | auth.md | Authentication, user identity |
| Components | components.md | Presence, ProseMirror, Resend components |
| TypeScript Fixes | typescript-fixes.md | TS2589 errors, static API generation |
| Checklist | checklist.md | Pre-commit verification checklist |
| Testing | testing.md | convex-test, Vitest patterns |
Process
- Check the quick reference above for common patterns
- Load specific reference files based on the task
- Verify against the checklist before finalizing code