convex-best-practices

Installation
SKILL.md

name: convex-best-practices description: Production patterns for Convex apps and the rules the @convex-dev/eslint-plugin enforces: validators, indexes, idempotent mutations, avoiding OCC conflicts, thin function wrappers, error handling. Use when reviewing Convex code, asking whether a pattern is right, setting up ESLint, or fixing write conflicts and slow queries.

Convex best practices

The patterns that keep a Convex app fast and correct in production. The rule that matters most: read as little as possible before you write, and read through an index.

Rules that matter most

  1. Validators on every function. args and returns, with returns: v.null() when nothing comes back.
  2. Indexes, not filters. Every table read goes through withIndex against an index in convex/schema.ts.
  3. Idempotent mutations. Return early when the document is already in the target state so retries are safe.
  4. Patch without reading first. ctx.db.patch(id, fields) throws if the doc is missing; you rarely need the old value.
  5. Promise.all for independent writes. Do not await them one at a time.
  6. Schedule internal.* only. Crons and ctx.scheduler run without a client, so public targets skip auth.
  7. Thin wrappers. Auth and business logic live in plain helpers that take ctx.
  8. ConvexError for anything a client should read. Plain Error messages are redacted in production.
Installs
3.8K
GitHub Stars
407
First Seen
Jan 24, 2026