convex-create-component
Skill68 starsChanged 14 days agoApache-2.0View on GitHub
Create reusable Convex components with clear boundaries and a small app-facing API. - Creating a new Convex component in an existing app - Extracting reusable backend logic into a component - Building a third-party integration that should own its own tables and workflows - Packaging Convex functionality for reuse across multiple apps 1. Ask the user what they are building and what the end goal is. If the repo already makes the answer obvious, say so and confirm before proceeding.…
- Reads credentials
19 other projects use a version of this, 11 of them edited.
Adopted by
Steady: 0 new projects took it in the last 4 weeks, none the 4 weeks before.thin data
Most recently taken up by
- convex/agent-skillsword for word, first seen Oct 17, 2026
- get-convex/workflowedited, first seen Oct 9, 2026
- moltbot/molthubword for word, first seen Oct 8, 2026
- get-convex/convex-helpersedited, first seen Oct 8, 2026
- clawdbot/clawdhubword for word, first seen Oct 8, 2026
- pingdotgg/lawnword for word, first seen Oct 8, 2026
Used with
Projects with it also use convex-migration-helper, convex-performance-audit and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
vantageos-agencySkillconvex-migration-helper
Plans and executes safe Convex schema and data migrations using the widen-migrate-narrow workflow and the @convex-dev/migrations component. Use this skill when a deployment fails schema validation, existing documents need backfilling, fields need adding or removing or changing type, tables need splitting or merging, or a zero-downtime migration strategy is needed. Also use when the user mentions breaking schema changes, multi-deploy rollouts, or data transformations on existing Convex tables.
Also in 16 projects that use this
vantageos-agencySkillconvex-performance-audit
Audits and optimizes Convex application performance across hot-path reads, write contention, subscription cost, and function limits. Use this skill when a Convex feature is slow or expensive, npx convex insights shows high bytes or documents read, OCC conflict errors or mutation retries appear, subscriptions or UI updates are costly, functions hit execution or transaction limits, or the user mentions performance, latency, read amplification, or invalidation problems in a Convex app.
Also in 16 projects that use this
FabienGreardSkillconvex-acquire-domain
Find and buy a domain for the current Convex app through Convex, then bind it (labs; spend action).
Also in 4 projects that use this
FabienGreardSkillconvex-check-updates
Check the current app's pinned Convex components against recommended versions and upgrade them behind a build gate.
Also in 4 projects that use this
openclawSkillclawhub-ban-appeals
Review ClawHub account-ban appeals, distinguish bans from moderation holds or blocked releases, and prepare an evidence-backed moderation decision. Route validated scanner inaccuracies to clawhub-clawscan.
Also in 3 projects that use this
openclawSkillclawhub-clawscan
Investigate ClawScan health alerts, diagnose scanner or ClawHub integration failures, prepare operational repairs, and route validated verdict inaccuracies upstream. Account ban appeals use clawhub-ban-appeals.
Also in 3 projects that use this
- +1 more from vantageos-agency
- +5 more from openclaw
Other versions19 projects use a version of this.
Word for word · 8
- openclaw/clawhub★ 9.6k100% same
- clawdbot/clawdhub★ 9.5k100% same
- moltbot/molthub★ 9.5k100% same
- pingdotgg/lawn★ 690100% same
- convex/agent-skills★ 68100% same
- FabienGreard/TouchGrassBar★ 5100% same
- fiinytid/nexusai.gg★ 2100% same
- getsentry/friday★ 0100% same
Edited · 11
- raroque/boop-agent★ 1.3k98% same
- waynesutton/markdown-site★ 62898% same
- get-convex/convex-helpers★ 49694% same
- get-convex/workflow★ 8694% same
- sholajegede/mastra-vs-langchain★ 1798% same
- vantageos-agency/vantage-peers★ 494% same
- Decentralized-Rights-Protocol/Dr-Blockchain★ 294% same
- ReScienceLab/TrySkills★ 294% same
- yisiliu/agent-town★ 198% same
- elpiarthera/vantage-starter★ 094% same
1 more not listed
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository33 other files it gives its agents.
- AGENTS.mdAGENTS.md
- convex-addSkill
- convex-advisorSkill
- convex-agentSkill
- convex-authSkill
- convex-authzSkill
- convex-backupSkill
- convex-billingSkill
- convex-costSkill
- convex-cronsSkill
- convex-deploy-guardSkill
- convex-designSkill
- convex-docsSkill
- convex-domainsSkill
- convex-envSkill
- convex-expertSkill
- convex-explain-appSkill
- convex-improve-convex-pluginSkill
- convex-insightsSkill
- convex-launch-readinessSkill
- convex-migrate-rehearseSkill
- convex-migrateSkill
- convex-monitorSkill
- convex-optimizeSkill
- convex-quickstartSkill
- convex-reviewerSkill
- convex-seedSkill
- convex-self-healSkill
- convex-sentinelSkill
- convexSkill
- convex-suggestSkill
- convex-testSkill
- convex-verifySkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
19 rules. 5 are common, 3 are distinctive, and 11 are very specific to this project.
5
Common
Most of the 11 edited versions we read keep these.
3
Distinctive
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Common: line 11
Create reusable Convex components with clear boundaries and a small app-facing API.
- Distinctive: line 31
Ask the user what they are building and what the end goal is.
- Very specific: line 43
Create the component structure with convex.config.ts, schema.ts, and function files.
- Very specific: line 49
Call the component from the app through components.<name> using ctx.runQuery, ctx.runMutation, or ctx.runAction.
- Distinctive: line 51
If React clients, HTTP callers, or public APIs need access, create wrapper functions in the app instead of exposing component functions …
- Very specific: line 53
Run npx convex dev and fix codegen, type, or boundary issues before finishing.
- Common: line 58
Ask the user, then pick one path:
- Common: line 67
Read exactly one reference file before proceeding.
- Very specific: line 73
Put it under convex/components/<componentName>/
- Very specific: line 194
Keep authentication in the app, because ctx.auth is not available inside components.
- Very specific: line 196
Keep environment access in the app, because component functions cannot read process.env.
- Very specific: line 200
Do not use v.id("parentTable") for app-owned tables inside component args or schema, because the component has no access to the app's table …
- Very specific: line 202
Import query, mutation, and action from the component's own ./_generated/server, not the app's generated files.
- Distinctive: line 204
Do not expose component functions directly to clients.
- Very specific: line 207
If the component defines HTTP handlers, mount the routes in the app's convex/http.ts, because components cannot register their own HTTP …
- Very specific: line 209
If the component needs pagination, use paginator from convex-helpers instead of built-in .paginate(), because .paginate() does not work …
- Very specific: line 214
Add args and returns validators to all public component functions, because the component boundary requires explicit type contracts.
- Common: line 299
If validation blocks on Convex login or deployment setup, stop and ask the user for that exact step instead of guessing.
- Common: line 304
Read exactly one of these after the user confirms the goal:
“Common” is measured: kept by at least 6 in 10 of the 11 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Convex Create Component
Create reusable Convex components with clear boundaries and a small app-facing API.
When to Use
- Creating a new Convex component in an existing app
- Extracting reusable backend logic into a component
- Building a third-party integration that should own its own tables and workflows
- Packaging Convex functionality for reuse across multiple apps
When Not to Use
- One-off business logic that belongs in the main app
- Thin utilities that do not need Convex tables or functions
- App-level orchestration that should stay in
convex/ - Cases where a normal TypeScript library is enough
Workflow
- Ask the user what they are building and what the end goal is. If the repo already makes the answer obvious, say so and confirm before proceeding.
- Choose the shape using the decision tree below and read the matching reference file.
- Decide whether a component is justified. Prefer normal app code or a regular library if the feature does not need isolated tables, backend functions, or reusable persistent state.
- Make a short plan for:
- what tables the component owns
- what public functions it exposes
- what data must be passed in from the app (auth, env vars, parent IDs)
- what stays in the app as wrappers or HTTP mounts
- Create the component structure with
convex.config.ts,schema.ts, and function files. - Implement functions using the component's own
./_generated/serverimports, not the app's generated files. - Wire the component into the app with
app.use(...). If the app does not already haveconvex/convex.config.ts, create it. - Call the component from the app through
components.<name>usingctx.runQuery,ctx.runMutation, orctx.runAction. - If React clients, HTTP callers, or public APIs need access, create wrapper functions in the app instead of exposing component functions directly.
- Run
npx convex devand fix codegen, type, or boundary issues before finishing.
Choose the Shape
Ask the user, then pick one path:
| Goal | Shape | Reference |
| Component for this app only | Local | references/local-components.md |
| Publish or share across apps | Packaged | references/packaged-components.md |
| User explicitly needs local + shared library code | Hybrid | references/hybrid-components.md |
| Not sure | Default to local | references/local-components.md |
Read exactly one reference file before proceeding.
Default Approach
Unless the user explicitly wants an npm package, default to a local component:
- Put it under
convex/components/<componentName>/ - Define it with
defineComponent(...)in its ownconvex.config.ts - Install it from the app's
convex/convex.config.tswithapp.use(...) - Let
npx convex devgenerate the component's own_generated/files
Component Skeleton
A minimal local component with a table and two functions, plus the app wiring.
// convex/components/notifications/convex.config.ts
import { defineComponent } from "convex/server";
export default defineComponent("notifications");// convex/components/notifications/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";
export default defineSchema({
notifications: defineTable({
userId: v.string(),
message: v.string(),
read: v.boolean(),
}).index("by_user_read", ["userId", "read"]),
});// convex/components/notifications/lib.ts
import { v } from "convex/values";
import { mutation, query } from "./_generated/server.js";
export const send = mutation({
args: { userId: v.string(), message: v.string() },
returns: v.id("notifications"),
handler: async (ctx, args) => {
return await ctx.db.insert("notifications", {
userId: args.userId,
message: args.message,
read: false,
});
},
});
export const listUnread = query({
args: { userId: v.string() },
returns: v.array(
v.object({
_id: v.id("notifications"),
_creationTime: v.number(),
userId: v.string(),
message: v.string(),
read: v.boolean(),
}),
),
handler: async (ctx, args) => {
return await ctx.db
.query("notifications")
.withIndex("by_user_read", (q) =>
q.eq("userId", args.userId).eq("read", false),
)
.collect();
},
});// convex/convex.config.ts
import { defineApp } from "convex/server";
import notifications from "./components/notifications/convex.config.js";
const app = defineApp();
app.use(notifications);
export default app;// convex/notifications.ts (app-side wrapper)
import { v } from "convex/values";
import { mutation, query } from "./_generated/server";
import { components } from "./_generated/api";
import { getAuthUserId } from "@convex-dev/auth/server";
export const sendNotification = mutation({
args: { message: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");
await ctx.runMutation(components.notifications.lib.send, {
userId,
message: args.message,
});
return null;
},
});
export const myUnread = query({
args: {},
handler: async (ctx) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");
return await ctx.runQuery(components.notifications.lib.listUnread, {
userId,
});
},
});Note the reference path shape: a function in
convex/components/notifications/lib.ts is called as
components.notifications.lib.send from the app.
Critical Rules
- Keep authentication in the app, because
ctx.authis not available inside components. - Keep environment access in the app, because component functions cannot read
process.env. - Pass parent app IDs across the boundary as strings, because
Idtypes become plain strings in the app-facingComponentApi. - Do not use
v.id("parentTable")for app-owned tables inside component args or schema, because the component has no access to the app's table namespace. - Import
query,mutation, andactionfrom the component's own./_generated/server, not the app's generated files. - Do not expose component functions directly to clients. Create app wrappers when client access is needed, because components are internal and need auth/env wiring the app provides.
- If the component defines HTTP handlers, mount the routes in the app's
convex/http.ts, because components cannot register their own HTTP routes. - If the component needs pagination, use
paginatorfromconvex-helpersinstead of built-in.paginate(), because.paginate()does not work across the component boundary. - Define indexes for queried fields instead of using Convex
.filter()after a database query. - Add
argsandreturnsvalidators to all public component functions, because the component boundary requires explicit type contracts.
Patterns
Authentication and environment access
// Bad: component code cannot rely on app auth or env
const identity = await ctx.auth.getUserIdentity();
const apiKey = process.env.OPENAI_API_KEY;// Good: the app resolves auth and env, then passes explicit values
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");
await ctx.runAction(components.translator.translate, {
userId,
apiKey: process.env.OPENAI_API_KEY,
text: args.text,
});Client-facing API
// Bad: assuming a component function is directly callable by clients
export const send = components.notifications.send;// Good: re-export through an app mutation or query
export const sendNotification = mutation({
args: { message: v.string() },
returns: v.null(),
handler: async (ctx, args) => {
const userId = await getAuthUserId(ctx);
if (!userId) throw new Error("Not authenticated");
await ctx.runMutation(components.notifications.lib.send, {
userId,
message: args.message,
});
return null;
},
});IDs across the boundary
// Bad: parent app table IDs are not valid component validators
args: {
userId: v.id("users"),
}// Good: treat parent-owned IDs as strings at the boundary
args: {
userId: v.string(),
}Advanced Patterns
For additional patterns including function handles for callbacks, deriving
validators from schema, static configuration with a globals table, and
class-based client wrappers, see references/advanced-patterns.md.
Validation
Try validation in this order:
npx convex codegen --component-dir convex/components/<name>npx convex codegennpx convex dev
Important:
- Fresh repos may fail these commands until
CONVEX_DEPLOYMENTis configured. - Until codegen runs, component-local
./_generated/*imports and app-sidecomponents.<name>...references will not typecheck. - If validation blocks on Convex login or deployment setup, stop and ask the user for that exact step instead of guessing.
Reference Files
Read exactly one of these after the user confirms the goal:
references/local-components.mdreferences/packaged-components.mdreferences/hybrid-components.md
Official docs: Authoring Components
Checklist
- Asked the user what they want to build and confirmed the shape
- Read the matching reference file
- Confirmed a component is the right abstraction
- Planned tables, public API, boundaries, and app wrappers
- Component lives under
convex/components/<name>/(or package layout if publishing) - Component imports from its own
./_generated/server - Auth, env access, and HTTP routes stay in the app
- Parent app IDs cross the boundary as
v.string() - Public functions have
argsandreturnsvalidators - Ran
npx convex devand fixed codegen or type issues
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

