convex-review
Convex Code Review
Security Checklist
1. Argument AND Return Validators
- All public
query,mutation,actionhaveargsvalidators - All functions have
returnsvalidators - No
v.any()for sensitive data - HTTP actions validate request body (Zod recommended)
Search: query({, mutation({, action({ - check each has args: AND returns:
2. Error Handling
- Uses
ConvexErrorfor user-facing errors (not plainError) - Error codes are structured:
{ code: "NOT_FOUND", message: "..." } - No sensitive info leaked in error messages
Search: throw new Error should be throw new ConvexError
3. Access Control
- All public functions check
ctx.auth.getUserIdentity()where needed - Uses auth helpers (
requireAuth,requireRole) - No client-provided email/username for authorization
- Row-level access verified (ownership checks)
Search: ctx.auth.getUserIdentity should appear in most public functions
4. Internal Functions
-
ctx.runQuery,ctx.runMutation,ctx.runActionuseinternal.*notapi.* -
ctx.scheduler.runAfterusesinternal.*notapi.* - Crons in
crons.tsuseinternal.*notapi.*
Search: api. in convex directory - should not be used for scheduling/running
5. Table Names in DB Calls
- All
ctx.db.get,patch,replace,deleteinclude table name as first arg
Search: db.get(, db.patch( - first arg should be quoted string
Performance Checklist
6. Database Queries
- No
.filter()on queries (use.withIndex()or filter in code) -
.collect()only with bounded results (<1000 docs) - Pagination for large result sets
Search: \.filter\(\(?q, \.collect\(
7. Indexes
- No redundant indexes (
by_foo+by_foo_and_bar) - All filtered queries use
.withIndex() - Index names include all fields
Review: schema.ts index definitions
8. Date.now() in Queries
- No
Date.now()in query functions - Time filtering uses boolean fields or client-passed timestamps
9. Promise Handling
- All promises awaited (
ctx.scheduler,ctx.db.*)
ESLint: no-floating-promises
Architecture Checklist
10. Action Usage
- Actions have
"use node";if using Node.js APIs -
ctx.runActiononly when switching runtimes - No sequential
ctx.runMutation/ctx.runQuery(combine for consistency)
11. Code Organization
- Business logic in helper functions (
convex/model/) - Public API handlers are thin wrappers
- Auth helpers in
convex/lib/auth.ts
12. Transaction Consistency
- Related reads in same query/mutation
- Batch operations in single mutation
- Mutations are idempotent
Quick Regex Searches
| Issue | Regex | Fix |
|---|---|---|
.filter() |
\.filter\(\(?q |
Use .withIndex() |
| Missing returns | handler:.*async without returns: |
Add returns: |
| Plain Error | throw new Error\( |
Use ConvexError |
| Missing table name | db\.(get|patch)\([^"'] |
Add table name |
Date.now() in query |
Date\.now\(\) |
Remove from queries |
api.* scheduling |
api\.[a-z] |
Use internal.* |
Production Readiness
- Security: Validators + ConvexError + Auth checks + Internal functions
- Performance: Indexes + Bounded queries + No Date.now()
- Architecture: Helper functions + Proper action usage + "use node"
- Code Quality: Awaited promises + Table names + Return validators
More from aaronvanston/skills-convex
convex-security
Security best practices for Convex functions including ConvexError handling, argument/return validation, authentication helpers, access control, rate limiting, and internal functions. Use when writing public queries/mutations/actions, implementing authentication, adding authorization checks, handling errors, or reviewing Convex functions for security.
7convex-cron
Scheduled functions and cron jobs in Convex. Use when setting up recurring tasks, cleanup jobs, data syncing, scheduled notifications, or any background automation that runs on a schedule.
6convex-actions
Best practices for Convex actions, transactions, and scheduling. Use when writing actions that call external APIs, using ctx.runQuery/ctx.runMutation, scheduling functions with ctx.scheduler, or working with the Convex runtime vs Node.js runtime ("use node").
6convex-patterns
Code organization patterns and TypeScript best practices for Convex. Use when structuring a Convex project, writing helper functions, defining schemas, working with types like QueryCtx/MutationCtx/ActionCtx, or organizing code in a convex/model directory.
6convex-agents
Building AI agents and assistants with Convex. Use when implementing chat interfaces, AI assistants, tool-calling agents, RAG (retrieval-augmented generation), conversation threads, or integrating LLMs like OpenAI/Anthropic.
6convex-realtime
Realtime subscriptions and optimistic updates in Convex. Use when implementing live data updates, optimistic UI, pagination with realtime, presence indicators, typing indicators, or any feature requiring instant data synchronization.
6