home / skills / phrazzld / claude-config / convex-development
This skill helps you optimize Convex backends for cost, performance, and security by applying best practices across queries, schemas, and migrations.
npx playbooks add skill phrazzld/claude-config --skill convex-developmentReview the files below or copy the command above to add this skill to your agents.
---
name: convex-development
description: |
Apply Convex database best practices for cost optimization, performance, security, and architecture.
Use when: building Convex backends, optimizing queries, handling embeddings/vector search,
reviewing Convex code, designing schemas, planning migrations, or discussing Convex architecture.
Keywords: Convex, real-time database, queries, mutations, actions, indexes, pagination,
vector search, embeddings, schema, migrations, ctx.auth, convex-helpers, bandwidth.
effort: high
---
# Convex Development
Best practices for robust, secure, performant, cost-effective Convex backends.
## Core Principle
**Deep modules via the `convex/model/` pattern.** Most logic should be plain TypeScript; query/mutation wrappers should be thin.
```
convex/
_generated/ # MUST commit to git!
model/ # Business logic (testable, reusable)
users.ts # Public API (thin wrappers)
schema.ts
```
## Critical Rules
1. **ALWAYS commit `convex/_generated/`** - Required for type-checking, CI/CD, team productivity
2. **Index what you query** - `.withIndex()` not `.filter()` for efficient queries
3. **Compound indexes for multi-field filters** - If querying `userId + status`, create index `["userId", "status"]` to filter at index level, not post-fetch
4. **Paginate everything** - Never unbounded `.collect()` on user-facing queries
5. **Trust `ctx.auth` only** - Never user-provided auth data
## Quick Reference
| Need | Use |
|------|-----|
| Read data reactively | `query` |
| Write to database | `mutation` |
| External APIs, vector search | `action` |
| Scheduled tasks | `internalMutation` / `internalAction` |
## Anti-Patterns Scanner
Run `scripts/anti_patterns_scanner.py ./convex` to detect common issues.
## Detailed References
For comprehensive guidance, see:
- `references/cost-mitigation.md` - Bandwidth optimization, indexing, pagination
- `references/embeddings-vectors.md` - Vector search patterns, co-location decisions
- `references/query-performance.md` - Compound indexes, query segmentation, caching
- `references/security-access.md` - Auth patterns, RLS, RBAC, convex-helpers
- `references/schema-migrations.md` - Expand/Contract pattern, environment management
- `references/architectural-patterns.md` - File organization, state machines, naming
## Philosophy
- **Cost First**: Bandwidth is often the largest cost. Index aggressively, paginate everything.
- **Security First**: Never trust client input. Always use `ctx.auth`.
- **Reactivity is Power**: Use `useQuery` for real-time updates; don't forfeit with one-off fetches.
- **Type Safety End-to-End**: Leverage Convex's full type chain from database to UI.
This skill applies Convex database best practices to optimize cost, performance, security, and architecture for production backends. It codifies patterns for schema design, queries, mutations, actions, indexing, pagination, and embeddings to keep systems efficient and maintainable. The guidance is practical, concrete, and geared toward teams building real-time apps with Convex.
The skill inspects Convex project structure and code to validate conventions like committing _generated/, thin public API wrappers, and a model/ layer for business logic. It highlights indexing opportunities, detects unbounded collections, flags auth anti-patterns, and advises where to run actions vs queries vs mutations. It also references patterns for vector search placement, schema migration strategy, and bandwidth/cost mitigation.
What should I commit to git for Convex?
Always commit convex/_generated/ so types remain consistent across CI and team members.
When should I use an action vs a query?
Use queries for reactive reads, mutations for database writes, and actions for external APIs, embedding/vector search, or long-running tasks.
How do I control bandwidth costs?
Index aggressively, paginate all user-facing queries, and avoid returning full collections with .collect(); optimize data shapes returned to clients.