Agent skill

Convex Functions

by waynesutton in waynesutton/builder-skills

Writes Convex queries, mutations, actions, and internal functions in the object form with args and returns validators, correct ctx usage, runtime boundaries, and error handling.

Apache-2.0Auto-check passed

Install Convex Functions

skills CLI
$ npx skills add waynesutton/builder-skills --skill convex-functions -a claude-code

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

GitHub CLI
$ gh skill install waynesutton/builder-skills convex-functions --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/waynesutton/builder-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/convex-functions .claude/skills/convex-functions && 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-functions
GitHub stars
404
Token cost
~2.8k tokens
SKILL.md length
895 words
Files
4 (incl. assets)
Skills in repo
17
Repo updated
First seen
Licence
Apache-2.0

At a glance

Writes Convex queries, mutations, actions, and internal functions in the object form with args and returns validators, correct ctx usage, runtime boundaries, and error handling.

  • Changing anything in convex/.ts that exports a function
  • SKILL.md covers Pick the function type, The object form, Reading data and Writing data, plus 7 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md
  • Deciding between query

What it does

Convex Functions is an agent skill from waynesutton/builder-skills. Writes Convex queries, mutations, actions, and internal functions in the object form with args and returns validators, correct ctx usage, runtime boundaries, and error handling. Use when adding or changing anything in convex/.ts that exports a function, or when deciding between query, mutation, and action.

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 5 other files, including assets (for example `agents/openai.yaml`).

The repository describes itself as: Builder skills for Convex apps. Convex patterns plus a PRD, task.md, changelog, and files.md workflow for Claude Code, Codex, Cursor, and OpenCode. The licence is Apache-2.0.

When your agent uses it

  • Changing anything in convex/.ts that exports a function
  • Deciding between query

Example prompts

  • “Use the convex-functions skill to write Convex queries, mutations, actions, and internal functions in the object form with args and returns…”
  • “/convex-functions”

What it can do on your machine

Read from SKILL.md and the folder at commit 82d1ce2. 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

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    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 no API keys, tokens, secrets or passwords.

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

Context cost

Convex Functions loads about 2.8k tokens when it runs. Until then it costs about 81 tokens; SKILL.md has 895 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~81
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k

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 waynesutton/builder-skills at commit 82d1ce2, republished under its Apache-2.0 licence (© waynesutton). 895 words, ~2,754 tokens.

