AI SummaryCursor rules for Convex best practices, providing guidelines for database schema design, queries, mutations, and function syntax in TypeScript/JavaScript projects. Useful for developers building Convex backends who want AI-assisted code review within Cursor.
Install
Copy this and paste it into Claude Code, Cursor, or any AI assistant:
I want to add the "diff0 — Cursor Rules" prompt rules to my project. Repository: https://github.com/eersnington/diff0 Please read the repo to find the rules/prompt file, then: 1. Download it to the correct location (.cursorrules, .windsurfrules, .github/prompts/, or project root — based on the file type) 2. If there's an existing rules file, merge the new rules in rather than overwriting 3. Confirm what was added
Description
AI Code Review for GitHub - OSS Coderabbit and Greptile (applied for Vercel's OSS Program)
New function syntax
• ALWAYS use the new function syntax for Convex functions. For example: `typescript import { query } from "./_generated/server"; import { v } from "convex/values"; export const f = query({ args: {}, returns: v.null(), handler: async (ctx, args) => { // Function body }, }); `
Http endpoint syntax
• HTTP endpoints are defined in convex/http.ts and require an httpAction decorator. For example: `typescript import { httpRouter } from "convex/server"; import { httpAction } from "./_generated/server"; const http = httpRouter(); http.route({ path: "/echo", method: "POST", handler: httpAction(async (ctx, req) => { const body = await req.bytes(); return new Response(body, { status: 200 }); }), }); ` • HTTP endpoints are always registered at the exact path you specify in the path field. For example, if you specify /api/someRoute, the endpoint will be registered at /api/someRoute.
Validators
• Below is an example of an array validator: `typescript import { mutation } from "./_generated/server"; import { v } from "convex/values"; export default mutation({ args: { simpleArray: v.array(v.union(v.string(), v.number())), }, handler: async (ctx, args) => { //... }, }); ` • Below is an example of a schema with validators that codify a discriminated union type: `typescript import { defineSchema, defineTable } from "convex/server"; import { v } from "convex/values"; export default defineSchema({ results: defineTable( v.union( v.object({ kind: v.literal("error"), errorMessage: v.string(), }), v.object({ kind: v.literal("success"), value: v.number(), }) ) ), }); ` • Always use the v.null() validator when returning a null value. Below is an example query that returns a null value: `typescript import { query } from "./_generated/server"; import { v } from "convex/values"; export const exampleQuery = query({ args: {}, returns: v.null(), handler: async (ctx, args) => { console.log("This query returns a null value"); return null; }, }); ` • Here are the valid Convex types along with their respective validators: Convex Type | TS/JS type | Example Usage | Validator for argument validation and schemas | Notes | | ----------- | ------------| -----------------------| -----------------------------------------------| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | Id | string | doc._id | v.id(tableName) | | | Null | null | null | v.null() | JavaScript's undefined is not a valid Convex value. Functions the return undefined or do not return will return null when called from a client. Use null instead. | | Int64 | bigint | 3n | v.int64() | Int64s only support BigInts between -2^63 and 2^63-1. Convex supports bigints in most modern browsers. | | Float64 | number | 3.1 | v.number() | Convex supports all IEEE-754 double-precision floating point numbers (such as NaNs). Inf and NaN are JSON serialized as strings. | | Boolean | boolean | true | v.boolean() | | String | string | "abc" | v.string() | Strings are stored as UTF-8 and must be valid Unicode sequences. Strings must be smaller than the 1MB total size limit when encoded as UTF-8. | | Bytes | ArrayBuffer | new ArrayBuffer(8) | v.bytes() | Convex supports first class bytestrings, passed in as ArrayBuffers. Bytestrings must be smaller than the 1MB total size limit for Convex types. | | Array | Array] | [1, 3.2, "abc"] | v.array(values) | Arrays can have at most 8192 values. | | Object | Object | {a: "abc"} | v.object({property: value}) | Convex only supports "plain old JavaScript objects" (objects that do not have a custom prototype). Objects can have at most 1024 entries. Field names must be nonempty and not start with "$" or "_". | | Record | Record | {"a": "1", "b": "2"} | v.record(keys, values) | Records are objects at runtime, but can have dynamic keys. Keys must be only ASCII characters, nonempty, and not start with "$" or "\_". |
Function registration
• Use internalQuery, internalMutation, and internalAction to register internal functions. These functions are private and aren't part of an app's API. They can only be called by other Convex functions. These functions are always imported from ./_generated/server. • Use query, mutation, and action to register public functions. These functions are part of the public API and are exposed to the public Internet. Do NOT use query, mutation, or action to register sensitive internal functions that should be kept private. • You CANNOT register a function through the api or internal objects. • ALWAYS include argument and return validators for all Convex functions. This includes all of query, internalQuery, mutation, internalMutation, action, and internalAction. If a function doesn't return anything, include returns: v.null() as its output validator. • If the JavaScript implementation of a Convex function doesn't have a return value, it implicitly returns null.
Discussion
Health Signals
My Fox Den
Community Rating
Sign in to rate this booster
Works With
Any AI assistant that accepts custom rules or system prompts