
Components Guide
Structure a Convex backend into installable, reusable components instead of one monolithic convex/ folder.
Overview
Components Guide is an agent skill for the Build phase that teaches how to encapsulate Convex features as reusable backend components with clear APIs.
Install
npx skills add https://github.com/get-convex/agent-skills --skill components-guideWhat is this skill?
- Explains components as self-contained mini-backends with isolated schema, functions, and data
- Contrasts monolithic convex/ layout with encapsulated storage, billing, notifications, and domain modules
- Covers sibling components, creating your own components, and wiring via convex.config.ts
- Guidance on when components beat monolithic code for maintainability and reuse
- Official npm-installed Convex components as the quick-start path
- Example monolithic layout cites four domain files at 500–600 lines each versus slim domain files after component split
Adoption & trust: 551 installs on skills.sh; 31 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Convex backend is one tangled convex/ directory where uploads, payments, and domain logic are impossible to reuse or navigate.
Who is it for?
Indie SaaS or API products on Convex that are outgrowing single-file modules and need reusable storage or billing building blocks.
Skip if: Teams not using Convex, or greenfield apps where a single small schema file is still sufficient.
When should I use this skill?
Planning or refactoring a Convex backend into reusable feature modules.
What do I get? / Deliverables
After the skill runs, you have a component-oriented layout, wiring pattern, and criteria for what belongs in components versus domain code.
- Component directory layout
- convex.config.ts wiring plan
- Domain-vs-component boundary notes
Recommended Skills
Journey fit
How it compares
Architecture guide for Convex composition—not a generic ORM or REST API skill.
Common Questions / FAQ
Who is components-guide for?
Solo and indie builders using Convex who want maintainable, npm-style backend modules instead of monolithic function files.
When should I use components-guide?
During Build when scaffolding convex/, splitting file upload or Stripe logic, or deciding component versus monolith for a new feature.
Is components-guide safe to install?
Review the Security Audits panel on this Prism page and inspect the skill source in your repo before letting an agent change convex.config.ts or install packages.
SKILL.md
READMESKILL.md - Components Guide
# Convex Components Guide Use components to encapsulate features and build maintainable, reusable backends. ## What Are Convex Components? **Components are self-contained mini-backends** that bundle: - Their own database schema - Their own functions (queries, mutations, actions) - Their own data (isolated tables) - Clear API boundaries **Think of them as:** npm packages for your backend, or microservices without the deployment complexity. ## Why Use Components? ### Traditional Approach (Monolithic) ``` convex/ users.ts (500 lines) files.ts (600 lines - upload, storage, permissions, rate limiting) payments.ts (400 lines - Stripe, webhooks, billing) notifications.ts (300 lines) analytics.ts (200 lines) Total: One big codebase, everything mixed together ``` ### Component Approach (Encapsulated) ``` convex/ components/ storage/ (File uploads - reusable) billing/ (Payments - reusable) notifications/ (Alerts - reusable) analytics/ (Tracking - reusable) convex.config.ts (Wire components together) domain/ (Your actual business logic) users.ts (50 lines - uses components) projects.ts (75 lines - uses components) Total: Clean, focused, reusable ``` ## Quick Start ### 1. Install a Component ```bash # Official components from npm npm install @convex-dev/ratelimiter ``` ### 2. Configure in convex.config.ts ```typescript import { defineApp } from "convex/server"; import ratelimiter from "@convex-dev/ratelimiter/convex.config"; export default defineApp({ components: { ratelimiter, }, }); ``` ### 3. Use in Your Code ```typescript import { components } from "./_generated/api"; export const createPost = mutation({ handler: async (ctx, args) => { // Use the component await components.ratelimiter.check(ctx, { key: `user:${ctx.user._id}`, limit: 10, period: 60000, // 10 requests per minute }); return await ctx.db.insert("posts", args); }, }); ``` ## Sibling Components Pattern Multiple components working together at the same level: ```typescript // convex.config.ts export default defineApp({ components: { // Sibling components - each handles one concern auth: authComponent, storage: storageComponent, payments: paymentsComponent, emails: emailComponent, analytics: analyticsComponent, }, }); ``` ### Example: Complete Feature Using Siblings ```typescript // convex/subscriptions.ts import { components } from "./_generated/api"; export const subscribe = mutation({ args: { plan: v.string() }, handler: async (ctx, args) => { // 1. Verify authentication (auth component) const user = await components.auth.getCurrentUser(ctx); // 2. Create payment (payments component) const subscription = await components.payments.createSubscription(ctx, { userId: user._id, plan: args.plan, amount: getPlanAmount(args.plan), }); // 3. Track conversion (analytics component) await components.analytics.track(ctx, { event: "subscription_created", userId: user._id, plan: args.plan, }); // 4. Send confirmation (emails component) await components.emails.send(ctx, { to: user.email, template: "subscription_welcome", data: { plan: args.plan }, }); // 5. Store subscription in main app await ctx.db.insert("subscriptions", { userId: user._id, paymentId: subscription.id, plan: args.plan, status: "active", }); return subscription; }, }); ``` ## Official Components Browse [Component Directory](https://www.convex.dev/components): ### Authentication - **@convex-dev/better-auth** - Better Auth integration ### Storage - **@convex-dev/r2** - Cloudflare R2 file storage - **@convex-dev/storage** - File upload/dow