convex-best-practices

Guidelines for building production-ready Convex apps covering function organization, query patterns, validation, TypeScript usage, error handling, and the Zen of Convex design philosophy

By waynesutton · 3,758 installs

npx skills add waynesutton/convexskills --skill convex-best-practices

Source repository · Upstream listing

Convex Best Practices Build production ready Convex applications by following established patterns for function organization, query optimization, validation, TypeScript usage, and error handling. Code Quality All patterns in this skill comply with @convex dev/eslint plugin . Install it for build time validation: The plugin enforces four rules: Rule What it enforces no old registered function syntax Object syntax with handler require argument validators args: {} on all functions explicit table ids Table name in db operations import wrong runtime No Node imports in Convex runtime Docs: https://docs.convex.dev/eslint Documentation Sources Before implementing, do not assume; fetch the latest documentation: Primary: https://docs.convex.dev/understanding/best practices/ Error Handling: https://docs.convex.dev/functions/error handling Write Conflicts: https://docs.convex.dev/error 1 For broader context: https://docs.convex.dev/llms.txt Instructions The Zen of Convex 1. Convex manages the hard parts Let Convex handle caching, real time sync, and consistency 2. Functions are the API Design your functions as your application's interface 3. Schema is truth Define your data model explicitly in schema.ts 4. TypeScript everywhere Leverage end to end type safety 5. Queries are reactive Think in terms of subscriptions, not requests Function Organization Organize your Convex functions by domain: Argument and Return Validation Always define validators for arguments AND return types: Query Patterns Use indexes instead of filters for efficient queries: Error Handling Use ConvexError for user facing errors: Avoiding Write Conflicts (Optimistic Concurrency Control) Convex uses OCC. Follow these patterns to minimize conflicts: TypeScript Best Practices Internal vs Public Functions Examples Complete CRUD Pattern Best Practices Never run npx convex deploy unless explicitly instructed Never run any git commands unless explicitly instructed Always define return validators for functions Use indexes for all queries that filter data Make mutations idempotent to handle retries gracefully Use ConvexError for user facing error messages Organize functions by domain (users.ts, tasks.ts, etc.) Use internal functions for sensitive operations Leverage TypeScript's Id and Doc types Common Pitfalls 1. Using filter instead of withIndex Always define indexes and use withIndex 2. Missing return validators Always specify the returns field 3. Non idempotent mutations Check current state before updating 4. Reading before patching unnecessarily Patch directly when possible 5. Not handling null returns Document IDs might not exist References Convex Documentation: https://docs.convex.dev/ Convex LLMs.txt: https://docs.convex.dev/llms.txt Best Practices: https://docs.convex.dev/understanding/best practices/ Error Handling: https://docs.convex.dev/functions/error handling Write Conflicts: https://docs.convex.dev/error 1