Convex conventions
These are house-style defaults, not a Convex manual. Use current official Convex
skills for scaffolding, auth, migrations, performance work, components, and API
mechanics; this skill adds project policy. Apply only what the requested change
touches.
Authority
Verify each touched API against live Convex docs and the installed version.
Read release notes before a major or minor upgrade. Live docs win over this
skill; memory and prior turns do not establish current API behavior.
Layout and shared shapes
- Keep
convex/ at root and never edit _generated/.
schema.ts owns defineSchema and table declarations.
auth.config.ts owns the Clerk JWT provider.
- Keep one module each for reusable table validators, semantic validation, auth
helpers, and rate-limit configuration.
- Add
crons.ts and http.ts only when used.
- Public feature surfaces and their tests are co-located.
- Define table validators once and compose them into schema,
args, and
returns; do not redeclare an existing shape inline.
Auth and public functions
- Clerk is the identity provider. Server code derives identity from
ctx.auth.getUserIdentity() through one helper; clients never submit userId.
- Every public function authenticates at the top and declares both
args and
returns validators.
- Use internal functions for scheduling, sensitive side effects, and
cross-function reuse that must not be public.
- Keep structural validation in validators and semantic checks such as date
correctness, length caps, and sanitization in the handler.
Reads, writes, and effects
- Indexes narrow candidates; further filtering happens in code. Give indexes
semantic names and avoid redundant ones.
- Cap every otherwise unbounded query with
.take(); comment only when the cap
is load-bearing.
- Queries are pure and deterministic: no
Date.now() inside them.
- Mutations write. Actions call external systems. An action persists through an
internal mutation rather than mixing the roles.
- Rate-limit every public mutation with the current
@convex-dev/rate-limiter API. Token bucket suits high-frequency operations;
fixed window suits low-frequency operations.
Stored data
- User-created rows use soft deletion with optional numeric
deletedAt; public
mutations do not hard-delete them.
- Audit trails are append-only records.
- Server metadata such as identity and timestamps comes from handler context,
never client args.
- Data-at-rest schema changes use widen, migrate, then narrow through the
official migration workflow.
- Aggregate additions include a backfill. Aggregate synchronization failure
must not block the primary write.
Client types and components
- Derive client types from generated
Doc<...> and Id<...>.
- One dedicated module re-exports semantic client aliases; app code imports
there, never directly from
convex/_generated, and never manually copies table
shapes.
- Prefer official Convex components for existing capabilities and verify each
component README. Use the official component workflow when authoring a new
reusable component.
Completion
- Codegen and typecheck pass.
- Relevant function tests and the project gate pass.
- Any schema migration ran against the development deployment and its result is
recorded.
- No public function lacks auth,
args, or returns; no public mutation lacks
rate limiting; no unbounded query lacks a cap.
1---2name: convex-conventions3description: Applies the user's Convex backend conventions while deferring mechanics to upstream Convex skills and current APIs to the live Convex docs. Use when scaffolding, reviewing, or refactoring Convex functions, schemas, or auth.4license: Unlicense OR MIT5---67# Convex conventions89These are house-style defaults, not a Convex manual. Use current official Convex10skills for scaffolding, auth, migrations, performance work, components, and API11mechanics; this skill adds project policy. Apply only what the requested change12touches.1314## Authority1516Verify each touched API against live Convex docs and the installed version.17Read release notes before a major or minor upgrade. Live docs win over this18skill; memory and prior turns do not establish current API behavior.1920## Layout and shared shapes2122- Keep `convex/` at root and never edit `_generated/`.23- `schema.ts` owns `defineSchema` and table declarations.24- `auth.config.ts` owns the Clerk JWT provider.25- Keep one module each for reusable table validators, semantic validation, auth26 helpers, and rate-limit configuration.27- Add `crons.ts` and `http.ts` only when used.28- Public feature surfaces and their tests are co-located.29- Define table validators once and compose them into schema, `args`, and30 `returns`; do not redeclare an existing shape inline.3132## Auth and public functions3334- Clerk is the identity provider. Server code derives identity from35 `ctx.auth.getUserIdentity()` through one helper; clients never submit `userId`.36- Every public function authenticates at the top and declares both `args` and37 `returns` validators.38- Use internal functions for scheduling, sensitive side effects, and39 cross-function reuse that must not be public.40- Keep structural validation in validators and semantic checks such as date41 correctness, length caps, and sanitization in the handler.4243## Reads, writes, and effects4445- Indexes narrow candidates; further filtering happens in code. Give indexes46 semantic names and avoid redundant ones.47- Cap every otherwise unbounded query with `.take()`; comment only when the cap48 is load-bearing.49- Queries are pure and deterministic: no `Date.now()` inside them.50- Mutations write. Actions call external systems. An action persists through an51 internal mutation rather than mixing the roles.52- Rate-limit every public mutation with the current53 `@convex-dev/rate-limiter` API. Token bucket suits high-frequency operations;54 fixed window suits low-frequency operations.5556## Stored data5758- User-created rows use soft deletion with optional numeric `deletedAt`; public59 mutations do not hard-delete them.60- Audit trails are append-only records.61- Server metadata such as identity and timestamps comes from handler context,62 never client args.63- Data-at-rest schema changes use widen, migrate, then narrow through the64 official migration workflow.65- Aggregate additions include a backfill. Aggregate synchronization failure66 must not block the primary write.6768## Client types and components6970- Derive client types from generated `Doc<...>` and `Id<...>`.71- One dedicated module re-exports semantic client aliases; app code imports72 there, never directly from `convex/_generated`, and never manually copies table73 shapes.74- Prefer official Convex components for existing capabilities and verify each75 component README. Use the official component workflow when authoring a new76 reusable component.7778## Completion7980- Codegen and typecheck pass.81- Relevant function tests and the project gate pass.82- Any schema migration ran against the development deployment and its result is83 recorded.84- No public function lacks auth, `args`, or `returns`; no public mutation lacks85 rate limiting; no unbounded query lacks a cap.