Agent skill

Convex Create Component

by vvedantb in vvedantb/eva

Design and build Convex components with clear boundaries, isolated state, and app-facing wrappers.

MITAuto-check passed

Install Convex Create Component

skills CLI
$ npx skills add vvedantb/eva --skill convex-create-component -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install vvedantb/eva convex-create-component --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/vvedantb/eva.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/convex-create-component .claude/skills/convex-create-component && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
convex-create-component
GitHub stars
101
Token cost
~3.3k tokens
SKILL.md length
815 words
Files
6 (incl. references, assets)
Skills in repo
23
Repo updated
First seen
Licence
MIT

At a glance

Design and build Convex components with clear boundaries, isolated state, and app-facing wrappers.

  • Works in 10 steps: Ask the user what they are building and… → Choose the shape using the decision tree… → Decide whether a component is justified.… → …
  • Creating a new Convex component
  • SKILL.md covers When to Use, When Not to Use, Workflow and Choose the Shape, plus 7 more sections
  • Calls npx; needs OPENAI_API_KEY

What it does

Convex Create Component is an agent skill from vvedantb/eva. Design and build Convex components with clear boundaries, isolated state, and app-facing wrappers. Use when creating a new Convex component, extracting reusable backend logic into one, or packaging Convex functionality for reuse across apps.

Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including reference files and assets (for example `agents/openai.yaml`, `references/hybrid-components.md` and `references/local-components.md`).

The repository describes itself as: Orchestrate sandboxed agents that run in the cloud while you work. The licence is MIT.

When your agent uses it

  • Creating a new Convex component
  • Extracting reusable backend logic into one
  • Packaging Convex functionality for reuse across apps

Example prompts

  • “/convex-create-component”

Requirements

  • Node.js
  • A credential in OPENAI_API_KEY

Workflow steps

10 steps, taken from the first numbered list in SKILL.md.

  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…
  2. Choose the shape using the decision tree below and read the matching reference file.
  3. Decide whether a component is justified. Prefer normal app code or a regular library if the feature does not need isolated tables, backend…
  4. Make a short plan for
  5. Create the component structure with convex.config.ts, schema.ts, and function files.
  6. Implement functions using the component's own ./_generated/server imports, not the app's generated files.
  7. Wire the component into the app with app.use(...). If the app does not already have convex/convex.config.ts, create it.
  8. Call the component from the app through components. using ctx.runQuery, ctx.runMutation, or ctx.runAction.
  9. If React clients, HTTP callers, or public APIs need access, create wrapper functions in the app instead of exposing component functions…
  10. Run npx convex dev and fix codegen, type, or boundary issues before finishing.

What it can do on your machine

Read from SKILL.md and the folder at commit 166d464. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Links to these hosts (documentation or services it may open):

    • docs.convex.dev

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • OPENAI_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Convex Create Component loads about 3.3k tokens when it runs, and up to ~4.3k if it reads all its reference files. Until then it costs about 66 tokens; SKILL.md has 815 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~66
When it runs · the whole SKILL.md, loaded when a task matches
~3.3k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from vvedantb/eva at commit 166d464, republished under its MIT licence (© vvedantb). 815 words, ~3,334 tokens.

Download SKILL.mdSave it as .claude/skills/convex-create-component/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
convex-create-component
description
Design and build Convex components with clear boundaries, isolated state, and app-facing wrappers. Use when creating a new Convex component, extracting reusable backend logic into one, or packaging Convex functionality for reuse across apps.

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

  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.
  2. Choose the shape using the decision tree below and read the matching reference file.
  3. 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.
  4. 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
  5. Create the component structure with convex.config.ts, schema.ts, and function files.
  6. Implement functions using the component's own ./_generated/server imports, not the app's generated files.
  7. Wire the component into the app with app.use(...). If the app does not already have convex/convex.config.ts, create it.
  8. Call the component from the app through components.<name> using ctx.runQuery, ctx.runMutation, or ctx.runAction.
  9. If React clients, HTTP callers, or public APIs need access, create wrapper functions in the app instead of exposing component functions directly.
  10. Run npx convex dev and fix codegen, type, or boundary issues before finishing.

