Skip to main content

convex

Convex reactive backend expert: schema design, TypeScript functions, real-time subscriptions, auth, file storage, scheduling, and deployment.

Quellinformationen

Repository
davila7/claude-code-templates
Letzte Quellaktivität
4. April 2026 um 23:08
Erkannte Sprache von SKILL.md
Englisch
Sterne
32.672
Forks
3.772

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
convex
description
Convex reactive backend expert: schema design, TypeScript functions, real-time subscriptions, auth, file storage, scheduling, and deployment.
risk
safe
source
https://docs.convex.dev
date_added
2026-02-27
# Convex You are an expert in Convex — the open-source, reactive backend platform where queries are TypeScript code. You have deep knowledge of schema design, function authoring (queries, mutations, actions), real-time data subscriptions, authentication, file storage, scheduling, and deployment workflows across React, Next.js, Angular, Vue, Svelte, React Native, and server-side environments. ## When to Use - Use when building a new project with Convex as the backend - Use when adding Convex to an existing React, Next.js, Angular, Vue, Svelte, or React Native app - Use when designing schemas for a Convex document-relational database - Use when writing or debugging Convex functions (queries, mutations, actions) - Use when implementing real-time/reactive data patterns - Use when setting up authentication with Convex Auth or third-party providers (Clerk, Auth0, etc.) - Use when working with Convex file storage, scheduled functions, or cron jobs - Use when deploying or managing Convex projects ## Core Concepts Convex is a **document-relational** database with a fully managed backend. Key differentiators: - **Reactive by default**: Queries automatically re-run and push updates to all connected clients when underlying data changes - **TypeScript-first**: All backend logic — queries, mutations, actions, schemas — is written in TypeScript - **ACID transactions**: Serializable isolation with optimistic concurrency control - **No infrastructure to manage**: Serverless, scales automatically, zero config - **End-to-end type safety**: Types flow from schema → backend functions → client hooks ### Function Types | Type | Purpose | Can Read DB | Can Write DB | Can Call External APIs | Cached/Reactive | | :-------------- | :------------------------ | :------------- | :---------------- | :--------------------- | :-------------- | | **Query** | Read data | ✅ | ❌ | ❌ | ✅ | | **Mutation** | Write data | ✅ | ✅ | ❌ | ❌ | | **Action** | Side effects | via `runQuery` | via `runMutation` | ✅ | ❌ | | **HTTP Action** | Webhooks/custom endpoints | via `runQuery` | via `runMutation` | ✅ | ❌ | ## Project Setup ### New Project (Next.js) ```bash npx create-next-app@latest my-app cd my-app && npm install convex npx convex dev ``` ### Add to Existing Project ```bash npm install convex npx convex dev ``` The `npx convex dev` command: 1. Prompts you to log in (GitHub) 2. Creates a project and deployment 3. Generates `convex/` folder for backend functions 4. Syncs functions to your dev deployment in real-time 5. Creates `.env.local` with `CONVEX_DEPLOYMENT` and `NEXT_PUBLIC_CONVEX_URL` ### Folder Structure ``` my-app/ ├── convex/ │ ├── _generated/ ← Auto-generated (DO NOT EDIT) │ │ ├── api.d.ts │ │ ├── dataModel.d.ts │ │ └── server.d.ts │ ├── schema.ts ← Database schema definition │ ├── tasks.ts ← Query/mutation functions │ └── http.ts ← HTTP actions (optional) ├── .env.local ← CONVEX_DEPLOYMENT, NEXT_PUBLIC_CONVEX_URL └── convex.json ← Project config (optional) ``` ## Schema Design Define your schema in `convex/schema.ts` using the validator library: ```typescript import { defineSchema, defineTable } from "convex/server"; import { v } from "convex/values"; export default defineSchema({ users: defineTable({ name: v.string(), email: v.string(), avatarUrl: v.optional(v.string()), tokenIdentifier: v.string(), }) .index("by_token", ["tokenIdentifier"]) .index("by_email", ["email"]), messages: defineTable({ authorId: v.id("users"), channelId: v.id("channels"), body: v.string(), attachmentId: v.optional(v.id("_storage")), }) .index("by_channel", ["channelId"]) .searchIndex("search_body", { searchField: "body" }), channels: defineTable({ name: v.string(), description: v.optional(v.string()), isPrivate: v.boolean(), }), }); ``` ### Validator Types | Validator | TypeScript Type | Notes | | :-------------------------------- | :-------------------- | :--------------------------------------------- | | `v.string()` | `string` | | | `v.number()` | `number` | IEEE 754 float | | `v.bigint()` | `bigint` | | | `v.boolean()` | `boolean` | | | `v.null()` | `null` | | | `v.id("tableName")` | `Id<"tableName">` | Document reference | | `v.array(v.string())` | `string[]` | | | `v.object({...})` | `{...}` | Nested objects | | `v.optional(v.string())` | `string \| undefined` | | | `v.union(v.string(), v.number())` | `string \| number` | | | `v.literal("active")` | `"active"` | Literal types | | `v.bytes()` | `ArrayBuffer` | Binary data | | `v.float64()` | `number` | Explicit 64-bit float (used in vector indexes) | | `v.any()` | `any` | Escape hatch | ### Indexes ```typescript // Single-field index defineTable({ email: v.string() }).index("by_email", ["email"]); // Compound index (order matters for range queries) defineTable({ orgId: v.string(), createdAt: v.number(), }).index("by_org_and_date", ["orgId", "createdAt"]); // Full-text search index defineTable({ body: v.string(), channelId: v.id("channels") }).searchIndex( "search_body", { searchField: "body", filterFields: ["channelId"], }, ); // Vector search index (for AI/embeddings) defineTable({ embedding: v.array(v.float64()), text: v.string() }).vectorIndex( "by_embedding", { vectorField: "embedding", dimensions: 1536, }, ); ``` ## Writing Functions ### Queries (Read Data) Queries are reactive — clients automatically get updates when data changes. ````typescript import { query } from "./_generated/server"; import { v } from "convex/values"; // Simple query — list all tasks export const list = query({ args: {}, handler: async (ctx) => { return await ctx.db.query("tasks").collect(); }, }); // Query with arguments and filtering export const getByChannel = query({ args: { channelId: v.id("channels") }, handler: async (ctx, args) => { return await ctx.db .query("messages") .withIndex("by_channel", (q) => q.eq("channelId", args.channelId)) .order("desc") .take(50); }, }); // Query with auth check export const getMyProfile = query({ args: {}, handler: async (ctx) => { const identity = await ctx.auth.getUserIdentity(); if (!identity) return null; return await ctx.db .query("users") .withIndex("by_token", (q) => q.eq("tokenIdentifier", identity.tokenIdentifier), ) .unique(); }, }); ### Paginated Queries Use cursor-based pagination for lists or infinite scroll UIs. ```typescript import { query } from "./_generated/server"; import { paginationOptsValidator } from "convex/server"; export const listPaginated = query({ args: { paginationOpts: paginationOptsValidator }, handler: async (ctx, args) => { return await ctx.db .query("messages") .order("desc") .paginate(args.paginationOpts); }, }); ``` ### Mutations (Write Data) Mutations run as ACID transactions with serializable isolation. ```typescript import { mutation } from "./_generated/server"; import { v } from "convex/values"; // Insert a document export const create = mutation({ args: { text: v.string(), isCompleted: v.boolean() }, handler: async (ctx, args) => { const taskId = await ctx.db.insert("tasks", { text: args.text, isCompleted: args.isCompleted, }); return taskId; }, }); // Update a document export const update = mutation({ args: { id: v.id("tasks"), isCompleted: v.boolean() }, handler: async (ctx, args) => { await ctx.db.patch(args.id, { isCompleted: args.isCompleted }); }, }); // Delete a document export const remove = mutation({ args: { id: v.id("tasks") }, handler: async (ctx, args) => { await ctx.db.delete(args.id); }, }); // Multi-document transaction (automatically atomic) export const transferCredits = mutation({ args: { fromUserId: v.id("users"), toUserId: v.id("users"), amount: v.number(), }, handler: async (ctx, args) => { const fromUser = await ctx.db.get(args.fromUserId); const toUser = await ctx.db.get(args.toUserId); if (!fromUser || !toUser) throw new Error("User not found"); if (fromUser.credits < args.amount) throw new Error("Insufficient credits"); await ctx.db.patch(args.fromUserId, { credits: fromUser.credits - args.amount, }); await ctx.db.patch(args.toUserId, { credits: toUser.credits + args.amount, }); }, }); ```` ### Actions (External APIs & Side Effects) Actions can call third-party services but cannot directly access the database — they must use `ctx.runQuery` and `ctx.runMutation`. ```typescript import { action } from "./_generated/server"; import { v } from "convex/values"; import { api } from "./_generated/api"; export const sendEmail = action({ args: { to: v.string(), subject: v.string(), body: v.string() }, handler: async (ctx, args) => { // Call external API const response = await fetch("https://api.sendgrid.com/v3/mail/send", { method: "POST", headers: { Authorization: `Bearer ${process.env.SENDGRID_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ personalizations: [{ to: [{ email: args.to }] }], from: { email: "noreply@example.com" }, subject: args.subject, content: [{ type: "text/plain", value: args.body }], }), }); if (!response.ok) throw new Error("Failed to send email"); // Write result back to database via mutation await ctx.runMutation(api.emails.recordSent, { to: args.to, subject: args.subject, sentAt: Date.now(), });
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen