convex
Mindrally/skills/convex/SKILL.md
Guidelines for developing with Convex backend-as-a-service platform, covering queries, mutations, actions, and real-time data patterns
Skill258 starsChanged 8 months ago
- Sends data out
What's in it
- Convex Development Guidelines
- General Development Specifications
- Code Style and Structure
- Error Handling
- UI Framework Integration
- Convex-Specific Patterns
- Queries
- Mutations
- Actions
- Schema Definition with Indexes
- HTTP Router
- Scheduled Jobs
- File Handling
- Best Practices
- Performance Considerations
---
name: convex
description: Guidelines for developing with Convex backend-as-a-service platform, covering queries, mutations, actions, and real-time data patterns
---
# Convex Development Guidelines
You are an expert in Convex backend development, TypeScript, and real-time data synchronization patterns.
## General Development Specifications
### Code Style and Structure
- Write concise TypeScript using functional declarations, iterators, and modules
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
- Structure code with exported components, subcomponents, helpers, and static types
- Use dash-case for directories with named exports
- Prefer interfaces over types; avoid enums in favor of union types
- Use functional components with declarative JSX patterns
### Error Handling
- Handle errors early in functions with guard clauses
- Log errors appropriately for debugging
- Provide user-friendly error messages
- Use Zod for form validation
- Implement proper error boundaries in React components
### UI Framework Integration
- Use Shadcn UI and Radix UI for component primitives
- Style with Tailwind CSS using responsive, mobile-first design
- Minimize useClient, useEffect, and useState usage
- Leverage React Server Components where applicable
- Use Suspense for loading states and dynamic loading for code splitting
## Convex-Specific Patterns
### Queries
Structure queries using the `query` constructor:
```typescript
import { query } from "./_generated/server";
import { v } from "convex/values";
export const getItems = query({
args: {
status: v.optional(v.string()),
},
handler: async (ctx, args) => {
// ctx provides: db, storage, auth
const identity = await ctx.auth.getUserIdentity();
if (args.status) {
return await ctx.db
.query("items")
.withIndex("by_status", (q) => q.eq("status", args.status))
.collect();
}
return await ctx.db.query("items").collect();
},
});
```
**Important**: Prefer Convex indexes over filters for better performance. Define indexes in schema.ts using the `.index()` method, then query with `.withIndex()`.
### Mutations
Structure mutations for database writes:
```typescript
import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const createItem = mutation({
args: {
title: v.string(),
description: v.optional(v.string()),
},
handler: async (ctx, args) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new Error("Not authenticated");
}
return await ctx.db.insert("items", {
title: args.title,
description: args.description,
userId: identity.subject,
createdAt: Date.now(),
});
},
});
```
### Actions
Use actions for external API calls and side effects:
```typescript
import { action } from "./_generated/server";
import { v } from "convex/values";
export const sendEmail = action({
args: {
to: v.string(),
subject: v.string(),
body: v.string(),
},
handler: async (ctx, args) => {
// Actions can call external APIs
const response = await fetch("https://api.email-service.com/send", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(args),
});
return response.ok;
},
});
```
### Schema Definition with Indexes
```typescript
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
items: defineTable({
title: v.string(),
description: v.optional(v.string()),
status: v.string(),
userId: v.string(),
createdAt: v.number(),
})
.index("by_status", ["status"])
.index("by_user", ["userId"])
.index("by_user_and_status", ["userId", "status"]),
});
```
### HTTP Router
Define HTTP routes for webhooks and external integrations:
```typescript
import { httpRouter } from "convex/server";
import { httpAction } from "./_generated/server";
const http = httpRouter();
http.route({
path: "/webhook",
method: "POST",
handler: httpAction(async (ctx, request) => {
const body = await request.json();
// Process webhook
return new Response(JSON.stringify({ success: true }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}),
});
export default http;
```
### Scheduled Jobs
Implement cron jobs for recurring tasks:
```typescript
import { cronJobs } from "convex/server";
import { internal } from "./_generated/api";
const crons = cronJobs();
// Run every hour
crons.interval(
"cleanup-old-items",
{ hours: 1 },
internal.tasks.cleanupOldItems
);
// Run at specific time (daily at midnight UTC)
crons.monthly(
"monthly-report",
{ day: 1, hourUTC: 0, minuteUTC: 0 },
internal.reports.generateMonthlyReport
);
export default crons;
```
### File Handling
Three-step process for file uploads:
```typescript
// 1. Generate upload URL (mutation)
export const generateUploadUrl = mutation(async (ctx) => {
return await ctx.storage.generateUploadUrl();
});
// 2. Client POSTs file to the URL
// const uploadUrl = await generateUploadUrl();
// const response = await fetch(uploadUrl, { method: "POST", body: file });
// const { storageId } = await response.json();
// 3. Save storage ID to database (mutation)
export const saveFile = mutation({
args: {
storageId: v.id("_storage"),
filename: v.string(),
},
handler: async (ctx, args) => {
return await ctx.db.insert("files", {
storageId: args.storageId,
filename: args.filename,
});
},
});
```
## Best Practices
1. **Always use indexes** for queries that filter or sort data
2. **Validate arguments** using Convex validators (`v.string()`, `v.number()`, etc.)
3. **Check authentication** early in handlers that require it
4. **Use internal functions** for operations that should not be exposed to clients
5. **Leverage real-time subscriptions** - Convex queries automatically update when data changes
6. **Keep mutations small** and focused on single operations
7. **Use actions for side effects** - never call external APIs from queries or mutations
8. **Handle errors gracefully** with proper error messages for users
## Performance Considerations
- Use `.withIndex()` instead of `.filter()` whenever possible
- Paginate large result sets using `.paginate()`
- Use `.first()` instead of `.collect()` when expecting a single result
- Consider data denormalization for frequently accessed data
- Use Convex's built-in caching - avoid implementing your own
More agent context in Mindrally/skills
264 other files this repository gives its agents, the first 60 shown.
Skill
- accessibility-a11yaccessibility-a11y/SKILL.md
- alpine-jsalpine-js/SKILL.md
- analytics-data-analysisanalytics-data-analysis/SKILL.md
- android-developmentandroid-development/SKILL.md
- angular-developmentangular-development/SKILL.md
- angularangular/SKILL.md
- anime-jsanime-js/SKILL.md
- anthropic-claude-developmentanthropic-claude-development/SKILL.md
- api-developmentapi-development/SKILL.md
- apollo-graphqlapollo-graphql/SKILL.md
- aspnet-coreaspnet-core/SKILL.md
- astroastro/SKILL.md
- auth0-authenticationauth0-authentication/SKILL.md
- autogen-developmentautogen-development/SKILL.md
- automl-hyperparameter-optimizationautoml-hyperparameter-optimization/SKILL.md
- aws-developmentaws-development/SKILL.md
- azureazure/SKILL.md
- backend-developmentbackend-development/SKILL.md
- bash-scriptingbash-scripting/SKILL.md
- beautifulsoup-parsingbeautifulsoup-parsing/SKILL.md
- bitbucket-workflowbitbucket-workflow/SKILL.md
- blazorblazor/SKILL.md
- blender-python-addonblender-python-addon/SKILL.md
- blockchainblockchain/SKILL.md
- bootstrapbootstrap/SKILL.md
- business-central-developmentbusiness-central-development/SKILL.md
- cheerio-parsingcheerio-parsing/SKILL.md
- chrome-extension-developmentchrome-extension-development/SKILL.md
- ci-cd-best-practicesci-cd-best-practices/SKILL.md
- clean-architectureclean-architecture/SKILL.md
- clean-codeclean-code/SKILL.md
- clerk-authenticationclerk-authentication/SKILL.md
- cloudflare-developmentcloudflare-development/SKILL.md
- computer-vision-opencvcomputer-vision-opencv/SKILL.md
- cppcpp/SKILL.md
- c-sharpc-sharp/SKILL.md
- csscss/SKILL.md
- cypresscypress/SKILL.md
- data-analysis-jupyterdata-analysis-jupyter/SKILL.md
- data-analystdata-analyst/SKILL.md
- data-jupyter-pythondata-jupyter-python/SKILL.md
- deep-learning-pythondeep-learning-python/SKILL.md
- deep-learning-pytorchdeep-learning-pytorch/SKILL.md
- deep-learningdeep-learning/SKILL.md
- deno-typescriptdeno-typescript/SKILL.md
- design-systemsdesign-systems/SKILL.md
- devopsdevops/SKILL.md
- django-pythondjango-python/SKILL.md
- django-rest-api-developmentdjango-rest-api-development/SKILL.md
- dockerdocker/SKILL.md
- dotnetdotnet/SKILL.md
- drizzle-ormdrizzle-orm/SKILL.md
- drupal-developmentdrupal-development/SKILL.md
- elasticsearch-best-practiceselasticsearch-best-practices/SKILL.md
- electron-developmentelectron-development/SKILL.md
- elixirelixir/SKILL.md
- embedded-stm32embedded-stm32/SKILL.md
- esbuild-bundleresbuild-bundler/SKILL.md
- ethereumethereum/SKILL.md
- expo-react-native-javascript-best-practicesexpo-react-native-javascript-best-practices/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool public_context_discussion, action report. How to connect one.

