convex-helpers
SKILL.md
convex-helpers
NPM: convex-helpers | Repo: https://github.com/get-convex/convex-helpers
Installation
npm install convex-helpers
# Zod validation: npm install zod
# Hono endpoints: npm install hono
Quick Import Reference
// Core utilities
import { asyncMap, pruneNull, nullThrows, pick, omit } from "convex-helpers";
// Custom function builders
import { customQuery, customMutation, customAction, customCtx, NoOp } from "convex-helpers/server/customFunctions";
// Relationship traversal
import { getOrThrow, getAll, getAllOrThrow, getOneFrom, getOneFromOrThrow, getManyFrom, getManyVia, getManyViaOrThrow } from "convex-helpers/server/relationships";
// Row-level security
import { wrapDatabaseReader, wrapDatabaseWriter } from "convex-helpers/server/rowLevelSecurity";
// Zod validation (v4)
import { zCustomQuery, zCustomMutation, zid } from "convex-helpers/server/zod4";
// Validator utilities
import { literals, nullable, partial, deprecated, brandedString, systemFields, withSystemFields, doc, typedV, validate } from "convex-helpers/validators";
// Filter, pagination, streams
import { filter } from "convex-helpers/server/filter";
import { getPage, paginator } from "convex-helpers/server/pagination";
import { stream, mergedStream } from "convex-helpers/server/stream";
// Triggers
import { Triggers } from "convex-helpers/server/triggers";
// CRUD
import { crud } from "convex-helpers/server/crud";
// CORS & Hono
import { corsRouter } from "convex-helpers/server/cors";
import { HonoWithConvex, HttpRouterWithHono } from "convex-helpers/server/hono";
// React hooks
import { makeUseQueryWithStatus } from "convex-helpers/react";
import { ConvexQueryCacheProvider, useQuery, usePaginatedQuery } from "convex-helpers/react/cache";
import { SessionProvider, useSessionQuery, useSessionMutation } from "convex-helpers/react/sessions";
Helper Selection Guide
| Need | Helper | Reference |
|---|---|---|
| Wrap query/mutation with auth, logging, ctx extensions | customQuery / customMutation / customCtx |
custom-functions.md |
| Traverse 1:1, 1:N, M:N relationships | getOneFrom, getManyFrom, getManyVia |
relationships.md |
| Row-level access control on reads/writes | wrapDatabaseReader / wrapDatabaseWriter |
row-level-security.md |
| Zod schemas for Convex args | zCustomQuery, zid |
zod-validation.md |
Shorthand validators (literals, partial, etc.) |
literals, nullable, partial, brandedString, typedV |
validators.md |
JS/TS filter on queries (beyond .filter()) |
filter() |
filter-pagination-streams.md |
| Manual pagination / multiple paginations per query | getPage, paginator |
filter-pagination-streams.md |
| UNION/JOIN-style query composition | stream, mergedStream, flatMap |
filter-pagination-streams.md |
| React on-change triggers (computed fields, cascading deletes) | Triggers |
triggers.md |
| Auto-generate CRUD for a table | crud() |
crud-http-cors.md |
| CORS headers on HTTP actions | corsRouter |
crud-http-cors.md |
| Hono web framework for HTTP routes | HttpRouterWithHono |
crud-http-cors.md |
| Session tracking without auth | SessionProvider, useSessionQuery |
react-hooks.md |
| Richer useQuery with status/error | makeUseQueryWithStatus |
react-hooks.md |
| Query subscription caching | ConvexQueryCacheProvider |
react-hooks.md |
| Parallel async operations | asyncMap |
core-utilities.md |
Core Patterns
Authentication wrapper (most common pattern)
import { customQuery, customCtx } from "convex-helpers/server/customFunctions";
import { query } from "./_generated/server";
export const authenticatedQuery = customQuery(query, {
input: async (ctx, args) => {
const user = await getCurrentUser(ctx);
if (!user) throw new Error("Not authenticated");
return { ctx: { ...ctx, user }, args };
},
});
// Usage
export const myQuery = authenticatedQuery({
args: { id: v.id("posts") },
handler: async (ctx, { id }) => {
// ctx.user available
return ctx.db.get(id);
},
});
Relationship loading
import { asyncMap } from "convex-helpers";
import { getOneFromOrThrow, getManyFrom, getManyViaOrThrow } from "convex-helpers/server/relationships";
// Requires indexes named after the field: .index("userId", ["userId"])
const author = await getOneFromOrThrow(ctx.db, "authors", "userId", user._id);
const posts = await getManyFrom(ctx.db, "posts", "authorId", author._id);
const categories = await getManyViaOrThrow(ctx.db, "postCategories", "categoryId", "postId", post._id);
// Nested loading
const postsWithComments = await asyncMap(posts, async (post) => ({
...post,
comments: await getManyFrom(ctx.db, "comments", "postId", post._id),
}));
Validator shorthands
import { literals, nullable, partial } from "convex-helpers/validators";
// Instead of v.union(v.literal("a"), v.literal("b"))
status: literals("active", "inactive", "archived")
// Instead of v.union(v.null(), v.string())
email: nullable(v.string())
// Make all fields optional (for patches)
const patchValidator = partial({ name: v.string(), age: v.number() });
Best Practices
- Custom functions are the foundation — most helpers (RLS, sessions, triggers) build on
customQuery/customMutation. Define your builders early. - Index your database — relationship helpers, pagination, and streams all require indexes on queried fields.
- Prefer built-in when sufficient — use built-in
.filter()and.paginate()unless you need JS predicates or multiple paginations. - Security first — use
internalfunctions for CRUD, add RLS before exposing publicly, validate all inputs. - Use asyncMap for parallel fetches —
await asyncMap(ids, id => ctx.db.get(id))runs in parallel. - Limit stream reads — always set
maximumRowsReadwhen usingfilterWithto prevent scanning entire tables.
Deprecated Helpers (use components instead)
| Old helper | Replacement |
|---|---|
convex-helpers/server/retries |
@convex-dev/action-retrier |
convex-helpers/server/migrations |
@convex-dev/migrations |
convex-helpers/server/rateLimit |
@convex-dev/rate-limiter |
CLI Tools
# Generate TypeScript API spec for external repos
npx convex-helpers ts-api-spec
npx convex-helpers ts-api-spec --prod
# Generate OpenAPI spec
npx convex-helpers open-api-spec
Weekly Installs
9
Repository
imfa-solutions/skillsGitHub Stars
1
First Seen
Feb 24, 2026
Security Audits
Installed on
opencode9
antigravity9
claude-code9
github-copilot9
codex9
kimi-cli9