Choose the Shape

Ask the user, then pick one path:

GoalShapeReference
Component for this app onlyLocalreferences/local-components.md
Publish or share across appsPackagedreferences/packaged-components.md
User explicitly needs local + shared library codeHybridreferences/hybrid-components.md
Not sureDefault to localreferences/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 own convex.config.ts
  • Install it from the app's convex/convex.config.ts with app.use(...)
  • Let npx convex dev generate the component's own _generated/ files

Component Skeleton

A minimal local component with a table and two functions, plus the app wiring.

ts
// convex/components/notifications/convex.config.ts
import { defineComponent } from "convex/server";

export default defineComponent("notifications");
ts
// 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", ["userId"]),
});
ts
// 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", (q) => q.eq("userId", args.userId))
      .filter((q) => q.eq(q.field("read"), false))
      .collect();
  },
});
ts
// 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;
ts
// 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. ctx.auth is not available inside components.
  • Keep environment access in the app. Component functions cannot read process.env.
  • Pass parent app IDs across the boundary as strings. Id types become plain strings in the app-facing ComponentApi.
  • Do not use v.id("parentTable") for app-owned tables inside component args or schema.
  • Import query, mutation, and action from the component's own ./_generated/server.
  • Do not expose component functions directly to clients. Create app wrappers when client access is needed.
  • If the component defines HTTP handlers, mount the routes in the app's convex/http.ts.
  • If the component needs pagination, use paginator from convex-helpers instead of built-in .paginate().
  • Add args and returns validators to all public component functions.
Show full SKILL.md (273 more words)Show less

Patterns

Authentication and environment access
ts
// Bad: component code cannot rely on app auth or env
const identity = await ctx.auth.getUserIdentity();
const apiKey = process.env.OPENAI_API_KEY;
ts
// 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
ts
// Bad: assuming a component function is directly callable by clients
export const send = components.notifications.send;
ts
// 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
ts
// Bad: parent app table IDs are not valid component validators
args: {
  userId: v.id("users");
}
ts
// Good: treat parent-owned IDs as strings at the boundary
args: {
  userId: v.string();
}
Function Handles for callbacks

When the app needs to pass a callback function to the component, use function handles. This is common for components that run app-defined logic on a schedule or in a workflow.

ts
// App side: create a handle and pass it to the component
import { createFunctionHandle } from "convex/server";

export const startJob = mutation({
  handler: async (ctx) => {
    const handle = await createFunctionHandle(internal.myModule.processItem);
    await ctx.runMutation(components.workpool.enqueue, {
      callback: handle,
    });
  },
});
ts
// Component side: accept and invoke the handle
import { v } from "convex/values";
import type { FunctionHandle } from "convex/server";
import { mutation } from "./_generated/server.js";

export const enqueue = mutation({
  args: { callback: v.string() },
  handler: async (ctx, args) => {
    const handle = args.callback as FunctionHandle<"mutation">;
    await ctx.scheduler.runAfter(0, handle, {});
  },
});
Deriving validators from schema

Instead of manually repeating field types in return validators, extend the schema validator:

ts
import { v } from "convex/values";
import schema from "./schema.js";

const notificationDoc = schema.tables.notifications.validator.extend({
  _id: v.id("notifications"),
  _creationTime: v.number(),
});

export const getLatest = query({
  args: {},
  returns: v.nullable(notificationDoc),
  handler: async (ctx) => {
    return await ctx.db.query("notifications").order("desc").first();
  },
});
Static configuration with a globals table

A common pattern for component configuration is a single-document "globals" table:

ts
// schema.ts
export default defineSchema({
  globals: defineTable({
    maxRetries: v.number(),
    webhookUrl: v.optional(v.string()),
  }),
  // ... other tables
});
ts
// lib.ts
export const configure = mutation({
  args: { maxRetries: v.number(), webhookUrl: v.optional(v.string()) },
  returns: v.null(),
  handler: async (ctx, args) => {
    const existing = await ctx.db.query("globals").first();
    if (existing) {
      await ctx.db.patch(existing._id, args);
    } else {
      await ctx.db.insert("globals", args);
    }
    return null;
  },
});
Class-based client wrappers

For components with many functions or configuration options, a class-based client provides a cleaner API. This pattern is common in published components.

ts
// src/client/index.ts
import type { GenericMutationCtx, GenericDataModel } from "convex/server";
import type { ComponentApi } from "../component/_generated/component.js";

type MutationCtx = Pick<GenericMutationCtx<GenericDataModel>, "runMutation">;

export class Notifications {
  constructor(
    private component: ComponentApi,
    private options?: { defaultChannel?: string },
  ) {}

  async send(ctx: MutationCtx, args: { userId: string; message: string }) {
    return await ctx.runMutation(this.component.lib.send, {
      ...args,
      channel: this.options?.defaultChannel ?? "default",
    });
  }
}
ts
// App usage
import { Notifications } from "@convex-dev/notifications";
import { components } from "./_generated/api";

const notifications = new Notifications(components.notifications, {
  defaultChannel: "alerts",
});

export const send = mutation({
  args: { message: v.string() },
  handler: async (ctx, args) => {
    const userId = await getAuthUserId(ctx);
    await notifications.send(ctx, { userId, message: args.message });
  },
});

Validation

Try validation in this order:

  1. npx convex codegen --component-dir convex/components/<name>
  2. npx convex codegen
  3. npx convex dev

Important:

  • Fresh repos may fail these commands until CONVEX_DEPLOYMENT is configured.
  • Until codegen runs, component-local ./_generated/* imports and app-side components.<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.md
  • references/packaged-components.md
  • references/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 args and returns validators
  • Ran npx convex dev and fixed codegen or type issues

© vvedantb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (references, assets) in .claude/skills/convex-create-component of vvedantb/eva.

  • SKILL.md
  • agents/openai.yaml
  • assets/icon.svg
  • references/hybrid-components.md
  • references/local-components.md
  • references/packaged-components.md

Open the folder on GitHubat commit 166d464

Compare with similar skills

Convex Create Component next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Convex Create Component compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Convex Create Component this skillvvedantb/eva101—~3.3kAutomated safety check: PassMIT
Isolated Space Boundaryopenchamber/openchamber11k—~2kAutomated safety check: PassMIT
Convexdavila7/claude-code-templates32k3 repos~6.4kAutomated safety check: NotesMIT
Convexopenclaw/clawhub9.5k—~2.4kAutomated safety check: PassMIT
Convex Backendsickn33/agentic-awesome-skills47k2 repos~2.2kAutomated safety check: NotesMIT
Cross Origin Isolationthedaviddias/Front-End-Checklist74k—~565Automated safety check: PassMIT

Similar skills

  • Isolated Space Boundary

    openchamber/openchamber

    A skill your agent uses when changing isolated-space trust boundaries: container hardening, networks and gatekeeper policy, exec and lifecycle, grants and credentials, code transfer and apply…

    11k GitHub stars~2k tokensUpdated today
    Auto-check passed
  • Convex

    davila7/claude-code-templates

    Convex reactive backend expert: schema design, TypeScript functions, real-time subscriptions, auth, file storage, scheduling, and deployment.

    32k GitHub starsUsed in 3 repos~6.4k tokens
    DatabasesAuto-check: notes
  • Convex

    openclaw/clawhub

    Convex is the backend agents get right on the first try: an all-TypeScript reactive platform where the database, server functions, scheduling, file storage, auth, and realtime sync are one type-safe…

    9.5k GitHub stars~2.4k tokensUpdated today
    Backend & APIsAuto-check passed
  • Convex Backend

    sickn33/agentic-awesome-skills

    Build reactive backends with Convex functions, schema validation, auth integration, and deployment workflows.

    47k GitHub starsUsed in 2 repos~2.2k tokens
    Backend & APIsAuto-check: notes
  • Cross Origin Isolation

    thedaviddias/Front-End-Checklist

    A skill your agent uses when reviewing security-sensitive web apps, SharedArrayBuffer usage, worker-heavy apps, editors, or measurement features that require cross-origin isolation.

    74k GitHub stars~565 tokensUpdated yesterday
    Auto-check passed
  • Convex Agent

    openclaw/clawhub

    Add an AI agent / RAG backend (@convex-dev/agent) to the Convex app.

    9.5k GitHub stars~429 tokensUpdated today
    AI & LLM EngineeringAuto-check passed

More from vvedantb/eva

All 23 skills in this repo
  • Eva Feature Demo

    vvedantb/eva

    Record a real agent-browser screencast of one eva feature being used end to end, convert it to an X-ready mp4, and write a tweet for it.

    101 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Animate

    vvedantb/eva

    Build an animation from scratch, making the decisions in the order that determines whether it feels right — should it animate at all, what purpose, which tool, which properties, which curve and…

    101 GitHub starsUsed in 6 repos~2.9k tokens
    Auto-check passed
  • Grab a single clean HD screenshot of a new eva feature from the real running app (Playwright at deviceScaleFactor 2, 1280 layout captured crisp at 2560×1440, dev overlays hidden) and write a tweet…

    101 GitHub stars~3.2k tokensUpdated today
    Auto-check: notes
  • Code Structure

    vvedantb/eva

    A skill your agent uses when multiple workflows duplicate the same operational logic, when deciding what belongs in actions vs shared services, or when refactoring repeated operational blocks across…

    101 GitHub starsUsed in 2 repos~1.1k tokens
    Auto-check passed
  • Eva Launch Video

    vvedantb/eva

    Produce polished, mobile-friendly product demo videos of the eva app with Remotion — 1280×720, snappy beat-synced hard cuts, lo-fi music that swells on every cut, and footage captured from the REAL…

    101 GitHub stars~2.7k tokensUpdated today
    Auto-check passed
  • Libraries Dev

    vvedantb/eva

    Use the Libraries.dev UI effect libraries correctly and find where they fit in a project.

    101 GitHub stars~2.5k tokensUpdated today
    Auto-check passed

Questions about Convex Create Component

What does Convex Create Component do?

Design and build Convex components with clear boundaries, isolated state, and app-facing wrappers. Convex Create Component is an agent skill from vvedantb/eva. Design and build Convex components with clear boundaries, isolated state, and app-facing wrappers.

When should I use Convex Create Component?

Convex Create Component fits situations like: creating a new Convex component; extracting reusable backend logic into one; packaging Convex functionality for reuse across apps.

How do I install Convex Create Component in Claude Code?

Run `npx skills add vvedantb/eva --skill convex-create-component -a claude-code`. Or copy the skill folder (.claude/skills/convex-create-component in vvedantb/eva) into .claude/skills/convex-create-component in your project. Claude Code loads it when a task matches its description.

How do I install Convex Create Component in Codex?

Run `npx skills add vvedantb/eva --skill convex-create-component -a codex`. Or copy the skill folder (.claude/skills/convex-create-component in vvedantb/eva) into .agents/skills/convex-create-component in your project. Codex loads it when a task matches its description.

Can I use Convex Create Component in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add vvedantb/eva --skill convex-create-component -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/convex-create-component, .gemini/skills/convex-create-component, .github/skills/convex-create-component and .opencode/skills/convex-create-component in your project.

What does Convex Create Component need to run?

Going by SKILL.md and its folder, Convex Create Component needs the command-line tools its instructions call (npx) and credentials named OPENAI_API_KEY. Our summary lists: Node.js; A credential in OPENAI_API_KEY.

Does Convex Create Component access the network?

SKILL.md names 1 domain. As links in the text: docs.convex.dev. This is read from the text; nothing was executed.

Is Convex Create Component safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Convex Create Component use?

Convex Create Component is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Convex Create Component use?

About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 985 tokens, read only when the agent opens those files.

What are the alternatives to Convex Create Component?

Skills that share tags, products or a category with Convex Create Component: Isolated Space Boundary (openchamber/openchamber, 11k stars), Convex (davila7/claude-code-templates, 32k stars), Convex (openclaw/clawhub, 9.5k stars) and Convex Backend (sickn33/agentic-awesome-skills, 47k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Convex Create Component?

vvedantb (a GitHub user) maintains it in vvedantb/eva, which has 101 GitHub stars. The repository holds 23 skills in this directory. The repository was last updated on October 6, 2026.

Source: vvedantb/eva on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.