calcom/cal.com
Development workflow
How to move from git pull to a green PR.
The hot loop
yarn dev # Web app on http://localhost:3000
yarn dev:api # Web + apps/api/v2 on http://localhost:5555
yarn dev:website # Web + the marketing website
yarn db-studio # Prisma Studio on http://localhost:5555
yarn tdd # Vitest watch modeyarn dev translates to turbo run dev --filter="@calcom/web". Turbo's pipeline lives in turbo.json. Cache hits depend on inputs declared per task — when in doubt, yarn turbo run <task> --force to bypass the cache.
Schema changes
# 1. Edit packages/prisma/schema.prisma
# 2. Create the migration
yarn workspace @calcom/prisma prisma migrate dev --name <descriptive-name>
# 3. Regenerate client + zod types + kysely types
yarn workspace @calcom/prisma prisma generate
# 4. Update types in seed + tests
yarn workspace @calcom/prisma db-deploy # apply on CIThree generators run from one schema (see packages/prisma/schema.prisma):
prisma-client—packages/prisma/generated/prismazod-prisma-types—packages/prisma/zodprisma-kysely—packages/kysely/types.ts
Forgetting prisma generate after a schema change is the most common cause of "missing enum/type" errors (AGENTS.md says: "Run yarn prisma generate if you see missing enum/type errors").
App Store changes
Anything under packages/app-store/<provider> requires a regeneration of the app registry:
yarn app-store-cli # interactive create / edit / delete
yarn create-app # alias for app-store create
yarn edit-app # alias for app-store edit
yarn delete-app # alias for app-store delete
yarn app-store:build # rebuild registriesThe CLI source is packages/app-store-cli. It walks packages/app-store/*, reads each config.json and _metadata.ts, and writes *.generated.ts files (e.g., packages/app-store/apps.metadata.generated.ts, apps.server.generated.ts, bookerApps.metadata.generated.ts). These files must never be hand-edited (AGENTS.md Don'ts list).
Git hooks
Husky is installed via package.json postinstall:
"postinstall": "husky install && turbo run post-install"The hooks live in .husky/. The pre-commit hook runs lint-staged, which is configured by lint-staged.config.mjs and biome-staged.json. Lint-staged by default runs Biome on changed .ts/.tsx/.js/.jsx files.
Branching and stacked PRs
AGENTS.md strongly recommends:
- <500 lines of code change per PR
- <10 code files per PR
- Single responsibility per PR
- Schema changes, backend logic, and UI in separate PRs
The Cal.com bot ecosystem (kodiak[bot]) is tuned for small, focused PRs.
Conventional commits
Subject line format:
<type>(<scope>): <description>Common types: feat, fix, refactor, chore, docs, test, cleanup. Recent log examples:
feat(workflows): allow per-event-type opt-out
fix(event-types): align URL prefix with input text baseline
cleanup(test): remove org booking integration coverage
refactor: remove dead workflow runtime configi18n strings
User-facing strings live in packages/i18n/locales/en/common.json (and per-locale siblings). The web app's translations are mirrored to apps/web/public/static/locales/en/common.json. The script i18n.json and the GitHub Actions workflow .github/workflows/i18n.yml handle propagation. Run i18n-unused (configured by i18n-unused.config.js) to catch dead keys.
Run a single test fast
TZ=UTC yarn vitest run path/to/file.test.ts
TZ=UTC yarn vitest run -t "specific test name"The TZ=UTC is intentional — many tests assume UTC because Day.js timezone behavior is otherwise machine-dependent. The root setupVitest.ts configures shared mocks; per-package setup lives in vitest.config.mts and vitest.workspace.ts.
Specs (opt-in)
For substantial features the team uses a spec workflow described in SPEC-WORKFLOW.md. Specs live under specs/. To opt in, you tell the AI/reviewer "use spec-driven development" — there's no enforcement, just a shared process for capturing intent before code.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.