Skip to content
STACK IT FAST

Cal.com

Curated OSSClassicScheduling SaaS6-20 people

Audited from github.com/calcom/cal.com

Cal.com is an open-source scheduling infrastructure platform: a Next.js/React booking app and app-store of calendar, video, and payment integrations, backed by a separate NestJS Platform API for programmatic access.

Language
TypeScript
Database
PostgreSQL
Hosting
Docker
License
MIT
Running for
3 years 2 months
Team
6-20 people

Why this architecture

Splitting the tRPC-based web app from an independently versioned NestJS Platform API lets Cal.com serve both its own product and third-party developers from one monorepo, while Turborepo and per-integration app-store packages keep dozens of calendar/payment providers buildable and testable in isolation.

Tech stack by layer

12 technologies · audited Sep 17, 2026
Frontend & UI
  • Next.jsPowers the main booking web app in apps/web, built and started via next build / next start.
  • ReactComponent model for the web app and the embeddable booking widgets in packages/embeds.
  • Tailwind CSSUtility CSS used across the web app and shared UI packages, referenced by the repo topics.(inferred)
  • tRPCTyped client-server API calls between the Next.js app and its backend, defined in packages/trpc.
Backend & APIs
  • NestJSFramework for the standalone Platform API (apps/api/v2), separate from the Next.js app.
  • tRPCServer-side procedures backing the web app, built with the @calcom/trpc workspace package.
  • BullMQRedis-backed job queue used by the Platform API via @nestjs/bull for async/background work.
  • PrismaORM and migration tool for the shared @calcom/prisma package used by both the web app and API v2.
Data & Persistence
  • PostgreSQLPrimary relational database, referenced directly in docker-compose.yml and required by the Dockerfile build args.
  • RedisUsed for caching and as the BullMQ queue backend, wired into docker-compose.yml for local development.
  • KyselyTyped SQL query builder used by the shared @calcom/kysely workspace package alongside Prisma.
Infrastructure & Deploy
  • TurborepoOrchestrates builds, tests, and dev servers across the yarn workspace monorepo.
  • DockerMulti-stage Dockerfile builds a standalone Next.js production image for self-hosting.
  • GitHub ActionsRuns the extensive CI matrix: type checks, unit/e2e/embed tests, bundle analysis, and Docker release builds.

Cal.com architecture diagram

Open SVG
Cal.com architecture diagramBooking app → tRPC server (tRPC); Embeds → Booking app (embed); Platform clients → API v2 (REST); tRPC server → PostgreSQL (Prisma); API v2 → PostgreSQL (Prisma); API v2 → Redis (enqueue); Redis → Background jobs (jobs); tRPC server → Integrations (app-store)CLIENTSSERVICESWORKERS & JOBSDATA & STORAGEEXTERNALBooking appNext.js · ReactEmbedsbooking widgetsPlatform clientsRESTtRPC serverpackages/trpcAPI v2NestJSBackground jobsBullMQPostgreSQLPrisma · KyselyRediscache · queueIntegrationscalendars · video · paymentsembedtRPCRESTjobsPrismaPrismaenqueueapp-store
How the main components of Cal.com connect, drawn from the audited repository.
Diagram as text
  • Booking app (Next.js · React) → tRPC server (packages/trpc): tRPC
  • Embeds (booking widgets) → Booking app (Next.js · React): embed
  • Platform clients (REST) → API v2 (NestJS): REST
  • tRPC server (packages/trpc) → PostgreSQL (Prisma · Kysely): Prisma
  • API v2 (NestJS) → PostgreSQL (Prisma · Kysely): Prisma
  • API v2 (NestJS) → Redis (cache · queue): enqueue
  • Redis (cache · queue) → Background jobs (BullMQ): jobs
  • tRPC server (packages/trpc) → Integrations (calendars · video · payments): app-store

Key architectural decisions

