Blocks

Blocks are production features you add with one command. Like shadcn/ui components, they are copied into your project as source code: you read them, own them and change them. There is no runtime package to keep up with.

Shell
npx calm add jobs
  Blocks
  + @calmapi/jobs v1.0.0 · @calmapi (bundled)
    Background jobs and cron on MongoDB (no Redis): retries with backoff, schedules, event triggers, admin API and a devtools panel.

  Files
  create    app/blocks/jobs/cron.js
  create    app/blocks/jobs/index.js
  create    app/blocks/jobs/queue.js
  create    app/jobs/welcome-email.js

  Environment (.env.example and .env)
  + JOBS_WORKER=on
  + JOBS_CONCURRENCY=4

? Apply these changes? [Y/n]

calm add writes the files, adds npm dependencies to package.json and installs them, appends environment variables to .env.example and .env (without touching values you already have), records the block in calm.lock, and prints the block's notes. Restart (or let npm run dev restart) and the block is live: every folder in app/blocks/ with an index.js is loaded at boot.

Official blocks#

BlockWhat you get
Users and access
api-keysPersonal and service API keys with scopes, hashed at rest, expiry and revoke
magic-linkPasswordless sign-in by email, bound to the browser that asked
totpTwo-factor authentication with authenticator apps, recovery codes and replay protection
privacyUsers export their data and delete their account (delete, anonymize or keep per resource)
Messaging
notificationsctx.notify(): in-app inbox, push and email in one call, with preferences and quiet hours
push-expo / push-fcmPush notification delivery through Expo or Firebase Cloud Messaging, alone or together
mail-resend / mail-smtpEmail delivery
webhooksOutgoing webhooks for resource events: signed, retried, logged, SSRF safe
realtime-sseLive resource events, filtered per subscriber by the same policies
Data and files
storage-localUploads to disk with type and size allowlists, magic-byte checks and safe downloads
storage-s3Direct-to-S3 uploads with presigned URLs (AWS S3, Cloudflare R2, MinIO)
audit-logWho changed what, with field diffs (private values never logged)
soft-deletesoftDelete: true per resource, with trash and restore
Running in production
jobsMongoDB job queue and cron (no Redis): retries, schedules, event triggers, admin API
feature-flagsKill switches, gradual rollouts, targeting, variants and route gates
idempotencyThe Idempotency-Key header: safe retries for payments and other writes
rate-limit-mongoRate limits shared across instances
APIs and agents
api-docsInteractive API reference at /docs
mcp-serverYour resources as MCP tools for AI agents, enforced by your API's rules
Shell
npx calm add --list                 # official blocks
npx calm add jobs audit-log         # several at once
npx calm add jobs --dry-run         # show the plan, write nothing
npx calm block list                 # blocks in this project, and the files you changed

The devtools Blocks panel shows every installed block: where it came from, the files you changed since, what it hooks into, its environment variables (set or missing) and its routes.

Where blocks come from#

An address is resolved like this:

AddressSource
jobs or @calmapi/jobsThe official registry. The CLI carries a copy of it, so this works offline. --remote fetches https://docs.calmapi.dev/r/jobs.json instead.
gh:acme/blocks/billingr/billing.json in a GitHub repository, what calm block pack writes. Add @v1.2.0 (or a branch or commit) to pin it.
@acme/billingThe @acme registry declared in your package.json
https://example.com/r/thing.jsonAny URL
./blocks/thing.jsonA local file

Registries are declared in package.json:

JSON
{
  "calm": {
    "registries": { "@acme": "https://acme.dev/r/{name}.json" }
  }
}

The official registry is served as JSON at https://docs.calmapi.dev/r/index.json, one file per block (for example /r/jobs.json), in the shadcn registry-item format. To write and share your own, see Building your own block and Publishing your own block.

Safety rules#

  • A block can only write inside your project, never to calm/ or calm.lock.
  • Existing files with different content are kept and reported as conflicts; pass --overwrite to replace them.
  • Blocks that provide the same resource refuse to be installed together (storage-local and storage-s3 both provide file).
  • registryDependencies are installed first; dependencies already in package.json are left as they are.
  • Blocks can declare the oldest CalmAPI they work with (minVersion); older projects are asked to run calm upgrade first.
  • Blocks that are not official are reviewed before anything is written: calm add lists in plain language what their code does (network requests, file writes, child processes, eval, request hooks, the environment variables it reads, the hosts it mentions). Risky findings must be confirmed, and with --yes they also need --trust. A block runs in your app with full access, like any code you paste, so read it. See What people see before installing.

After adding a block#

The block's code is now in your project, and it is yours. Change it, delete parts you do not need, or remove the block by deleting its folder (and its entry in calm.lock). Re-running calm add <block> later shows which files differ from the current upstream version. calm upgrade never touches block files.