Agent skill

Kitcn

by udecode in udecode/kitcn

A skill your agent uses for Convex/kitcn setup and feature work: cRPC, ORM, auth, React.

Apache-2.0Auto-check passedDatabases

Install Kitcn

skills CLI
$ npx skills add udecode/kitcn --skill kitcn -a claude-code

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

GitHub CLI
$ gh skill install udecode/kitcn kitcn --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/udecode/kitcn.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/kitcn .claude/skills/kitcn && 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
kitcn
GitHub stars
450
Token cost
~7.9k tokens
SKILL.md length
2,775 words
Files
23 (incl. references)
Skills in repo
33
Repo updated
First seen
Licence
Apache-2.0

At a glance

A skill your agent uses for Convex/kitcn setup and feature work: cRPC, ORM, auth, React.

  • Works in 11 steps: Schema + Relations + Trigger → Procedure Builders + Middleware → Query + Mutation Procedure Template → …
  • Convex/kitcn setup and feature work: cRPC
  • SKILL.md covers Scope, Skill Contract, Shortcut Mode (tRPC + Drizzle… and Directory Boundary, plus 7 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Kitcn is an agent skill from udecode/kitcn. Use for Convex/kitcn setup and feature work: cRPC, ORM, auth, React.

Its SKILL.md is about 7.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 25 other files, including reference files (for example `references/features/aggregates.md`, `references/features/auth-admin.md` and `references/features/auth-organizations.md`).

It sits in Databases, covering ORMs and data access. It works with React. The repository describes itself as: Convex + Better Auth + tRPC + Drizzle + TanStack Query + shadcn. The licence is Apache-2.0.

When your agent uses it

  • Convex/kitcn setup and feature work: cRPC
  • Tasks that involve ORMs and data access

Example prompts

  • “/kitcn”

Workflow steps

11 steps, taken from the step headings in SKILL.md.

  1. Schema + Relations + Trigger
  2. Procedure Builders + Middleware
  3. Query + Mutation Procedure Template
  4. Query Modes (Use The Right One)
  5. Mutation Patterns (Most Used)
  6. Error Model
  7. React Query Integration
  8. RSC Patterns (Next.js)
  9. HTTP Route Pattern (When Feature Needs REST/Webhooks)
  10. Scheduling Pattern (If Needed)
  11. Testing Baseline (High Signal)

What it can do on your machine

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

    No URLs in SKILL.md.

    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

Kitcn loads about 7.9k tokens when it runs, and up to ~83k if it reads all its reference files. Until then it costs about 19 tokens; SKILL.md has 2,775 words of instructions outside code blocks.

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

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 udecode/kitcn at commit c6010f5, republished under its Apache-2.0 licence (© udecode). 2,775 words, ~7,909 tokens.

Download SKILL.mdSave it as .claude/skills/kitcn/SKILL.md (or your agent's skills folder). This skill also uses 22 other files; get the full folder from GitHub.
name
kitcn
description
Use for Convex/kitcn setup and feature work: cRPC, ORM, auth, React.
sources
www/content/docs/concepts.mdx, www/content/docs/orm/index.mdx, www/content/docs/orm/schema/relations.mdx, www/content/docs/orm/schema/triggers.mdx…

kitcn Core Skill (80% Path)

Use this file first for everyday feature delivery in an already configured kitcn app.

  • If setup/bootstrap/env/auth wiring or project structure mirroring is missing, use references/setup/index.md (then the relevant setup file).
  • If the task is advanced or niche, load only the specific feature reference listed at the end.

Scope

In scope:

  • Add or update schema tables, indexes, relations, and triggers.
  • Implement cRPC procedures (query, mutation, action, httpAction) with runtime auth + rate limits.
  • Implement feature UI with useCRPC() + TanStack Query.
  • Add minimal high-value tests for auth, errors, and side effects. Out of scope:
  • Greenfield setup/install/env/bootstrap.
  • Full plugin deep-dives (admin/organizations/polar).
  • Internal package-level parity testing.

Skill Contract

  1. Favor ctx.orm for app data access.
  2. Keep list/read paths bounded and index-aware.
  3. Use cRPC builders and middleware; avoid raw handler objects for new feature code.
  4. Use CRPCError for expected failures.
  5. Prefer schema triggers for cross-row invariants, but move invariant maintenance to explicit mutation helpers if trigger execution is unstable (for example init/seed hangs or recursive write paths).
  6. Keep auth/rate-limit checks server-side.
  7. Inter-procedure calls: use generated runtime helpers: create<Module>Handler(ctx) in queries/mutations, create<Module>Caller(ctx) in actions/HTTP routes, caller.actions.* for action procedures, and caller.schedule.* for scheduling. Never call ctx.runQuery/ctx.runMutation/ctx.runAction directly for module procedures.

Shortcut Mode (tRPC + Drizzle Mental Model)

Default assumption:

  • cRPC behavior is tRPC-like (builder chain + middleware + TanStack options).
  • ORM behavior is Drizzle-like (schema, relations, findMany/findFirst, insert/update/delete). Only remember these non-parity deltas:
  1. Procedure input root must be z.object(...) (no primitive root args).
  2. No z.void() outputs; omit .output(...) for no-value mutations.
  3. .output(...) parses the handler's value as-is and substitutes nothing: a handler must return the schema's input type, so z.string().nullable() needs an explicit null (?? null), not undefined. Model absent values as .nullable(), never a top-level .optional() — Convex wires undefined as null and cannot express top-level optionality, so .output(z.string().optional()) publishes v.string() and the deployment rejects the null whenever the handler returns undefined. .optional() inside an object is fine. The low-level returns: option on zCustomQuery/zCustomMutation/zCustomAction differs — it substitutes null for undefined before parsing.
  4. Stacked .input(...) calls merge input shapes.
  5. .paginated({ limit, item }) must be before .query() and adds input.cursor, input.endCursor, and input.limit; pass all three to ORM cursor queries so live splits stay bounded.
  6. Metadata is codegen’d onto @convex/api leaves (api.namespace.fn.meta) so never put secrets in .meta(...); chaining .meta(...) is shallow merge and supports defaultMeta.
  7. Auth metadata drives client behavior: auth: "optional" waits for auth load then runs, auth: "required" waits then skips when logged out.
  8. ctx.orm enforces constraints + RLS; ctx.db bypasses them.
  9. Non-paginated findMany() must be explicitly sized (limit, cursor mode, schema defaultLimit, or explicit allowFullScan).
  10. Predicate where requires explicit .withIndex(...); no implicit full scan fallback.
  11. Cursor pagination uses the first orderBy field; index that field for stable paging.
  12. maxScan applies to cursor mode only; allowFullScan is for non-cursor full-scan opt-in.
  13. String operators / columns projection / many-relation subfilters can run post-fetch; bound result size early.
  14. Search mode is relevance-ordered and does not support orderBy; vector mode has stricter limits (no cursor/offset/top-level where/order).
  15. Update/delete without where throws unless allowFullScan().
  16. count(), aggregate(), and groupBy() require a matching aggregateIndex. Use groupBy({ by, _count, _sum }) instead of multiple .count() calls or findMany + manual JS grouping. Every by field must be finite-constrained (eq/in/isNull) in where. See references/features/aggregates.md.
  17. cRPC React queries are real-time by default (subscribe: true); never use queryClient.invalidateQueries for these subscribed paths.
  18. In RSC, prefetch hydrates client, caller is server-only and not hydrated, preloadQuery hydrates but can cause stale split ownership if also rendered client-side.
  19. Better Auth Next.js shortcut is convexBetterAuth(...); generic server-only shortcut is createCallerFactory(...).
  20. On the kitcn auth client path, use createAuthMutations(authClient) wrappers so logout unsubscribes auth queries before sign out. Raw Convex preset keeps a smaller plain authClient.
  21. NEVER use ctx.runQuery/ctx.runMutation/ctx.runAction directly for module-to-module calls. Use the generated runtime helpers from convex/functions/generated/<module>.runtime.
  22. create<Module>Handler(ctx) is the default in queries/mutations: zero overhead, query/mutation ctx only, and no redundant validation or middleware.
  23. create<Module>Caller(ctx) is for actions and HTTP routes. Action procedures live under caller.actions.*; scheduling lives under caller.schedule.now|after|at|cancel. Use requireActionCtx(ctx) only for true ActionCtx callbacks; use requireSchedulerCtx(ctx) when mutation or action contexts can schedule. Each caller/handler eagerly loads its module, so split large modules.
  24. API types (Api, ApiInputs, ApiOutputs, Select, Insert, TableName) import from @convex/api — no manual inferApiInputs<typeof api>.
  25. HTTP router must export as httpRouter (not appRouter) for codegen.
  26. Server wiring imports come from convex/functions/generated/ directory: getAuth, defineAuth from generated/auth; initCRPC, QueryCtx, MutationCtx, OrmCtx from generated/server; create<Module>Caller, create<Module>Handler from generated/<module>.runtime. No manual convex/lib/orm.ts.
  27. defineAuth(() => ({ ...options, triggers })) replaces split getAuthOptions + authTriggers. Trigger callbacks are doc-first: beforeCreate(data), onCreate(doc), onUpdate(newDoc, oldDoc) — no ctx first param.
  28. Internal auth functions at internal.generated.* (not internal.auth.*).
  29. Async mutation batching is the default (codegen wires it). Customize per call: execute({ batchSize, delayMs }). Opt into sync: execute({ mode: 'sync' }) or defineSchema(..., { defaults: { mutationExecutionMode: 'sync' } }). Relevant defaults: mutationBatchSize, mutationLeafBatchSize, mutationMaxRows, mutationScheduleCallCap.
  30. Polymorphic unions are schema-first: use actionType: discriminator({ variants, as? }) in convexTable(...). Query config does not include a polymorphic option. Writes stay flat; reads synthesize nested details (or custom alias). Use withVariants: true to auto-load all one() relations on discriminator tables.
  31. Do not add manual ORM mutation batching loops in app/plugin code by default. Convex runtime batching already handles mutation execution. Prefer set-based deletes/updates over per-row loops. Only add explicit chunking when batching external side effects (for example Resend API calls) or bounded cleanup sweeps.

Directory Boundary

Use references/setup/ when the task needs:

  1. Project/file structure setup → setup/index.md + setup/server.md
  2. Auth bootstrap → setup/auth.md
  3. Client/provider wiring → setup/react.md
  4. Framework-specific setup → setup/next.md or setup/start.md For full template-level recreation: start with setup/index.md, then load relevant setup files, then load selected feature refs.

First-Pass Feature Intake (Do This Before Edits)

Lock these decisions first:

  1. Auth level per endpoint: public / optionalAuth / auth / private.
  2. Data invariants: what must always be true after writes?
  3. Query shape: list, detail, relation-loaded, search, or stream composition.
  4. Pagination mode: offset, cursor, infinite.
  5. Side effects: trigger vs scheduled function vs inline mutation.
  6. UI consumption: client hook only, RSC prefetch, or server-only caller.
  7. Risk paths: unauthorized, forbidden, not found, conflicts, rate limit.

Canonical File Targets

Typical feature touches:

  • convex/functions/schema.ts
  • convex/functions/<feature>.ts
  • convex/lib/crpc.ts (only if middleware/procedure builder changes)
  • src/lib/convex/crpc.tsx (only if cRPC context/meta wiring changes)
  • src/** feature UI files
  • convex/functions/http.ts or convex/routers/** for HTTP endpoints
  • convex/functions/crons.ts or scheduled handlers if needed

E2E Build Order (Default)

  1. Schema + indexes + relations.
  2. Trigger hooks for cross-row invariants (or explicit mutation-side sync if trigger path is unstable).
  3. Procedures with strict input/output + auth + rate limits.
  4. React hooks (query/mutation/infinite) using cRPC options.
  5. Optional: HTTP route(s), scheduling hooks.
  6. Tests for auth/error/trigger behavior.

Core Patterns

1) Schema + Relations + Trigger
ts
import {
  convexTable,
  defineSchema,
  id,
  integer,
  index,
  text,
  timestamp,
} from "kitcn/orm";

export const project = convexTable(
  "project",
  {
    name: text().notNull(),
    ownerId: id("user").notNull(),
    updatedAt: timestamp()
      .notNull()
      .defaultNow()
      .$onUpdateFn(() => new Date()),
  },
  (t) => [index("ownerId_updatedAt").on(t.ownerId, t.updatedAt)]
);

export const task = convexTable(
  "task",
  {
    projectId: id("project").notNull(),
    title: text().notNull(),
    status: text().notNull().default("open"),
    updatedAt: timestamp()
      .notNull()
      .defaultNow()
      .$onUpdateFn(() => new Date()),
  },
  (t) => [index("projectId_updatedAt").on(t.projectId, t.updatedAt)]
);

export default defineSchema({ project, task })
  .relations((r) => ({
    project: {
      tasks: r.many.task(),
    },
    task: {
      project: r.one.project({ from: r.task.projectId, to: r.project.id }),
    },
  }))
  .triggers({
    task: {
      change: async (change, ctx) => {
        const projectId = change.newDoc?.projectId ?? change.oldDoc?.projectId;
        if (!projectId) return;
        const open = await ctx.orm.query.task.findMany({
          where: { projectId, status: "open" },
          columns: { id: true },
          limit: 500,
        });
        await ctx.orm.update(project).set({ openTaskCount: open.length });
      },
    },
  });

Schema rules that matter:

  1. Index fields that power filters/order/search.
  2. many() relation paths need child FK indexes.
  3. Trigger logic must be bounded and non-recursive.
  4. Use table defaults for consistent write behavior.
  5. Keep full ORM/query edge cases in references/features/orm.md.
2) Procedure Builders + Middleware
ts
import { getSession } from "kitcn/auth";
import { CRPCError } from "kitcn/server";
import { initCRPC, type QueryCtx } from "../functions/generated/server";

const c = initCRPC
  .meta<{
    auth?: "optional" | "required";
    role?: "admin";
    ratelimit?: string;
  }>()
  .create();

function requireAuth<T>(user: T | null): T {
  if (!user) {
    throw new CRPCError({ code: "UNAUTHORIZED", message: "Not authenticated" });
  }
  return user;
}
async function getSessionUser(ctx: QueryCtx) {
  const session = await getSession(ctx);
  if (!session) return null;
  return await ctx.orm.query.user.findFirst({
    where: { id: { eq: session.userId } },
  });
}

export const publicQuery = c.query.meta({ auth: "optional" });
export const authQuery = c.query
  .meta({ auth: "required" })
  .use(async ({ ctx, next }) => {
    const user = requireAuth(await getSessionUser(ctx));
    return next({ ctx: { ...ctx, user, userId: user.id } });
  });
export const authMutation = c.mutation
  .meta({ auth: "optional" })
  .use(async ({ ctx, next }) => {
    const user = await getSessionUser(ctx);
    return next({
      ctx: { ...ctx, user, userId: user?.id ?? null },
    });
  });

Builder rules that matter:

  1. Build public, optional, auth, and private procedure families once in convex/lib/crpc.ts. Authenticated action builders live in convex/lib/crpc-action.ts, the only builder module that imports getAuth.
  2. .meta(...) is client-visible via generated API metadata. Never put secrets there.
  3. Middleware receives server-only procedure info. When procedures are built from your app generated/server helper, standard export const queries, mutations, and actions infer module:function automatically from file path + export name. Use .name("module:function") only to override or cover unusual export shapes.
  4. Resolve session/user once in middleware. Do not re-fetch auth state in every procedure. Query/mutation middleware uses getSession(ctx) from kitcn/auth, which reads the session row directly. Keep getAuth(ctx) out of convex/lib/crpc.ts: it pulls the whole Better Auth definition and every auth plugin into the static import closure of every procedure module, and Convex has no dynamic import() to escape it. Import getAuth only in the modules that call auth.api.* — convex/lib/crpc-action.ts, HTTP routes, and organization/admin mutations.
  5. Shared c.middleware() chains preserve mutation writer types on mutation procedures. If the middleware itself performs writes, type it as mutation-only with c.middleware<MutationCtx>(...).
  6. Keep deeper auth/runtime edge cases in references/setup/server.md and references/features/auth*.md.
3) Query + Mutation Procedure Template
ts
import * as z from "zod";
import { eq } from "kitcn/orm";
import { CRPCError } from "kitcn/server";
import { authMutation, authQuery } from "../lib/crpc";
import { project } from "./schema";

export const listProjects = authQuery
  .paginated({ limit: z.number().min(1).max(50).default(20), item: project })
  .query(async ({ ctx, input }) =>
    ctx.orm.query.project.findMany({
      where: { ownerId: ctx.userId },
      orderBy: { updatedAt: "desc" },
      cursor: input.cursor,
      endCursor: input.endCursor,
      limit: input.limit,
    })
  );

export const renameProject = authMutation
  .input(z.object({ id: z.string(), name: z.string().min(1).max(120) }))
  .mutation(async ({ ctx, input }) => {
    const current = await ctx.orm.query.project.findFirst({
      where: { id: input.id, ownerId: ctx.userId },
      columns: { id: true },
    });
    if (!current) {
      throw new CRPCError({ code: "NOT_FOUND", message: "Project not found" });
    }
    await ctx.orm
      .update(project)
      .set({ name: input.name })
      .where(eq(project.id, current.id));
    return null;
  });

Procedure rules that matter:

  1. Root input must be z.object(...).
  2. Use strict .input(...); add .output(...) only when needed.
  3. Omit .output(...) for no-value mutations.
  4. Use the default mutation rate limit; add .meta({ ratelimit: ... }) only for named bucket overrides.
  5. Throw CRPCError for expected outcomes.
  6. Bound every list with limit, cursor, or .paginated(...).
  7. Move advanced query-builder shapes to references/features/orm.md.
3b) Inter-Procedure Composition

Use:

  1. create<Module>Handler(ctx) in queries/mutations.
  2. create<Module>Caller(ctx) in actions/HTTP routes.
  3. caller.actions.* for action procedures.
  4. caller.schedule.* for scheduled procedures.
  5. Never ctx.runQuery / ctx.runMutation / ctx.runAction for module procedures.
4) Query Modes (Use The Right One)
  1. Default to object where.
  2. Use callback where only when composition reads better than object form.
  3. Predicate/filter callbacks require .withIndex(...) first plus explicit limit/maxScan.
  4. Full-text search uses search: { index, query, filters } and does not support orderBy.
  5. Cursor paging is only stable when the orderBy field is indexed.
  6. Advanced modes (pageByKey, vector search, pipelines, aggregate indexes) live in references/features/orm.md.
5) Mutation Patterns (Most Used)
  1. Use .returning(...) on inserts when caller needs created ids.
  2. Every update/delete path gets an explicit where(...).
  3. Clear optional columns with unsetToken.
  4. Async mutation execution is the default; use .execute({ mode: "sync" }) only when atomic all-at-once behavior is required.
  5. Prefer set-based deletes/updates. Add chunking only for external side effects or bounded cleanups.
  6. Upsert, conflict handling, mutation batching, and schema extension edge cases live in references/features/orm.md.
6) Error Model

Use this map consistently:

  1. BAD_REQUEST: invalid input or business precondition.
  2. UNAUTHORIZED: no session.
  3. FORBIDDEN: session exists, permission missing.
  4. NOT_FOUND: missing or inaccessible resource.
  5. CONFLICT: duplicate or conflicting write.
  6. TOO_MANY_REQUESTS: rate limit.
  7. INTERNAL_SERVER_ERROR: unexpected failures only. cRPC also raises it for a failed .output(...) parse, with message Output validation failed and sanitized structural Zod issues in error.data.ZodError. Custom issue messages and fields stay server-side because they can contain handler output.
  8. Add small custom data payloads on CRPCError when the client needs domain metadata like conflicting ids. Read them on the client from error.data.

Required tests:

  1. unauthenticated rejection
  2. permission rejection when relevant
  3. missing resource path
  4. conflict path when relevant
  5. rate-limited write path when relevant
Show full SKILL.md (1,054 more words)Show less
7) React Query Integration

Preconditions (must be true before writing/using useCRPC() code paths):

  1. Generated imports exist (@convex/api) from setup bootstrap.
  2. Provider chain is mounted (CRPCProvider inside QueryClient + Convex provider flow).
  3. If bootstrap/provider prerequisites are missing, stop feature work and finish references/setup/ first.
  4. Backend state is project-local in .convex/, not ~/.convex.

useCRPC() pattern: const crpc = useCRPC(); const projects = useQuery(crpc.project.listProjects.queryOptions({ cursor: null, limit: 20 })); const createProject = useMutation(crpc.project.createProject.mutationOptions());

Key client defaults/deltas:

  1. Queries are real-time by default (subscribe: true).
  2. Never use queryClient.invalidateQueries for subscribed cRPC query paths.
  3. Use { subscribe: false } only for one-time fetches; refresh those with explicit refetch/fetchQuery.
  4. Use skipUnauth: true to avoid unauthorized fetch churn.
  5. For pagination, use useInfiniteQuery from kitcn/react.
  6. Prefer typed queryKey(...) helpers for cache read/write/fetch ops instead of manual keys.
  7. For kitcn auth flows, prefer createAuthMutations(...) wrappers (not raw auth client calls) to avoid logout race errors. Raw Convex preset keeps the plain auth client path.
  8. For mutation toasts, prefer error.data?.message over error.message; data.message is the clean CRPCError payload.
  9. Prefer one global QueryClient mutation onError toast with mutation.meta.errorMessage / skipErrorToast rather than copy-pasting onError in every component.
  10. Full client/RSC depth lives in references/features/react.md.
8) RSC Patterns (Next.js)

Choose one per use case:

  1. prefetch(...) (preferred): non-blocking, hydrated, client owns data.
  2. caller.*: blocking server-only logic (redirects/auth checks), not hydrated.
  3. preloadQuery(...): blocking + hydrated when server needs data immediately.

Do not render preloadQuery result on server and again on client for the same data path.

  1. HydrateClient must wrap all client components that consume prefetched queries.
  2. Next.js-specific setup and deeper hydration tradeoffs live in references/setup/next.md and references/features/react.md.
9) HTTP Route Pattern (When Feature Needs REST/Webhooks)
ts
import { createTaskCaller } from "../functions/generated/task.runtime";

export const createTaskRoute = authRoute
  .post("/api/projects/:projectId/tasks")
  .params(z.object({ projectId: z.string() }))
  .input(z.object({ title: z.string().min(1) }))
  .output(z.object({ id: z.string() }))
  .mutation(async ({ ctx, params, input }) => {
    const caller = createTaskCaller(ctx);
    const id = await caller.createFromHttp({
      projectId: params.projectId,
      title: input.title,
      userId: ctx.userId,
    });
    return { id };
  });

HTTP-specific rules:

  1. Use z.coerce.* for search params.
  2. Keep auth and permission checks in middleware/procedure.
  3. Apply rate limits to public/heavy endpoints.
  4. Validate webhook signatures before any side effects.
  5. Use publicRoute / authRoute / optionalAuthRoute builders from convex/lib/crpc.ts.
  6. Compose endpoints with router(...) for feature-level HTTP grouping.
  7. Client calls must pass path/query args as { params, searchParams }; query values are strings.
  8. Webhooks, streaming, and Hono-specific patterns live in references/features/http.md.
10) Scheduling Pattern (If Needed)

Example: const caller = createTaskCaller(ctx); await caller.schedule.now.sendTaskCreated({ taskId: created.id, userId: ctx.userId }); await caller.schedule.at(input.sendAt).sendReminder({ taskId: input.taskId, userId: ctx.userId });

Scheduling rules:

  1. Auth context is not propagated; pass user/org IDs explicitly.
  2. Mutation scheduling is atomic with the mutation transaction.
  3. Store returned job IDs when cancellation is required.
  4. Scheduling inside actions is not atomic with action failure.
  5. Cron schedules run in UTC.
  6. Use ctx.scheduler.* directly only when you must schedule non-procedure internal.* functions.
  7. Cron expressions and operational details live in references/features/scheduling.md.
11) Testing Baseline (High Signal)

Minimum feature test set:

  1. happy path query/mutation
  2. unauthenticated rejection (UNAUTHORIZED)
  3. permission/ownership rejection (FORBIDDEN where relevant)
  4. missing resource (NOT_FOUND)
  5. trigger side effect assertion
  6. scheduler assertion if feature schedules work
  7. not-found checks should use real IDs or non-ID lookup keys (slug/name/email), not synthetic IDs
  8. Full testing recipes live in references/features/testing.md.
  9. If Convex bootstrap blocks integration tests, extract pure guards/helpers and keep one smoke integration test once bootstrap works.

Performance + Safety Checklist

Before calling a feature done:

  1. Every list query is bounded (limit/cursor).
  2. Filters/order align with indexes.
  3. Expensive post-fetch logic uses pre-narrowed index path.
  4. Mutations use targeted where and avoid accidental full scans.
  5. Trigger logic is bounded, idempotent, and avoids ping-pong loops.
  6. Error codes are explicit and intentional.
  7. User-facing writes have rate-limit metadata.
  8. Tests cover auth + not-found + side effects.
  9. ctx.db is not used on paths that rely on ORM constraints/RLS.
  10. Paginated endpoints use .paginated(...) + ORM cursor flow (not ad-hoc wrappers).
  11. For any predicate/full-scan-like path, .withIndex(...) + bound (limit/maxScan) is explicit.
  12. NEVER use @ts-nocheck, no global lint-rule downgrades, no unresolved lint warnings in touched files.

Common Mistakes (And Fixes)

MistakeCorrect pattern
Raw Convex handler for new feature procedurescRPC builders (publicQuery, authMutation, etc.)
Write-time side effects duplicated across mutationsSchema trigger, or one centralized mutation-side sync helper when trigger path is unsafe
Missing bounds on list/searchAdd limit + cursor/pagination
orderBy written as array objectsUse object form: orderBy: { updatedAt: "desc" }
Using ctx.db for policy-sensitive readsUse ctx.orm (RLS/constraints path)
Throwing generic Error for expected outcomesThrow CRPCError with explicit code
Infinite list with TanStack native hook directlyUse useInfiniteQuery from kitcn/react
Primitive root input (z.string())Use root z.object(...) input schema
Returning nothing with z.void()Omit explicit output
Returning a possibly-missing lookup under .output(...nullable())Coalesce it: ?? null. .output(...) substitutes nothing for undefined
Manual pagination wrappers for infinite endpointsUse .paginated({ limit, item })
Synthetic Convex IDs in tests ("missing-id")Use inserted IDs or semantic lookup keys
Aggregates disabled but helper/config still presentRemove aggregate helper + defineTriggers handlers + app config together
Putting secrets in .meta(...)Keep metadata non-sensitive (client-visible)
Using ctx.runQuery/ctx.runMutation/ctx.runAction directlyUse create<Module>Handler(ctx) in queries/mutations, create<Module>Caller(ctx) in actions/HTTP with caller.actions.* / caller.schedule.* (from generated/<module>.runtime)
Using createCaller in query/mutation contextUse create<Module>Handler(ctx) — zero overhead, bypasses redundant validation
Adding // @ts-nocheck to unblock compileNEVER do this; fix the underlying types using canonical patterns in references/setup/
Relaxing lint rules to pass checksKeep baseline lint config; fix code-level warnings/errors instead

Reference Escalation Map (Load Only If Needed)

Setup (once per project):

  • references/setup/index.md: bootstrap, env, decision intake, gates, checklist, troubleshooting
  • references/setup/server.md: core backend (schema, ORM, cRPC) + optional module gates
  • references/setup/auth.md: auth core bootstrap + plugin setup
  • references/setup/react.md: client core (QueryClient, provider, cRPC context)
  • references/setup/next.md: Next.js App Router setup
  • references/setup/start.md: TanStack Start setup
  • references/setup/doc-guidelines.md: skill/docs sync contract

Features (per session, self-contained):

  • references/features/orm.md: full ORM API, constraints, RLS, advanced mutations, filtering/search/composition/pagination
  • references/features/react.md: full client, RSC, hydration, error handling matrix
  • references/features/http.md: typed REST routes, webhooks, streaming
  • references/features/scheduling.md: cron + delayed job patterns
  • references/features/testing.md: deeper testing scenarios
  • references/features/aggregates.md: aggregate component patterns
  • references/features/migrations.md: built-in online data migrations (defineMigration, CLI, deploy, drift). Load when: task involves data backfills, optional→required field hardening, field renames/removals, type narrowing, or kitcn migrate CLI commands. Skip for backward-compatible changes (new optional fields, new tables, code-level defaults).
  • references/features/create-plugins.md: canonical plugin authoring patterns (split package entries, token config, scaffold/lockfile/CLI manifest rules). Load when: creating or refactoring plugins.
  • references/features/ratelimit.md: ratelimit runtime accounting (shard budget dealing, check() vs limit(), snapshot conversion, read accuracy, failure modes). Load when: tuning shards, reading remaining quota, or debugging unexpected denials. Skip for plain ratelimit.middleware() wiring, which setup/server.md owns.
  • references/features/auth.md: full Better Auth core flow
  • references/features/auth-admin.md: admin plugin details
  • references/features/auth-organizations.md: org/multi-tenant plugin details

© udecode, 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 22 other files (references) in .agents/skills/kitcn of udecode/kitcn.

  • SKILL.md
  • references/features/aggregates.md
  • references/features/auth-admin.md
  • references/features/auth-organizations.md
  • references/features/auth-polar.md
  • references/features/auth.md
  • references/features/create-plugins.md
  • references/features/http.md
  • references/features/migrations.md
  • references/features/orm.md
  • references/features/ratelimit.md
  • references/features/react.md
  • references/features/scheduling.md
  • references/features/testing.md
  • references/setup/auth.md
  • references/setup/biome.md
  • references/setup/doc-guidelines.md
  • references/setup/expo.md
  • … and 5 more

Open the folder on GitHubat commit c6010f5

Compare with similar skills

Kitcn 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.

Kitcn compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Kitcn this skilludecode/kitcn450—~7.9kAutomated safety check: PassApache-2.0
Supercheck Architecturesupercheck-io/supercheck215—~1.3kAutomated safety check: PassAGPL-3.0
Context7 MCPrtadewald/skills180—~681Automated safety check: PassNone
Documentation Lookupaffaan-m/ECC275k1 repos~670Automated safety check: PassMIT
Context7 MCPdanielvm-git/bigpowers257—~603Automated safety check: PassMIT
Vite Flare Starterjezweb/claude-skills1.1k—~2.6kAutomated safety check: PassMIT

Similar skills

  • Supercheck Architecture

    supercheck-io/supercheck

    Work on Supercheck system architecture, Next.js routes and actions, React data hooks, Drizzle schemas and migrations, app-worker boundaries, or cross-package contracts.

    215 GitHub stars~1.3k tokensUpdated today
    DatabasesAuto-check passed
  • Context7 MCP

    rtadewald/skills

    This skill should be used when the user asks about libraries, frameworks, API references, or needs code examples.

    180 GitHub stars~681 tokensUpdated 9 days ago
    DatabasesAuto-check passed
  • 通过 Context7 MCP 使用最新的库和框架文档,而非训练数据。当用户提出设置问题、API参考、代码示例或命名框架(例如 React、Next.js、Prisma)时激活。

    275k GitHub starsUsed in 1 repo~670 tokens
    DatabasesAuto-check passed
  • Context7 MCP

    danielvm-git/bigpowers

    Fetch current library docs via Context7 MCP instead of training data.

    257 GitHub stars~603 tokensUpdated 17 days ago
    DatabasesAuto-check passed
  • Vite Flare Starter

    jezweb/claude-skills

    Scaffold a full-stack Cloudflare app from the vite-flare-starter template — React 19 + Hono + D1+Drizzle + better-auth + Tailwind v4+shadcn/ui + TanStack Query + R2 + Workers AI.

    1.1k GitHub stars~2.6k tokensUpdated 3 days ago
    DatabasesAuto-check passed
  • Modern Web Guidance

    JetBrains/skills

    Official

    Search tool for modern web development best practices. An agent skill from JetBrains/skills.

    364 GitHub starsUsed in 3 repos~1.4k tokens
    DevOps & CloudAuto-check passed

More from udecode/kitcn

All 33 skills in this repo
  • Walkthrough

    udecode/kitcn

    Create a short annotated visual walkthrough from real final-state screenshots or rendered artifacts.

    450 GitHub stars~1.6k tokensUpdated 7 days ago
    Auto-check passed
  • Avoid Feature Creep

    udecode/kitcn

    Prevent feature creep when building software, apps, and AI-powered products.

    450 GitHub stars~2.7k tokensUpdated 7 days ago
    Auto-check passed
  • Changeset Resolve

    udecode/kitcn

    Repair an unreleased .changeset/.md file so it matches the real branch delta against main.

    450 GitHub stars~922 tokensUpdated 7 days ago
    Auto-check passed
  • Audit newer Convex npm releases against kitcn. An agent skill from udecode/kitcn.

    450 GitHub stars~1.8k tokensUpdated 7 days ago
    Auto-check passed
  • Jotai X

    udecode/kitcn

    A skill your agent uses when working with Jotai X stores (createAtomStore), accessing state in components or callbacks, persisting state to cookies or localStorage

    450 GitHub stars~3.7k tokensUpdated 7 days ago
    Auto-check passed
  • Linear Backlog

    udecode/kitcn

    Run a scoped Linear backlog autonomously as a sequence of maximal safe parallel batches by composing orchestrator, autogoal, and task.

    450 GitHub stars~3.1k tokensUpdated 7 days ago
    Auto-check passed

Works with

Categories

Questions about Kitcn

What does Kitcn do?

A skill your agent uses for Convex/kitcn setup and feature work: cRPC, ORM, auth, React. Kitcn is an agent skill from udecode/kitcn. Use for Convex/kitcn setup and feature work: cRPC, ORM, auth, React.

When should I use Kitcn?

Kitcn fits situations like: convex/kitcn setup and feature work: cRPC; tasks that involve ORMs and data access.

How do I install Kitcn in Claude Code?

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

How do I install Kitcn in Codex?

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

Can I use Kitcn 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 udecode/kitcn --skill kitcn -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/kitcn, .gemini/skills/kitcn, .github/skills/kitcn and .opencode/skills/kitcn in your project.

What does Kitcn need to run?

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

Does Kitcn access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Kitcn 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 Kitcn use?

Kitcn 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 Kitcn use?

About 7.9k tokens (SKILL.md is roughly 32k 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 76k tokens, read only when the agent opens those files.

What are the alternatives to Kitcn?

Skills that share tags, products or a category with Kitcn: Supercheck Architecture (supercheck-io/supercheck, 215 stars), Context7 MCP (rtadewald/skills, 180 stars), Documentation Lookup (affaan-m/ECC, 275k stars) and Context7 MCP (danielvm-git/bigpowers, 257 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Kitcn?

udecode (a GitHub organization) maintains it in udecode/kitcn, which has 450 GitHub stars. The repository holds 33 skills in this directory. The repository was last updated on October 1, 2026.

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