Backend
Drive Convex or Concave, verify local runtime, generate files, deploy, migrate, reset, and analyze.
dev
npx kitcn devOptions:
| Flag | Description |
|---|---|
--api <dir> | Output directory for api.ts (default: convex/shared) |
--backend <convex|concave> | Backend CLI to drive |
--bootstrap | Run one-shot local Convex bootstrap and exit |
--config <path> | Path to kitcn config file (default: ./concave.json) |
--backfill=auto|on|off | Dev aggregate backfill mode toggle (default: auto) |
--backfill-wait / --no-backfill-wait | Wait for all target indexes to become READY |
--backfill-batch-size <n> | Batch size for aggregate backfill kickoff |
--migrations=auto|on|off | Dev migration mode toggle (default: auto) |
--migrations-wait / --no-migrations-wait | Wait for migration run completion |
--migrations-allow-drift / --no-migrations-allow-drift | Override drift policy in dev |
Wraps the selected backend dev command, generates runtime files on startup, watches for changes, and passes all other flags through.
On backend convex, kitcn dev runs convex init before codegen,
watchers, and the main convex dev process.
Set meta["kitcn"].dev.preRun in concave.json to run one Convex
setup function inside the main dev loop. It is Convex-only; backend concave
has no equivalent --run flow.
dev.preRun maps to Convex's native convex dev --run <function> flow with
the same deployment-target args as the main dev command.
Local backend state depends on the selected backend:
- Convex:
.convex/at project root - Concave Bun/Node:
.concave/local/
kitcn dev always runs full cRPC generation by default. Use kitcn codegen --scope ... for one-off scoped generation.
When aggregate backfill is enabled, kitcn dev kicks off aggregateBackfill and waits for READY by default (in background).
When convex/functions/schema.ts changes, kitcn dev re-runs resume backfill automatically only if aggregate index signatures changed.
# One-shot local Convex bootstrap
npx kitcn dev --bootstrapverify
npx kitcn verifyRuns a one-shot local Convex runtime proof through the kitcn dev path.
Use it when you want a CI-safe answer to one question: does local kitcn dev boot cleanly right now?
kitcn verify:
- runs the runtime path through
dev --once - reuses the current local Convex deployment when one is already configured
- falls back to local anonymous setup for fresh non-interactive Convex verify
codegen
Generate api.ts once against the selected backend connection:
npx kitcn codegenOptions:
| Flag | Description |
|---|---|
--api <dir> | Output directory (default: convex/shared) |
--backend <convex|concave> | Backend CLI to drive |
--scope <all|auth|orm> | Generation scope (default: all) |
--config <path> | Path to kitcn config file (default: ./concave.json) |
--debug | Show detailed output |
--silent | Suppress all output |
See Scope Modes for the full output manifest per scope.
Plugin note:
kitcn codegendiscovers plugins from schema extensions and local plugin scaffold registration.- Plugin discovery is used for typing/runtime context only.
codegendoes not generate plugin runtime modules. Plugin runtime files are scaffold-owned.
env
Manage environment variables:
# Push all vars from convex/.env
npx kitcn env push
# Force overwrite existing values
npx kitcn env push --force
# Production deployment
npx kitcn env push --prod
# Rotate auth keys, then push fresh JWKS
npx kitcn env push --rotate
# Pull remote values to stdout
npx kitcn env pull
# Write remote values to a file
npx kitcn env pull --out convex/.env.remotePush options:
| Flag | Description |
|---|---|
--rotate | Rotate auth keys before fetching fresh JWKS |
--force | Overwrite existing values (default: skip if up to date) |
--from-file <path> | Push values from a file instead of convex/.env |
Pull options:
| Flag | Description |
|---|---|
--out <path> | Write pulled values to a file instead of stdout |
Target options:
| Flag | Description |
|---|---|
--prod | Target the production deployment |
--deployment-name <name> | Target a named deployment |
--preview-name <name> | Target a named preview deployment |
--env-file <path> | Use an env file to resolve the target deployment |
kitcn env push reads convex/.env by default, filters Convex-managed variables, then pushes one batch update through convex env set --from-file. If auth scaffold is installed, it also ensures BETTER_AUTH_SECRET exists locally, fetches JWKS with convex run generated/auth:getLatestJwks, and includes both in the push payload. With --rotate, it runs convex run generated/auth:rotateKeys first, then pushes the fresh JWKS.
On backend convex, kitcn dev handles the local auth bootstrap flow and watches convex/.env for later local edits. kitcn dev --bootstrap is the one-shot local setup version of that flow. kitcn verify is the one-shot local runtime proof. kitcn add auth --yes reuses the same local bootstrap path when it needs generated auth runtime and JWKS. Use kitcn env push for --prod, --rotate, or explicit repair against an already active deployment.
If --from-file is omitted and stdin is piped, kitcn env push reads the piped payload instead of convex/.env.
kitcn env pull wraps convex env list and preserves the exact payload format, so you can print it or write it to disk unchanged.
All env commands forward Convex deployment-target args such as --prod, --deployment-name, --preview-name, and --env-file.
Other env commands stay aligned with Convex:
npx kitcn env list
npx kitcn env get <name>
npx kitcn env set <name> <value>
npx kitcn env remove <name>kitcn env set keeps Convex 1.33 behavior for interactive values,
--from-file, and stdin input. kitcn env pull gives you the same
robust export format, so env pull --out <path> and env set --from-file <path>
round-trip cleanly.
On backend concave, kitcn env ... fails clearly because Concave has no upstream env command.
Unknown commands on backend convex pass straight through to the Convex CLI, so kitcn insights opens the same insights surface as convex insights.
deploy
npx kitcn deploy --prodkitcn deploy runs:
- selected backend
deploy ... - post-deploy
generated/server:migrationRun(direction: "up") - status polling (
generated/server:migrationStatus) until completion (default behavior) - post-deploy
generated/server:aggregateBackfill - aggregate status polling (
generated/server:aggregateBackfillStatus) untilREADY(default behavior)
Options:
| Flag | Description |
|---|---|
--backfill=auto|on|off | Enable/disable post-deploy aggregate backfill |
--backfill-wait / --no-backfill-wait | Wait for all target indexes to become READY |
--backfill-batch-size <n> | Batch size for backfill jobs |
--backfill-poll-ms <n> | Poll interval while waiting |
--backfill-timeout-ms <n> | Max wait duration before timeout |
--backfill-strict / --no-backfill-strict | Fail deploy on timeout/backfill error |
--migrations=auto|on|off | Enable/disable post-deploy migrate up |
--migrations-wait / --no-migrations-wait | Wait for migration completion |
--migrations-batch-size <n> | Batch size for migration workers |
--migrations-poll-ms <n> | Poll interval while waiting for migration completion |
--migrations-timeout-ms <n> | Max migration wait duration before timeout |
--migrations-strict / --no-migrations-strict | Fail deploy on migration timeout/error |
--migrations-allow-drift / --no-migrations-allow-drift | Override drift blocking policy |
Already-READY indexes are skipped (noop). See Resume Compatibility for full behavior rules.
aggregate rebuild
npx kitcn aggregate rebuild --prodRuns generated/server:aggregateBackfill in rebuild mode (clear + recompute) for the selected deployment, then waits for READY by default.
aggregate backfill
npx kitcn aggregate backfill --prodRuns generated/server:aggregateBackfill in resume mode (no clear/rebuild) for the selected deployment, then waits for READY by default.
aggregate prune
npx kitcn aggregate prune --prodRuns generated/server:aggregateBackfill in prune mode to delete storage/state for aggregate indexes no longer declared in schema.
migrate create
npx kitcn migrate create backfill_user_statusCreates a timestamped migration file under convex/functions/migrations/ and regenerates convex/functions/migrations/manifest.ts.
migrate up
npx kitcn migrate up --prodRuns generated/server:migrationRun with direction: "up" and waits by default.
migrate down
# Roll back the latest migration
npx kitcn migrate down --steps 1 --prod
# Roll back everything after a target migration id
npx kitcn migrate down --to 20260227_000000_backfill_user_ban_reason --prodRuns generated/server:migrationRun with direction: "down" in reverse applied order.
migrate status
npx kitcn migrate status --prodReads migration run/state internals from generated/server:migrationStatus.
migrate cancel
npx kitcn migrate cancel --prodCancels the active migration run (generated/server:migrationCancel).
reset
Wipe all table data in one step. Useful for dev resets and seeding workflows.
npx kitcn reset --yesThe --yes flag is required — reset is destructive. Under the hood it calls generated/server:reset (which uses ctx.orm.withoutTriggers to clear every table, including internal aggregate and migration state tables).
You can run custom functions before and after the reset:
# Seed data after reset
npx kitcn reset --yes --after generated/seed:seedAll
# Snapshot before, seed after
npx kitcn reset --yes --before generated/seed:snapshot --after generated/seed:seedAllOptions:
| Flag | Description |
|---|---|
--yes | Required. Confirm destructive reset |
--before <fn> | Run a Convex function before reset |
--after <fn> | Run a Convex function after reset |
analyze
Analyze Convex runtime bundle size and dependency hotspots:
# Function-oriented hotspot ranking (default)
npx kitcn analyze
# Deploy-accurate bundle view
npx kitcn analyze --deploy
# Deep drilldown for one entry
npx kitcn analyze '^convex/functions/auth\\.ts$' --detailsOptions:
| Flag | Description |
|---|---|
--deploy | Deploy-accurate isolate bundle analysis |
--details | Show expanded per-entry package graph details |
--input | Include top internal inputs in expanded details |
--interactive, -i | Enable interactive hotspot UI (default: off, TTY only) |
--all, -a | Include Convex-ignored entries (multi-dot files and generated/ modules) |
--show-small | Include tiny dependencies (hidden by default) |
--warn-mb <n> | WARN threshold in MB (default: 6) |
--danger-mb <n> | DANGER threshold in MB (default: 8) |
--fail-mb <n> | Exit with code 1 if largest output meets threshold |
--width <n> | Force terminal output width |
See Mode Behavior for the full 12-item behavior reference.
Output
The CLI generates convex/shared/api.ts. Do not create this file manually — it is fully generated by kitcn dev / kitcn codegen.
The CLI extracts metadata from procedure exports automatically. See Metadata Extraction for supported patterns and base procedure mapping.
Configuration
kitcn supports a project config at ./concave.json (or pass --config <path>).
It reads settings from meta["kitcn"].
The CLI reads from convex.json:
{
"functions": "convex"
}The functions field specifies the Convex functions directory (default: convex).
Path Aliases
Add a path alias to import @convex/api:
{
"compilerOptions": {
"paths": {
"@convex/*": ["./convex/shared/*"]
}
}
}Then import:
import { api } from '@convex/api';Next Steps
API Reference
Scope Modes
Scope modes apply to kitcn codegen.
| Scope | Generated outputs |
|---|---|
all (default) | convex/shared/api.ts, <functionsDir>/generated/server.ts, <functionsDir>/generated/auth.ts, runtime files |
auth | <functionsDir>/generated/server.ts, <functionsDir>/generated/auth.ts, <functionsDir>/generated/auth.runtime.ts (when <functionsDir>/auth.ts has a default export) |
orm | <functionsDir>/generated/server.ts, runtime files for ORM internals |
In scoped modes, stale artifacts outside the current scope are removed automatically (for example convex/shared/api.ts and cRPC runtime modules in auth/orm mode).
Resume Compatibility
- key shape changes (
aggregateIndex(...).on(...)fields /.all()key shape) require rebuild; deploy exits in strict mode and instructskitcn aggregate rebuild - metric additions (
.count/.sum/.avg/.min/.max) are backfilled automatically - metric removals are metadata-only updates (no clear/rebuild)
- removed aggregate indexes are pruned automatically (state + bucket/member/extrema rows)
Mode Behavior
- Default mode (
kitcn analyze) ranks least optimized Convex function modules by output size and dependency weight. --deploymirrors deploy shape by bundling the same selected entry set together with shared chunks.- Convex-ignored entries with detected handlers are included by default in both modes. Add
--allto include every ignored entry (including ones without detected handlers). --detailsadds a package graph view (size + top cross-package imports). Add--inputto include the top internal inputs table.- Filter to specific entries by passing a positional regex:
kitcn analyze polar.*orkitcn analyze '^convex/functions/polar.*\\.ts$'. - Hotspot output is agent-first: it prints an Agent queue with ready-to-run optimization commands.
- Use
--interactiveto open the keyboard-driven hotspot UI (--interactiveis hotspot-only and rejected with--deploy). - Ranking includes only modules with detected handler exports (cRPC
_crpcMetascan, plus native Convex handler exports). - Interactive mode uses split panes by default (entry list left, detail preview right, key/status bar bottom).
- Right pane always follows the current selection (no pin mode).
- On narrow terminals (
<120columns), interactive mode falls back to stacked layout (list first, details second, key/status last). - Interactive controls:
j/kmove,←/→pane cycle,/filter,ssort cycle,gall-toggle,rrefresh,wwatch toggle,qquit,?help.
Metadata Extraction
Supported Patterns
// Base procedure auth is detected
export const list = publicQuery.query(...); // auth: undefined
export const me = authQuery.query(...); // auth: 'required'
export const profile = optionalAuthQuery.query(...); // auth: 'optional'
// Function type is detected
export const get = publicQuery.query(...); // type: 'query'
export const create = publicMutation.mutation(...); // type: 'mutation'
export const sync = publicAction.action(...); // type: 'action'
// .meta() is extracted
export const admin = authQuery
.meta({ role: 'admin' })
.query(...); // { auth: 'required', role: 'admin', type: 'query' }Base Procedure Mapping
| Base Procedure | Auth Type |
|---|---|
publicQuery | undefined |
publicMutation | undefined |
publicAction | undefined |
optionalAuthQuery | 'optional' |
optionalAuthMutation | 'optional' |
authQuery | 'required' |
authMutation | 'required' |
authAction | 'required' |
Configuration Reference
kitcn supports a project config at ./concave.json (or --config <path>):
{
"meta": {
"kitcn": {
"paths": {
"lib": "convex/lib",
"shared": "convex/shared"
},
"dev": {
"debug": false,
"args": [],
"preRun": "init",
"aggregateBackfill": {
"enabled": "auto",
"wait": true,
"batchSize": 1000,
"pollIntervalMs": 1000,
"timeoutMs": 900000,
"strict": false
},
"migrations": {
"enabled": "auto",
"wait": true,
"batchSize": 256,
"pollIntervalMs": 1000,
"timeoutMs": 900000,
"strict": false,
"allowDrift": true
}
},
"codegen": {
"debug": false,
"scope": "all",
"args": []
},
"deploy": {
"args": [],
"aggregateBackfill": {
"enabled": "auto",
"wait": true,
"batchSize": 1000,
"pollIntervalMs": 1000,
"timeoutMs": 900000,
"strict": true
},
"migrations": {
"enabled": "auto",
"wait": true,
"batchSize": 256,
"pollIntervalMs": 1000,
"timeoutMs": 900000,
"strict": true,
"allowDrift": false
}
}
}
}
}Precedence:
- CLI flags override config values.
- Config
dev.args/codegen.args/deploy.argsare prepended to CLI passthrough args. - If
codegen.scopeis missing, it defaults toall. - Plugin lockfile path is fixed at
<functionsDir>/plugins.lock.json.
If no config file is found, defaults are used silently. If only kitcn.json exists, the CLI exits with a legacy-config error. If --config points to a missing file, the CLI exits with an error.