Convex reactive database patterns, schema design, real-time queries, mutations, actions, authentication, migrations, performance optimization, and component creation. Use when designing Convex schemas, writing queries/mutations, managing the Convex backend, setting up auth, migrating data, optimizing performance, or building Convex components.
100
100%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
For project-specific schema, functions, and deployment details, see database-config.md.
Read the matching reference file before writing code for any of these topics:
| Topic | Reference |
|---|---|
| Project setup & scaffolding | references/quickstart.md |
| Schema & data migrations | references/migrations.md |
| Performance optimization | references/performance-audit.md |
| Authentication & access control | references/auth-setup.md |
| Component creation & isolation | references/components.md |
Function Registration
query/mutation/action; Private: internalQuery/internalMutation/internalAction (import from ./_generated/server)returns validator; use returns: v.null() when the function returns nothing (JS implicitly returns null)Function References
api.filename.functionName for public and internal.filename.functionName for internal functions (from ./_generated/api)ctx.runQuery/ctx.runMutation/ctx.runAction — always use function referencesQueries
.filter() — define an index in the schema and use .withIndex() instead.filter() is equivalent to JS filtering — neither pushes the filter to storage; only .withIndex() actually reduces documents scanned.unique() for single document queries.delete() on queries — collect results, then call ctx.db.delete(row._id) on eachMutations
references/migrations.mdctx.db.patch() — no-op writes still trigger invalidation and replicationActions
"use node"; at the top of files containing actions that use Node.js built-in modulesctx.db inside actions — actions don't have database access; use ctx.runQuery/ctx.runMutation insteadSchema
["field1", "field2"] → "by_field1_and_field2"_id or _creationTime — they are automatic system fieldsby_team_and_user covers both by_team queries and by_team_and_user queries)Components
ctx.auth or process.envv.string(), not v.id("parentTable")query/mutation/action from the component's own ./_generated/server, not the app's generated filesGeneral
convex/schema.ts using defineSchema/defineTablev.null() not v.undefined() — undefined is not a valid Convex valueprocess.env in actions onlyimport { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
users: defineTable({
name: v.string(),
email: v.string(),
role: v.union(v.literal("admin"), v.literal("user")),
})
.index("by_email", ["email"])
.index("by_role", ["role"]),
});import { query } from "./_generated/server";
import { v } from "convex/values";
export const list = query({
args: { role: v.optional(v.string()) },
returns: v.array(v.any()),
handler: async (ctx, args) => {
if (args.role) {
return await ctx.db.query("users")
.withIndex("by_role", q => q.eq("role", args.role!))
.collect();
}
return await ctx.db.query("users").collect();
},
});import { mutation } from "./_generated/server";
import { v } from "convex/values";
export const create = mutation({
args: { name: v.string(), email: v.string() },
returns: v.id("users"),
handler: async (ctx, args) => {
return await ctx.db.insert("users", { ...args, role: "user" });
},
});import { query } from "./_generated/server";
export const getMyProfile = query({
args: {},
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Not authenticated");
return await ctx.db
.query("users")
.withIndex("by_tokenIdentifier", (q) =>
q.eq("tokenIdentifier", identity.tokenIdentifier)
)
.unique();
},
});references/migrations.md if the change is breaking (adding required fields, changing types, deleting fields)convex/schema.ts and run npx convex dev locally; confirm the dev server starts and responds. Run a small validation script or sample queries to verify schema changes.returns validators and unit test against the dev server.npx convex deploy to push the change to production.curl -fsS https://<APP_URL>/health || (echo "health check failed" && exit 1)If an issue occurs: roll back via npx convex import of the last good export, fix locally, and re-deploy.
| Step | Checkpoint |
|---|---|
| Schema change | npx convex dev starts without errors |
| Migration needed | references/migrations.md checklist completed |
| Auth function | ctx.auth.getUserIdentity() returns non-null in test |
| Deploy | Smoke check passes; no convex insights regressions |
| Component | npx convex codegen succeeds; sibling functions inspected |
18c6f2c
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.