Cal.com is an open‑source scheduling platform that lets developers embed booking experiences directly into apps. This guide walks you through the core concepts, initial setup, typical workflows, advanced patterns, and the pitfalls most teams encounter. By the end you will have a working Cal.com instance and a clear roadmap for extending it.
Cal.com consists of three main layers: the API server, the React front‑end, and the data store. The API follows a REST‑plus‑GraphQL hybrid, exposing endpoints for events, users, and integrations. The front‑end renders booking pages using React components that call the same API. All data lives in PostgreSQL, which stores users, event types, availability rules, and webhook logs.
Key concepts you’ll use daily:
The fastest way to start is the official Docker compose file. It runs the API, web UI, and PostgreSQL in three containers.
git clone https://github.com/calcom/cal.com.git && cd cal.com
cp .env.example .env
.env:
DATABASE_URL=postgresql://cal:cal@postgres:5432/calNEXT_PUBLIC_WEBAPP_URL=http://localhostNEXTAUTH_SECRET to a 32‑byte random string (e.g., openssl rand -hex 16).docker compose up -d
docker compose exec web npm run prisma:migrate
http://localhost and create the first admin user.| Feature | Cal.com SaaS | Self‑Hosted |
|---|---|---|
| Pricing | $12‑$30 per active user / month | Free (hosting cost only) |
| Updates | Automatic | Manual (docker pull & restart) |
| Support | 24/7 email & chat | Community‑only unless you buy a support plan |
| Custom Domain | Included | Fully controllable |
| Data Residency | US/EU zones | Anywhere you host |
| Scalability | Managed auto‑scale | Depends on your infra (K8s, ECS, etc.) |
In the admin UI go to Event Types → New. Fill the form:
Save. The system generates a public URL like https://cal.com/yourteam/demo.
https://yourdomain.com/api/auth/callback/google.Cal.com can POST JSON to any endpoint when a booking occurs. Set the webhook URL in Settings → Webhooks. Example payload:
{
"event_type":"booking.created",
"payload":{
"id":"bk_01F8Z3",
"start":"2026-07-01T14:00:00Z",
"end":"2026-07-01T14:30:00Z",
"user":{"id":"usr_123","email":"dev@company.com"},
"metadata":{"custom_field":"value"}
}
}
Validate the signature header using the secret you configured.
Use the script tag provided by Cal.com or render the React component directly.
<script src="https://cal.com/embed.js"></script> <div data-cal-link="yourteam/demo"></div>
For React projects:
import { BookingPage } from '@calcom/ui';
function Demo() { return <BookingPage eventType="demo" />; }
Default rules are static. For dynamic availability (e.g., block holidays from an external API) use the availability webhook. Return a JSON array of { start, end } intervals. Cal.com will merge these with the static rules.
Cal.com supports a “team” model out of the box. To turn it into a full SaaS product:
TEAM_MODE=true in .env.tenantResolver that maps subdomains (acme.cal.com) to team IDs.getServerSideProps.Next.js supports SSR out of the box. Create pages/[team]/[slug].tsx and fetch the event type with getServerSideProps. This improves SEO for public calendars.
When traffic exceeds a few hundred bookings per minute, move to K8s:
docker build -t yourrepo/cal.com:latest .replicas: 3 and a HorizontalPodAutoscaler targeting CPU > 70%.npm run env:check before deployment.NEXTAUTH_SECRET is “secret”. Replace it with a cryptographically strong value.SaaS runs on Cal.com’s servers, includes automatic updates and support, and costs $12‑$30 per month per active user. Self‑hosted runs on your own infrastructure, you manage updates and scaling, but you avoid recurring fees. The self‑hosted Docker image starts at $0, plus hosting costs.
Cal.com officially supports PostgreSQL 13‑15. SQLite works for local testing but is not recommended for production because it lacks clustering and robust backup features.
Create a Google Cloud project, enable the Google+ API, generate OAuth client ID and secret, then add them in the Cal.com admin UI under Settings → Integrations → Google Calendar. Set redirect URL to https://your‑domain.com/api/auth/callback/google.
Yes. Cal.com exposes a React component library. You can replace the default <BookingPage/> with your own component, or override CSS variables via the theme-config.json file. The UI is built with Tailwind, so you can add any Tailwind class.
Skipping environment variable validation, running the app without a reverse proxy, and using default secrets in production are frequent errors. Always set NODE_ENV=production, configure HTTPS termination, and rotate all JWT secrets before launch.
---
With this guide you should be able to install Cal.com, create booking flows, and extend the platform for your own product. Start small, test each integration, and iterate. The open‑source community updates the code weekly, so keep an eye on the GitHub releases for security patches and new features.