.fyi
SkillsMCPPluginsSubagents

Browse by category

DevOps & CI/CD SkillsProductivity & Workflow SkillsOther SkillsProduct & Project Management SkillsDocumentation & Knowledge SkillsCode Review & Refactor SkillsBackend & APIs SkillsAgent Meta & Communication SkillsResearch SkillsSecurity SkillsUX UI & Design SkillsTesting & QA SkillsSee all →

Every Claude Code skill, MCP server, plugin and subagent in one directory. Searchable, comparable, and one command from installed. Live stats from GitHub, npm and PyPI.

We're on Product HuntYour agent's app storeCheck it out →
Agent SkillsMCP ServersPluginsSubagentsCoding Agents
CollectionsOfficial publishersGlossaryFAQBlogSearchSavedFeedback
PrivacyTermsllms.txtSitemap

made with ♥ · © 2026 aaaa.fyi

Independent project · real data from public registries

…/agent-skills/convex-create-component
home/skills/get-convex/agent-skills/convex-create-component
get-convex avatar

convex-create-component

byget-convex· 29 skills

Installs

92k

Stars

40

Forks

8

Category

Backend & APIs

View on GitHub

TL;DR

Builds reusable Convex components with isolated tables and app-facing APIs. Use for new components, reusable backend modules, integrations, or component boundary work.

How to install convex-create-component?

get-convex/agent-skills/convex-create-component
$npx -y skills add get-convex/agent-skills --skill convex-create-component

Installs into the current project.

›Prefer a prompt? Paste this to your agent

Use this skill

Run `npx skills use "https://github.com/get-convex/agent-skills" --skill "get-convex/agent-skills/convex-create-component"` and follow the generated skill instructions now. Read its complete output, redirecting it to a temporary file first if necessary. Resolve relative paths from the supporting-files directory it provides.

Use the whole pack

Use the skills in "https://github.com/get-convex/agent-skills" that are relevant to the current task. Run `npx skills add "https://github.com/get-convex/agent-skills"` and select the relevant skills, then follow their instructions.

Files · 1