7 decisions
  1. 01

    A single Yarn/Turborepo monorepo houses the web app, API, and app-store integrations

    The root package.json workspaces field lists apps/*, apps/api/*, packages/*, packages/app-store, packages/app-store/*, and example-apps/*, and turbo.json defines the shared build/test/dev pipeline across all of them.

  2. 02

    The Platform API is a separate NestJS service, not part of the Next.js app

    apps/api/v2/package.json builds with nest build and depends on @nestjs/common, @nestjs/core, and @nestjs/swagger, giving Cal.com a documented, independently deployable REST API distinct from the tRPC procedures used internally by apps/web.

  3. 03

    Two ORMs coexist: Prisma for the main schema, Kysely for typed raw queries

    packages/prisma is the schema-of-record used across the monorepo (referenced from apps/api/v2/package.json), while packages/kysely/package.json adds kysely and pg directly, giving performance-sensitive code paths a typed query builder without going through the Prisma client.

  4. 04

    Each of the ~30+ calendar/payment/video integrations ships as its own workspace package

    packages/app-store/* contains one package.json per integration (for example packages/app-store/applecalendar, packages/app-store/dailyvideo, packages/app-store/btcpayserver), each independently versioned and built through packages/app-store-cli.

  5. 05

    The self-hosted Docker image is built as a Next.js standalone production bundle

    The root Dockerfile prunes the workspace with npx turbo prune --scope=@calcom/web --scope=@calcom/trpc --docker, builds the tRPC and embed packages first, then runs the Next.js build with BUILD_STANDALONE=true before a second minimal runtime stage.

  6. 06

    Background jobs on the Platform API run through BullMQ on Redis

    apps/api/v2/package.json depends on @nestjs/bull and @nest-lab/throttler-storage-redis, giving the NestJS API both a Redis-backed job queue and Redis-backed rate limiting.

  7. 07

    The open-source Docker distribution is a separate product line, cal.diy

    docker-compose.yml pulls the image calcom.docker.scarf.sh/calcom/cal.diy and app.json (the Heroku one-click deploy manifest) is titled "Cal.diy", distinguishing the self-hosted Docker/Heroku path from the hosted cal.com service.

How Cal.com is built

How Cal.com is structured

Cal.com is a Yarn/Turborepo monorepo. The root package.json workspaces field spans apps/*, apps/api/*, packages/*, packages/features/*, packages/app-store and its subpackages, packages/platform/*, and example-apps/*; turbo.json defines the shared build, dev, and test pipeline and an unusually large globalEnv list reflecting the number of third-party integrations configured through environment variables. The two deployable apps are apps/web (the Next.js booking product) and apps/api/v2 (the standalone Platform API), with dozens of shared packages (packages/trpc, packages/prisma, packages/kysely, packages/lib, packages/features, packages/emails) consumed by both.

Frontend

apps/web/package.json is a Next.js application (built with next build --turbopack in dev) that calls its backend through tRPC (@calcom/trpc) rather than plain REST for most internal data fetching. Embeddable booking widgets are separate published packages (@calcom/embed-core, @calcom/embed-react, @calcom/embed-snippet, built via the publish-embed script), letting third-party sites embed Cal.com's booker outside the main app. Auth in the web app is layered with @boxyhq/saml-jackson for SAML SSO. Linting on apps/web runs through Biome (biome lint .) rather than ESLint, while type checking uses tsc --pretty --noEmit (and tsc-absolute in CI).

Backend & APIs

Two distinct backend surfaces exist. Internally, apps/web calls tRPC procedures defined in packages/trpc, giving end-to-end TypeScript types without a separate API contract. Externally, apps/api/v2 is a NestJS 10 application (nest build, @nestjs/common, @nestjs/core, @nestjs/swagger for generated API docs) that exposes a versioned, documented REST Platform API, built and deployed independently from the web app per its own production-build-without-database.yml and api-v2-production-build.yml CI workflows. The API v2 service depends on @nestjs/bull and @nest-lab/throttler-storage-redis, giving it a BullMQ job queue and Redis-backed rate limiting that the Next.js app does not need directly.

Data & persistence

PostgreSQL is the system of record, declared as the database service in docker-compose.yml and required as a build arg (DATABASE_URL) in the root Dockerfile. Prisma (packages/prisma, consumed via @calcom/prisma: workspace:* in apps/api/v2/package.json) is the primary ORM and migration tool, run through db-deploy and db-seed Turborepo tasks. A second, smaller data-access layer, packages/kysely/package.json, wraps kysely and the pg driver directly for typed queries that bypass the Prisma client. Redis, present in docker-compose.yml, backs both caching and the BullMQ queue used by API v2.

Build, test & deploy

CI is extensive: check-types.yml, unit-tests.yml, integration-tests.yml, e2e.yml, e2e-api-v2.yml, e2e-embed.yml, e2e-atoms.yml, performance-tests.yml, nextjs-bundle-analysis.yml, and check-prisma-migrations.yml all run as separate GitHub Actions workflows, alongside a release-docker.yaml workflow that builds and publishes the Docker image. atoms-production-build.yml and api-v2-production-build.yml validate that the Platform API and its consumable "atoms" package build cleanly outside the full monorepo context. Cron-triggered workflows (cron-bookingReminder.yml, cron-scheduleEmailReminders.yml, cron-syncAppMeta.yml, and others) run scheduled application jobs directly as GitHub Actions rather than through an in-app scheduler.

Self-hosting notes

The root Dockerfile builds a standalone Next.js production image: it prunes the workspace with npx turbo prune --scope=@calcom/web --scope=@calcom/trpc --docker, builds the tRPC and embed-core packages, copies app-store static assets, then runs next build with BUILD_STANDALONE=true before a second, minimal runtime stage. docker-compose.yml wires this image to Postgres and Redis containers for local self-hosting, using the published calcom.docker.scarf.sh/calcom/cal.diy image by default. app.json provides a one-click Heroku deploy for the same "Cal.diy" self-hosted distribution, requiring only a Postgres add-on and the app's encryption/auth secrets.

What to copy (and what not to)

Separating the Platform API (NestJS, independently versioned, Swagger-documented) from the internal tRPC layer used by the Next.js app is a good pattern once a product needs both a fast internal iteration loop and a stable public contract for third parties — building both on one shared Prisma schema (packages/prisma) keeps them consistent without duplicating models. Splitting every third-party integration into its own workspace package under packages/app-store/* scales well for a large integration surface, though it does mean turbo.json's globalEnv list has grown to dozens of provider-specific environment variables that any self-hoster has to sift through. Running Prisma and Kysely side by side is a pragmatic way to get typed raw SQL where the ORM's overhead matters, but it does introduce two query-building conventions a new contributor has to learn.

Sources & repo audit

Audited
Sep 17, 2026
Commit
6bc4529
License
MIT

Independent analysis of repository at github.com/calcom/cal.com. Spotted an inaccuracy? Use the claim form to request a correction.

Show this stack on your README or website
Tech stack of Cal.com
[![Tech stack of Cal.com on STACK IT FAST](https://stackitfast.com/badge/cal-com.svg)](https://stackitfast.com/project/cal-com)

Paste it into your README. It shows your current stack and links to this page.

Use this stack

Scaffold it with your agent

Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Cal.com's architecture.

  1. 1Copy the promptThe full markdown spec, with every layer and decision.
  2. 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
  3. 3Paste and scaffoldUse it as the first instruction; review before you ship.
use-this-stack.md · 61 lines · 8.0 KB
# MISSION: Scaffold "Cal.com" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Cal.com**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Cal.com
- **What It Does**: Cal.com is an open-source scheduling infrastructure platform: a Next.js/React booking app and app-store of calendar, video, and payment integrations, backed by a separate NestJS Platform API for programmatic access.
- **Domain & Category**: Scheduling SaaS
- **Production Scale**: 6-20 people
- **Development Mode**: CLASSIC
- **Architectural Rationale**: Splitting the tRPC-based web app from an independently versioned NestJS Platform API lets Cal.com serve both its own product and third-party developers from one monorepo, while Turborepo and per-integration app-store packages keep dozens of calendar/payment providers buildable and testable in isolation.
- **Live Website Reference**: https://cal.com
- **Source Repository**: https://github.com/calcom/cal.com
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: TypeScript, Next.js, React, PostgreSQL, Prisma, tRPC, NestJS, Tailwind CSS, Turborepo, BullMQ, Redis, Docker
- **Primary Language(s)**: TypeScript, CSS, HTML
- **License of the reference repo**: MIT
- **Frontend**: Next.js — Powers the main booking web app in apps/web, built and started via next build / next start.; React — Component model for the web app and the embeddable booking widgets in packages/embeds.; Tailwind CSS — Utility CSS used across the web app and shared UI packages, referenced by the repo topics.; tRPC — Typed client-server API calls between the Next.js app and its backend, defined in packages/trpc.
- **Backend & APIs**: NestJS — Framework for the standalone Platform API (apps/api/v2), separate from the Next.js app.; tRPC — Server-side procedures backing the web app, built with the @calcom/trpc workspace package.; BullMQ — Redis-backed job queue used by the Platform API via @nestjs/bull for async/background work.; Prisma — ORM and migration tool for the shared @calcom/prisma package used by both the web app and API v2.
- **Data & persistence**: PostgreSQL — Primary relational database, referenced directly in docker-compose.yml and required by the Dockerfile build args.; Redis — Used for caching and as the BullMQ queue backend, wired into docker-compose.yml for local development.; Kysely — Typed SQL query builder used by the shared @calcom/kysely workspace package alongside Prisma.
- **Infrastructure & deploy**: Turborepo — Orchestrates builds, tests, and dev servers across the yarn workspace monorepo.; Docker — Multi-stage Dockerfile builds a standalone Next.js production image for self-hosting.; GitHub Actions — Runs the extensive CI matrix: type checks, unit/e2e/embed tests, bundle analysis, and Docker release builds.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/calcom/cal.com @ 6bc4529)
1. **A single Yarn/Turborepo monorepo houses the web app, API, and app-store integrations**: The root package.json workspaces field lists apps/*, apps/api/*, packages/*, packages/app-store, packages/app-store/*, and example-apps/*, and turbo.json defines the shared build/test/dev pipeline across all of them.
2. **The Platform API is a separate NestJS service, not part of the Next.js app**: apps/api/v2/package.json builds with nest build and depends on @nestjs/common, @nestjs/core, and @nestjs/swagger, giving Cal.com a documented, independently deployable REST API distinct from the tRPC procedures used internally by apps/web.
3. **Two ORMs coexist: Prisma for the main schema, Kysely for typed raw queries**: packages/prisma is the schema-of-record used across the monorepo (referenced from apps/api/v2/package.json), while packages/kysely/package.json adds kysely and pg directly, giving performance-sensitive code paths a typed query builder without going through the Prisma client.
4. **Each of the ~30+ calendar/payment/video integrations ships as its own workspace package**: packages/app-store/* contains one package.json per integration (for example packages/app-store/applecalendar, packages/app-store/dailyvideo, packages/app-store/btcpayserver), each independently versioned and built through packages/app-store-cli.
5. **The self-hosted Docker image is built as a Next.js standalone production bundle**: The root Dockerfile prunes the workspace with npx turbo prune --scope=@calcom/web --scope=@calcom/trpc --docker, builds the tRPC and embed packages first, then runs the Next.js build with BUILD_STANDALONE=true before a second minimal runtime stage.
6. **Background jobs on the Platform API run through BullMQ on Redis**: apps/api/v2/package.json depends on @nestjs/bull and @nest-lab/throttler-storage-redis, giving the NestJS API both a Redis-backed job queue and Redis-backed rate limiting.
7. **The open-source Docker distribution is a separate product line, cal.diy**: docker-compose.yml pulls the image calcom.docker.scarf.sh/calcom/cal.diy and app.json (the Heroku one-click deploy manifest) is titled "Cal.diy", distinguishing the self-hosted Docker/Heroku path from the hosted cal.com service.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
   - Structure as a Turborepo monorepo with strict package boundaries:
     - `apps/web`: Application UI, routing, layouts, and server endpoints.
     - `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
     - `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
     - `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
   - Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
   - Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
   - Utilize Next.js 15 App Router: default to React Server Components (RSC) for data fetching. Handle mutations through Server Actions with Zod validation. Keep 'use client' directives restricted strictly to interactive leaf components.
4. **Design System & Aesthetics**:
   - Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
   - Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
   - Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
   - Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (PostgreSQL, Redis, Kysely): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.
Scaffolded something with this prompt?
Would you pick this stack for a scheduling saas project?

Copied 2 times · 1 of 1 reported launches succeeded (100%)

Frequently asked about Cal.com

What is Cal.com built with?

Cal.com is a TypeScript Turborepo monorepo: a Next.js and React web app using tRPC and Prisma over PostgreSQL, plus a separate NestJS Platform API (apps/api/v2) with BullMQ on Redis for background jobs.

Does Cal.com use Prisma or a raw query builder?

Both. Prisma (packages/prisma) is the primary ORM and schema source, while packages/kysely adds Kysely with the pg driver for typed queries in performance-sensitive code paths.

Can I self-host Cal.com?

Yes, through the cal.diy Docker image and docker-compose.yml (Postgres plus Redis), a standalone Next.js build in the root Dockerfile, or the Heroku one-click deploy defined in app.json.

Is the Cal.com API built with tRPC or REST?

Both exist side by side: internal web app calls use tRPC (packages/trpc), while the public, independently versioned Platform API in apps/api/v2 is a NestJS REST service documented with @nestjs/swagger.

How does Cal.com handle integrations with calendars and payment providers?

Each integration is its own workspace package under packages/app-store/* (for example applecalendar, dailyvideo, btcpayserver), built and scaffolded through the packages/app-store-cli tool.

One email a month: new deep dives and stack trends

New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.

use-this-stack.md