Download SKILL.mdSave it as .claude/skills/convex-functions/SKILL.md (or your agent's skills folder). This skill also uses 3 other files; get the full folder from GitHub.
name
convex-functions
description
Writes Convex queries, mutations, actions, and internal functions in the object form with args and returns validators, correct ctx usage, runtime boundaries, and error handling. Use when adding or changing anything in convex/*.ts that exports a function, or when deciding between query, mutation, and action.

Convex functions

Every exported function in convex/ uses the object form with args and returns validators. Pick the type by what the handler touches: queries read, mutations write, actions call out.

Pick the function type

TypeDatabaseExternal callsCallable byUse for
queryReadNoClients, other functionsReads. Cached and reactive.
mutationRead and writeNoClients, other functionsWrites. One transaction.
actionOnly via runQuery and runMutationYesClients, scheduler, other actionsfetch, third party SDKs, Node APIs
internalQuery, internalMutation, internalActionSame as the public formSameOnly other Convex functionsScheduled work, crons, privileged writes
httpActionOnly via runQuery and runMutationYesHTTP requests in convex/http.tsWebhooks, REST endpoints

Default to query or mutation. Reach for an action only when the handler must talk to something outside Convex.

The object form

Declare args and returns on every function. A function that returns nothing declares returns: v.null() and returns null. Hoist a shared document validator when several functions return the same shape.

typescript
// convex/tasks.ts
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";

const taskValidator = v.object({
  _id: v.id("tasks"),
  _creationTime: v.number(),
  userId: v.id("users"),
  title: v.string(),
  completed: v.boolean(),
});

export const get = query({
  args: { taskId: v.id("tasks") },
  returns: v.union(taskValidator, v.null()),
  handler: async (ctx, args) => {
    return await ctx.db.get(args.taskId);
  },
});

export const remove = mutation({
  args: { taskId: v.id("tasks") },
  returns: v.null(),
  handler: async (ctx, args) => {
    await ctx.db.delete(args.taskId);
    return null;
  },
});

Reading data

Use ctx.db.get(id) for one document by id. For everything else use withIndex against an index defined in convex/schema.ts. Never call .filter() on a table query; it scans the whole table.

typescript
export const listByUser = query({
  args: { userId: v.id("users") },
  returns: v.array(taskValidator),
  handler: async (ctx, args) => {
    return await ctx.db
      .query("tasks")
      .withIndex("by_user", (q) => q.eq("userId", args.userId))
      .order("desc")
      .take(50);
  },
});

Pick the terminal method by how many documents you expect:

MethodReturnsUse when
.unique()One doc or null, throws on more than oneThe index guarantees at most one match
.first()First doc or nullYou want the newest or oldest match
.take(n)Up to n docsA bounded list such as a recent feed
.collect()Every matchThe result set is small and stays small
.paginate(opts)A page plus cursorThe table is unbounded

Paginated queries take paginationOpts: paginationOptsValidator (from convex/server) as an argument.

Writing data

MethodWhat it does
ctx.db.insert("tasks", doc)Inserts and returns the new id
ctx.db.patch(id, fields)Shallow merges fields. Throws if the doc is missing
ctx.db.replace(id, doc)Replaces the whole doc. Throws if missing
ctx.db.delete(id)Deletes the doc

Patch directly when you do not need the old value. Reading first widens the window for write conflicts. Make mutations safe to retry.

typescript
export const rename = mutation({
  args: { taskId: v.id("tasks"), title: v.string() },
  returns: v.null(),
  handler: async (ctx, args) => {
    await ctx.db.patch(args.taskId, { title: args.title });
    return null;
  },
});

Internal functions and references

query, mutation, and action are public. Anyone with the deployment URL can call them. Use internalQuery, internalMutation, and internalAction for code that should only run from other Convex code: scheduled jobs, crons, webhook handlers, privileged writes.

Reference functions through the generated objects in ./_generated/api:

  • api.tasks.get points at a public function in convex/tasks.ts
  • internal.tasks.markPaid points at an internal function in the same file
  • Folders map to paths: convex/billing/invoices.ts gives api.billing.invoices.list

Always schedule internal.*. Scheduled functions and crons run without a client, so a public reference there skips the auth checks a client call would hit.

typescript
// convex/messages.ts
import { mutation, internalMutation } from "./_generated/server";
import { internal } from "./_generated/api";
import { v } from "convex/values";

export const send = mutation({
  args: { channelId: v.id("channels"), content: v.string() },
  returns: v.id("messages"),
  handler: async (ctx, args) => {
    const messageId = await ctx.db.insert("messages", args);
    await ctx.scheduler.runAfter(0, internal.messages.notifySubscribers, {
      channelId: args.channelId,
      messageId,
    });
    return messageId;
  },
});

export const notifySubscribers = internalMutation({
  args: { channelId: v.id("channels"), messageId: v.id("messages") },
  returns: v.null(),
  handler: async (ctx, args) => {
    const subs = await ctx.db
      .query("subscriptions")
      .withIndex("by_channel", (q) => q.eq("channelId", args.channelId))
      .collect();
    await Promise.all(
      subs.map((sub) =>
        ctx.db.insert("notifications", {
          userId: sub.userId,
          messageId: args.messageId,
          read: false,
        }),
      ),
    );
    return null;
  },
});

Actions and runtime boundaries

Actions have no ctx.db. They read through ctx.runQuery and write through ctx.runMutation. Each call is its own transaction, so keep the count low and do related reads and writes inside one mutation.

fetch works in the default runtime. Add "use node"; as the first line of a file only when an action needs Node built ins or a Node only SDK. A "use node" file can export actions only; queries and mutations go in a separate file.

typescript
// convex/orders.ts (default runtime)
import { action } from "./_generated/server";
import { internal } from "./_generated/api";
import { v, ConvexError } from "convex/values";
import { Doc } from "./_generated/dataModel";

export const charge = action({
  args: { orderId: v.id("orders") },
  returns: v.null(),
  handler: async (ctx, args) => {
    // Same file call: annotate the result so TypeScript does not hit a circular type
    const order: Doc<"orders"> | null = await ctx.runQuery(
      internal.orders.getForCharge,
      { orderId: args.orderId },
    );
    if (!order) {
      throw new ConvexError("Order not found");
    }
    const res = await fetch("https://api.payments.example/charge", {
      method: "POST",
      body: JSON.stringify({ amount: order.total }),
    });
    await ctx.runMutation(internal.orders.setStatus, {
      orderId: args.orderId,
      status: res.ok ? "paid" : "failed",
    });
    return null;
  },
});

Doc and Id come from ./_generated/dataModel. The annotation is only needed when the called function lives in the same file.

Show full SKILL.md (352 more words)Show less

Errors

Throw ConvexError from convex/values for anything a client should read. Its data reaches the client; a plain Error message is redacted in production. Return null for expected absences such as a lookup that finds nothing. Throw for real failures: not authenticated, not authorized, invalid input.

typescript
import { ConvexError } from "convex/values";

throw new ConvexError({ code: "NOT_FOUND", message: "Task not found" });

Thin wrappers

Keep handlers short. Put auth lookups, validation, and business logic in plain async functions that take ctx first, then call them from the wrapper. Plain helpers are testable and shared between queries and mutations without a ctx.runQuery hop.

typescript
import { QueryCtx, MutationCtx } from "./_generated/server";
import { ConvexError } from "convex/values";

export async function getCurrentUser(ctx: QueryCtx | MutationCtx) {
  const identity = await ctx.auth.getUserIdentity();
  if (!identity) {
    throw new ConvexError("Not authenticated");
  }
  const user = await ctx.db
    .query("users")
    .withIndex("by_token", (q) =>
      q.eq("tokenIdentifier", identity.tokenIdentifier),
    )
    .unique();
  if (!user) {
    throw new ConvexError("User not found");
  }
  return user;
}

From a query or mutation, call the helper directly. ctx.runQuery and ctx.runMutation are for actions and component boundaries.

Common mistakes

MistakeWhy it breaksDo instead
No returns validatorReturn shape drifts and client types lieDeclare returns, use v.null() for nothing
.filter() on a table queryFull table scanAdd an index, use withIndex
ctx.db inside an actionActions have no database handlectx.runQuery and ctx.runMutation
fetch inside a query or mutationTransactions must be deterministicMove it to an action
Scheduling api.*Runs public code without a client, skips authSchedule internal.*
"use node" in a file with queriesBundler rejects the fileSplit actions into their own file
Date.now() in a queryBreaks caching and reactivityPass time as an arg or store a status field
Many runQuery calls from one actionEach is a separate transaction, races appearOne mutation that does the related work
Plain Error for user messagesMessage is hidden in productionConvexError
Missing await on ctx.db or schedulerWrite may not commitAwait every ctx call

Checklist

  • Object form with args and returns on every exported function
  • returns: v.null() and return null when there is nothing to return
  • Reads use ctx.db.get(id) or withIndex, never .filter()
  • Unbounded tables use .paginate() or .take(n), not .collect()
  • Mutations patch directly and are safe to retry
  • Scheduled and cron targets are internal.*
  • Actions never touch ctx.db
  • "use node" only in files that export actions and need Node
  • Same file runQuery and runMutation results have a type annotation
  • Client visible errors are ConvexError
  • Every ctx.* promise is awaited

Docs

© waynesutton, Apache-2.0. 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 3 other files (assets) in skills/convex-functions of waynesutton/builder-skills.

  • SKILL.md
  • agents/openai.yaml
  • assets/large-logo.png
  • assets/small-logo.svg

Open the folder on GitHubat commit 82d1ce2

Compare with similar skills

Convex Functions 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 Functions compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Convex Functions this skillwaynesutton/builder-skills404—~2.8kAutomated safety check: PassApache-2.0
Frontend Query Mutationlangflow-ai/langflow156k—~979Automated safety check: PassMIT
Convexdavila7/claude-code-templates32k3 repos~6.4kAutomated safety check: NotesMIT
Convexopenclaw/clawhub9.5k—~2.4kAutomated safety check: PassMIT
Internal Commsalirezarezvani/claude-skills28k—~3.4kAutomated safety check: PassMIT
Internal Communicationsickn33/agentic-awesome-skills47k1 repos~3.4kAutomated safety check: PassMIT

Similar skills

  • Frontend Query Mutation

    langflow-ai/langflow

    Guide for implementing Langflow frontend query and mutation patterns with Axios and TanStack React Query v5.

    156k GitHub stars~979 tokensUpdated today
    Frontend & DesignAuto-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 yesterday
    Backend & APIsAuto-check passed
  • Internal Comms

    alirezarezvani/claude-skills

    A skill your agent uses when a Head of People Ops, BizOps lead, or Internal Communications owner needs to draft and sequence an internal-only change-management communication — a re-org announcement…

    28k GitHub stars~3.4k tokensUpdated 1 mo ago
    Writing & ContentAuto-check passed
  • Internal Communication

    sickn33/agentic-awesome-skills

    Internal communication log: title, type, date, department, host and attendees, agenda, action items, follow-up date, meeting link and delivery status.

    47k GitHub starsUsed in 1 repo~3.4k tokens
    Writing & ContentAuto-check passed
  • Query Netdata Agents

    netdata/netdata

    Query or explain direct Netdata Agent APIs and Functions; review direct-query recipes or helpers; troubleshoot bearer authentication.

    81k GitHub stars~2k tokensUpdated today
    DevOps & CloudAuto-check: notes

More from waynesutton/builder-skills

All 17 skills in this repo
  • Convex Agents

    waynesutton/builder-skills

    Builds AI agents on the Convex agent component: threads, messages, tools that call queries and mutations, streaming, RAG with vector search, and workflows for multi step jobs.

    404 GitHub stars~2.2k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Best Practices

    waynesutton/builder-skills

    Production patterns for Convex apps and the rules the @convex-dev/eslint-plugin enforces: validators, indexes, idempotent mutations, avoiding OCC conflicts, thin function wrappers, error handling.

    404 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Component Authoring

    waynesutton/builder-skills

    Creates reusable Convex components with defineComponent, a clean client wrapper, their own schema, and an npm publish setup.

    404 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Cron Jobs

    waynesutton/builder-skills

    Schedules work in Convex: cron jobs in convex/crons.ts, one off scheduled functions with runAfter and runAt, batching large jobs, and cancelling or inspecting the queue.

    404 GitHub stars~2k tokensUpdated 10 days ago
    Auto-check passed
  • Convex HTTP Actions

    waynesutton/builder-skills

    Adds HTTP endpoints in convex/http.ts: webhook receivers with signature checks, REST style routes, CORS, auth headers, streaming responses, and file uploads over HTTP.

    404 GitHub stars~2.6k tokensUpdated 10 days ago
    Auto-check passed
  • Convex Migrations

    waynesutton/builder-skills

    Changes a live Convex schema without downtime: make a field optional, backfill in batches, flip the validator, then clean up.

    404 GitHub stars~2.1k tokensUpdated 10 days ago
    Auto-check passed

Questions about Convex Functions

What does Convex Functions do?

Writes Convex queries, mutations, actions, and internal functions in the object form with args and returns validators, correct ctx usage, runtime boundaries, and error handling. Convex Functions is an agent skill from waynesutton/builder-skills. Writes Convex queries, mutations, actions, and internal functions in the object form with args and returns validators, correct ctx usage, runtime boundaries, and error handling.

When should I use Convex Functions?

Convex Functions fits situations like: changing anything in convex/.ts that exports a function; deciding between query.

How do I install Convex Functions in Claude Code?

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

How do I install Convex Functions in Codex?

Run `npx skills add waynesutton/builder-skills --skill convex-functions -a codex`. Or copy the skill folder (skills/convex-functions in waynesutton/builder-skills) into .agents/skills/convex-functions in your project. Codex loads it when a task matches its description.

Can I use Convex Functions 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 waynesutton/builder-skills --skill convex-functions -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-functions, .gemini/skills/convex-functions, .github/skills/convex-functions and .opencode/skills/convex-functions in your project.

What does Convex Functions need to run?

SKILL.md names no scripts, command-line tools or credentials: Convex Functions is instructions for the agent only.

Does Convex Functions 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 Functions 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 Functions use?

Convex Functions is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Convex Functions use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Convex Functions?

Skills that share tags, products or a category with Convex Functions: Frontend Query Mutation (langflow-ai/langflow, 156k stars), Convex (davila7/claude-code-templates, 32k stars), Convex (openclaw/clawhub, 9.5k stars) and Internal Comms (alirezarezvani/claude-skills, 28k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Convex Functions?

waynesutton (a GitHub user) maintains it in waynesutton/builder-skills, which has 404 GitHub stars. The repository holds 17 skills in this directory. The repository was last updated on September 28, 2026.

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