View on GitHub
SKILL.md
1# Convex Create Component
2 
3Create reusable Convex components with clear boundaries and a small app-facing
4API.
5 
6## When to Use
7 
8- Creating a new Convex component in an existing app
9- Extracting reusable backend logic into a component
10- Building a third-party integration that should own its own tables and
11 workflows
12- Packaging Convex functionality for reuse across multiple apps
13 
14## When Not to Use
15 
16- One-off business logic that belongs in the main app
17- Thin utilities that do not need Convex tables or functions
18- App-level orchestration that should stay in `convex/`
19- Cases where a normal TypeScript library is enough
20 
21## Workflow
22 
231. Ask the user what they are building and what the end goal is. If the repo
24 already makes the answer obvious, say so and confirm before proceeding.
252. Choose the shape using the decision tree below and read the matching
26 reference file.
273. Decide whether a component is justified. Prefer normal app code or a regular
28 library if the feature does not need isolated tables, backend functions, or
29 reusable persistent state.
304. Make a short plan for:
31 - what tables the component owns
32 - what public functions it exposes
33 - what data must be passed in from the app (auth, env vars, parent IDs)
34 - what stays in the app as wrappers or HTTP mounts
355. Create the component structure with `convex.config.ts`, `schema.ts`, and
36 function files.
376. Implement functions using the component's own `./_generated/server` imports,
38 not the app's generated files.
397. Wire the component into the app with `app.use(...)`. If the app does not
40 already have `convex/convex.config.ts`, create it.
418. Call the component from the app through `components.<name>` using
42 `ctx.runQuery`, `ctx.runMutation`, or `ctx.runAction`.
439. If React clients, HTTP callers, or public APIs need access, create wrapper
44 functions in the app instead of exposing component functions directly.
4510. Run `npx convex dev` and fix codegen, type, or boundary issues before
46 finishing.
47 
48## Choose the Shape
49 
50Ask the user, then pick one path:
51 
52| Goal | Shape | Reference |
53| ------------------------------------------------- | ---------------- | ----------------------------------- |
54| Component for this app only | Local | `references/local-components.md` |
55| Publish or share across apps | Packaged | `references/packaged-components.md` |
56| User explicitly needs local + shared library code | Hybrid | `references/hybrid-components.md` |
57| Not sure | Default to local | `references/local-components.md` |
58 
59Read exactly one reference file before proceeding.
60 
61## Default Approach
62 
63Unless the user explicitly wants an npm package, default to a local component:
64 
65- Put it under `convex/components/<componentName>/`
66- Define it with `defineComponent(...)` in its own `convex.config.ts`
67- Install it from the app's `convex/convex.config.ts` with `app.use(...)`
68- Let `npx convex dev` generate the component's own `_generated/` files
69 
70## Component Skeleton
71 
72A minimal local component with a table and two functions, plus the app wiring.
73 
74```ts
75// convex/components/notifications/convex.config.ts
76import { defineComponent } from "convex/server";
77 
78export default defineComponent("notifications");
79```
80 
81```ts
82// convex/components/notifications/schema.ts
83import { defineSchema, defineTable } from "convex/server";
84import { v } from "convex/values";
85 
86export default defineSchema({
87 notifications: defineTable({
88 userId: v.string(),
89 message: v.string(),
90 read: v.boolean(),
91 }).index("by_user_read", ["userId", "read"]),
92});
93```
94 
95```ts
96// convex/components/notifications/lib.ts
97import { v } from "convex/values";
98import { mutation, query } from "./_generated/server.js";
99 
100export const send = mutation({
101 args: { userId: v.string(), message: v.string() },
102 returns: v.id("notifications"),
103 handler: async (ctx, args) => {
104 return await ctx.db.insert("notifications", {
105 userId: args.userId,
106 message: args.message,
107 read: false,
108 });
109 },
110});
111 
112export const listUnread = query({
113 args: { userId: v.string() },
114 returns: v.array(
115 v.object({
116 _id: v.id("notifications"),
117 _creationTime: v.number(),
118 userId: v.string(),
119 message: v.string(),
120 read: v.boolean(),
121 }),
122 ),
123 handler: async (ctx, args) => {
124 return await ctx.db
125 .query("notifications")
126 .withIndex("by_user_read", (q) =>
127 q.eq("userId", args.userId).eq("read", false),
128 )
129 .collect();
130 },
131});
132```
133 
134```ts
135// convex/convex.config.ts
136import { defineApp } from "convex/server";
137import notifications from "./components/notifications/convex.config.js";
138 
139const app = defineApp();
140app.use(notifications);
141 
142export default app;
143```
144 
145```ts
146// convex/notifications.ts (app-side wrapper)
147import { v } from "convex/values";
148import { mutation, query } from "./_generated/server";
149import { components } from "./_generated/api";
150import { getAuthUserId } from "@convex-dev/auth/server";
151 
152export const sendNotification = mutation({
153 args: { message: v.string() },
154 returns: v.null(),
155 handler: async (ctx, args) => {
156 const userId = await getAuthUserId(ctx);
157 if (!userId) throw new Error("Not authenticated");
158 
159 await ctx.runMutation(components.notifications.lib.send, {
160 userId,
161 message: args.message,
162 });
163 return null;
164 },
165});
166 
167export const myUnread = query({
168 args: {},
169 handler: async (ctx) => {
170 const userId = await getAuthUserId(ctx);
171 if (!userId) throw new Error("Not authenticated");
172 
173 return await ctx.runQuery(components.notifications.lib.listUnread, {
174 userId,
175 });
176 },
177});
178```
179 
180Note the reference path shape: a function in
181`convex/components/notifications/lib.ts` is called as
182`components.notifications.lib.send` from the app.
183 
184## Critical Rules
185 
186- Keep authentication in the app, because `ctx.auth` is not available inside
187 components.
188- Keep environment access in the app, because component functions cannot read
189 `process.env`.
190- Pass parent app IDs across the boundary as strings, because `Id` types become
191 plain strings in the app-facing `ComponentApi`.
192- Do not use `v.id("parentTable")` for app-owned tables inside component args or
193 schema, because the component has no access to the app's table namespace.
194- Import `query`, `mutation`, and `action` from the component's own
195 `./_generated/server`, not the app's generated files.
196- Do not expose component functions directly to clients. Create app wrappers
197 when client access is needed, because components are internal and need
198 auth/env wiring the app provides.
199- If the component defines HTTP handlers, mount the routes in the app's
200 `convex/http.ts`, because components cannot register their own HTTP routes.
201- If the component needs pagination, use `paginator` from `convex-helpers`
202 instead of built-in `.paginate()`, because `.paginate()` does not work across
203 the component boundary.
204- Define indexes for queried fields instead of using Convex `.filter()` after a
205 database query.
206- Add `args` and `returns` validators to all public component functions, because
207 the component boundary requires explicit type contracts.
208 
209## Patterns
210 
211### Authentication and environment access
212 
213```ts
214// Bad: component code cannot rely on app auth or env
215const identity = await ctx.auth.getUserIdentity();
216const apiKey = process.env.OPENAI_API_KEY;
217```
218 
219```ts
220// Good: the app resolves auth and env, then passes explicit values
221const userId = await getAuthUserId(ctx);
222if (!userId) throw new Error("Not authenticated");
223 
224await ctx.runAction(components.translator.translate, {
225 userId,
226 apiKey: process.env.OPENAI_API_KEY,
227 text: args.text,
228});
229```
230 
231### Client-facing API
232 
233```ts
234// Bad: assuming a component function is directly callable by clients
235export const send = components.notifications.send;
236```
237 
238```ts
239// Good: re-export through an app mutation or query
240export const sendNotification = mutation({
241 args: { message: v.string() },
242 returns: v.null(),
243 handler: async (ctx, args) => {
244 const userId = await getAuthUserId(ctx);
245 if (!userId) throw new Error("Not authenticated");
246 
247 await ctx.runMutation(components.notifications.lib.send, {
248 userId,
249 message: args.message,
250 });
251 return null;
252 },
253});
254```
255 
256### IDs across the boundary
257 
258```ts
259// Bad: parent app table IDs are not valid component validators
260args: {
261 userId: v.id("users"),
262}
263```
264 
265```ts
266// Good: treat parent-owned IDs as strings at the boundary
267args: {
268 userId: v.string(),
269}
270```
271 
272### Advanced Patterns
273 
274For additional patterns including function handles for callbacks, deriving
275validators from schema, static configuration with a globals table, and
276class-based client wrappers, see `references/advanced-patterns.md`.
277 
278## Validation
279 
280Try validation in this order:
281 
2821. `npx convex codegen --component-dir convex/components/<name>`
2832. `npx convex codegen`
2843. `npx convex dev`
285 
286Important:
287 
288- Fresh repos may fail these commands until `CONVEX_DEPLOYMENT` is configured.
289- Until codegen runs, component-local `./_generated/*` imports and app-side
290 `components.<name>...` references will not typecheck.
291- If validation blocks on Convex login or deployment setup, stop and ask the
292 user for that exact step instead of guessing.
293 
294## Reference Files
295 
296Read exactly one of these after the user confirms the goal:
297 
298- `references/local-components.md`
299- `references/packaged-components.md`
300- `references/hybrid-components.md`
301 
302Official docs:
303[Authoring Components](https://docs.convex.dev/components/authoring)
304 
305## Checklist
306 
307- [ ] Asked the user what they want to build and confirmed the shape
308- [ ] Read the matching reference file
309- [ ] Confirmed a component is the right abstraction
310- [ ] Planned tables, public API, boundaries, and app wrappers
311- [ ] Component lives under `convex/components/<name>/` (or package layout if
312 publishing)
313- [ ] Component imports from its own `./_generated/server`
314- [ ] Auth, env access, and HTTP routes stay in the app
315- [ ] Parent app IDs cross the boundary as `v.string()`
316- [ ] Public functions have `args` and `returns` validators
317- [ ] Ran `npx convex dev` and fixed codegen or type issues

Security

Passed

  • Gen Agent Trust Hubpass
  • Socketpass
  • Snykpass
  • ZeroLeakspass

Preview

get-convex/agent-skillsget-convex/agent-skills

$ npx -y skills add get-convex/agent-skills --skill convex-create-component

▸ installing to .claude/skills…

✓ convex-create-component ready

Repoget-convex/agent-skills
TypeSkills
CategoryBackend & APIs
ForDeveloperArchitect
UpdatedJul 2026
License—
First seenJul 26, 2026

Tags

Skill

Related

6 picks
Type
  1. microsoft avatarazure-messagingTroubleshoot and resolve issues with Azure Messaging SDKs for Event Hubs and Service Bus.SkillsJul 2026473k1.3k
  2. larksuite avatarlark-openapi-explorer飞书/Lark 原生 OpenAPI 探索:从官方文档库中挖掘未经 CLI 封装的原生 OpenAPI 接口。当用户的需求无法被现有 lark-* skill 或 lark-cli 已注册命令满足,需要查找并调用原生飞书 OpenAPI 时使用。SkillsJul 2026386k16k
  3. larksuite avatarlark-skill-maker创建 lark-cli 的自定义 Skill。当用户需要把飞书 API 操作封装成可复用的 Skill(包装原子 API 或编排多步流程)时使用。SkillsJul 2026385k16k
  4. mattpocock avatarimplementImplement a piece of work based on a spec or set of tickets.SkillsJul 2026237k189k
  5. supabase avatarsupabaseUse when doing ANY task involving Supabase. Triggers: Supabase products (Database, Auth, Edge Functions, Realtime, Storage, Vectors, Cron, Queues); client…SkillsJul 2026188k2.4k
  6. firebase avatarfirebase-basicsProvides foundational setup, authentication, and project management workflows for Firebase using the Firebase CLI.SkillsJul 2026117k389