1.225 Meeting Scheduling Libraries#
Research into open-source and self-hostable meeting scheduling tools and libraries – the Calendly/Doodle alternative space. Covers scheduling link platforms (cal.com, Easy!Appointments), poll-based group scheduling (Rallly, schej.it), minimal scheduling link libraries, and CalDAV scheduling protocol support (RFC 6638, iMIP, iTIP).
Focus on what developers can pip/npm install or docker-compose up, not pure SaaS products. Key questions: when to use cal.com vs build your own, what is the minimum viable scheduling link, how OSS tools integrate with Google/Outlook/ iCloud, and what self-hosting requires.
Key finding: The meeting scheduling space bifurcates into two fundamentally different approaches – slot-based (Calendly-style, one person publishes availability) and poll-based (Doodle-style, group votes on times). cal.com dominates the slot-based OSS space with 35K+ GitHub stars and full-stack infrastructure. Poll-based scheduling has Rallly as the clear OSS leader. Building from scratch is viable only for narrow use cases; cal.com’s embed and API make it the pragmatic choice for most developers.
Explainer
Meeting Scheduling: Domain Explainer#
What Problem Does This Solve?#
You want to meet with someone. You send an email: “How about Tuesday at 2pm?” They reply Wednesday: “Tuesday doesn’t work, how about Thursday?” You reply Thursday: “Thursday is fine, but only after 3pm.” They reply Friday: “Let’s do next Monday instead.”
Five days to schedule a 30-minute meeting. Multiply by every meeting in an organization, and scheduling becomes a silent tax on productivity. Studies estimate knowledge workers spend 4-5 hours per week just coordinating meeting times.
Meeting scheduling software automates this negotiation. You publish your availability. Someone picks a slot. The meeting appears on both calendars. Done.
But “publish availability and let someone pick a slot” hides a surprising amount of complexity – timezone conversion, recurring availability patterns, buffer time between meetings, calendar provider integration, booking confirmation, cancellation flows, and the fundamental question of whether you are scheduling a 1-on-1 or trying to find a time that works for a group.
The Hardware Store Analogy#
Imagine you need to build an automated gate for your driveway. You could:
Buy a complete gate system (motor, controller, remote, sensors, installation guide). This is cal.com or Easy!Appointments – a full platform you deploy and configure. Works great if the gate fits your driveway. Expensive to customize if it does not.
Buy components and assemble (motor from one vendor, controller from another, write your own automation logic). This is building on tsdav, icalendar, and calendar APIs – more work, but you control every aspect.
Hire a gate service that installs and maintains everything for a monthly fee. This is Calendly, SavvyCal, or Zcal – SaaS products where you pay for convenience and give up control.
Ask your neighbors to vote on what kind of gate to install. This is Rallly or schej.it – poll-based group scheduling where the answer emerges from collective input rather than one person’s availability.
The hardware store sells components for options 1 and 2. This research focuses on those options – what a developer can install, self-host, and integrate.
Two Fundamentally Different Problems#
Meeting scheduling looks like one problem but is actually two:
Slot-Based Scheduling (Calendly Model)#
One person (the host) publishes available time slots. Another person (the guest) picks one. The interaction is asymmetric – the host sets the rules, the guest chooses within them.
Use cases: Sales calls, office hours, customer support, interviews, consultations, tutoring sessions. One party controls the schedule.
Technical requirements: Calendar integration (read the host’s busy times), availability rules (work hours, buffer time, minimum notice), booking engine (reserve the slot, send confirmations), embed/widget for websites.
Poll-Based Scheduling (Doodle Model)#
A group of people need to find a time that works for everyone. There is no host – everyone votes on proposed times, and the organizer picks the winner.
Use cases: Team meetings, committee scheduling, social events, club meetings. No single party controls the schedule.
Technical requirements: Propose times, collect votes, display overlap, handle timezone differences across voters, optionally integrate with participants’ calendars.
These two approaches require different architectures, different UIs, and different libraries. No single tool does both well.
What Makes It Hard#
The Calendar Provider Maze#
To check if someone is free, you need to read their calendar. But calendars live in different systems:
| Provider | Protocol | Auth |
|---|---|---|
| Google Calendar | Google Calendar API (REST) | OAuth 2.0 |
| Microsoft Outlook | Microsoft Graph API (REST) | OAuth 2.0 |
| Apple iCloud | CalDAV (WebDAV extension) | App-specific password |
| Fastmail, Nextcloud | CalDAV | Basic auth or OAuth |
| Arbitrary ICS feeds | HTTP GET on .ics URL | None (public) or basic auth |
There is no single protocol that covers all providers. Google technically supports CalDAV but with limitations. Microsoft does not support CalDAV at all. Every scheduling tool must implement multiple integrations or use a commercial aggregator (Nylas, Cronofy) that abstracts the differences.
Timezone Complexity#
A scheduling link that says “available 9am-5pm” seems simple until the host is in New York, the guest is in Tokyo, and the guest is looking at the scheduling page at 2am their time. The page must:
- Convert the host’s availability to the guest’s timezone
- Handle daylight saving time transitions (a slot that exists today might not exist next week due to DST)
- Handle “floating” times (all-day events with no timezone)
- Display times in the guest’s local timezone while booking in the host’s
Recurring Availability vs. One-Off Overrides#
“Available Monday through Friday, 9am-5pm” is a recurring pattern. But what about holidays? What about the afternoon blocked for a dentist appointment? The scheduling engine must layer:
- Base availability pattern (recurring)
- Calendar busy times (from connected calendars)
- Manual overrides (“block off next Friday”)
- Buffer rules (“30 minutes between meetings”)
Getting this layering wrong means double-bookings or phantom availability.
The Booking Race Condition#
Two people view the same scheduling page and see 2pm as available. Both click to book 2pm at nearly the same time. Only one booking can succeed. This is a concurrency problem that requires atomic reservation – checking availability and creating the booking must happen as one operation.
The Standards (Mostly Theoretical)#
The calendar standards world has protocols for scheduling:
| Standard | Purpose | Real-World Adoption |
|---|---|---|
| RFC 6638 (CalDAV Scheduling) | Server-mediated meeting invitations via CalDAV | Low – major providers use proprietary APIs |
| RFC 5546 (iTIP) | Transport-independent scheduling protocol | Used internally by servers, rarely by client code |
| RFC 6047 (iMIP) | Email-based meeting invitations | Universal – every “Accept/Decline” email uses this |
| VFREEBUSY (part of RFC 5545) | Machine-readable free/busy data | Supported but rarely used outside enterprise |
The irony: comprehensive scheduling standards exist but are largely ignored by the major providers. Google and Microsoft use their own REST APIs. iMIP (email-based invitations) is the only universally adopted scheduling standard – and most developers interact with it through higher-level libraries rather than implementing it directly.
Who Needs This?#
- SaaS builders adding scheduling to their product (most common)
- Freelancers/consultants wanting a self-hosted Calendly alternative
- Service businesses (salons, clinics, tutors) needing appointment booking
- Team leads organizing recurring group meetings
- Event organizers coordinating across many participants
- Privacy-conscious users who want scheduling without giving data to SaaS
The Current State (2026)#
Slot-based scheduling is dominated by cal.com (35K+ GitHub stars, VC-funded, 600+ contributors). It is the PostgreSQL of meeting scheduling – open source, battle-tested, with a commercial company ensuring long-term development. For most developers, the question is not “which library?” but “can I use cal.com?”
Poll-based scheduling has Rallly as the clear OSS leader (3.6K stars, clean Next.js codebase, Docker self-hosting).
Building from scratch makes sense only when cal.com’s architecture does not fit your constraints (wrong tech stack, need deep UI customization, or AGPL is incompatible with your licensing). Even then, cal.com’s embed widget and API often suffice.
Calendar API aggregation (Nylas, Cronofy) fills the gap between “build everything yourself” and “use a full platform.” These commercial services provide unified APIs across Google, Outlook, and iCloud, letting you build custom scheduling UI without implementing three different calendar integrations.
The biggest remaining gap in the ecosystem is a lightweight, embeddable scheduling component library – something between “use cal.com’s entire stack” and “build everything from scratch with CalDAV libraries.” A React component that handles availability display and booking with pluggable calendar backends does not yet exist as a standalone OSS project.
What to Read Next#
If you have decided you need meeting scheduling in your project:
S1 (Rapid Discovery) surveys the tools: cal.com, Easy!Appointments, Rallly, schej.it, CalDAV scheduling protocol support, and calendar API aggregators. Start here to understand what exists.
S2 (Comprehensive Analysis) goes deep on architecture: how cal.com’s availability engine works, what building a minimal scheduling link requires, and how CalDAV scheduling protocol operates.
S3 (Need-Driven Discovery) maps six personas to specific tools: indie SaaS developer, freelancer, service business, team lead, privacy- conscious developer, and enterprise IT admin. Find your persona and follow its recommendation.
S4 (Strategic Discovery) assesses long-term viability: which projects will still exist in 3-5 years, what ecosystem trends are reshaping the space, and how to choose a strategic path based on your risk tolerance.
S1: Rapid Discovery
cal.com (formerly Calendso) - Rapid Assessment#
Identity#
| Field | Value |
|---|---|
| Name | cal.com |
| Previous name | Calendso |
| Repository | github.com/calcom/cal.com |
| Stars | ~35,000 |
| Contributors | 600+ |
| License | AGPL-3.0 (with commercial license available) |
| Language | TypeScript, Next.js, Prisma |
| First release | 2021 |
| Last active | 2026 (weekly releases) |
| Funding | VC-backed (Series A, $25M+) |
What It Does#
cal.com is a full-stack scheduling platform – the open-source Calendly. It provides everything needed to create scheduling links, display availability, accept bookings, and manage calendar integrations. Self-hostable via Docker or deployable on Vercel/Railway.
Core Features#
- Scheduling links: Create booking pages with custom availability
- Event types: One-on-one, round-robin, collective (all hosts must attend), managed event types (admin-controlled templates)
- Calendar integration: Google Calendar, Outlook (via Microsoft Graph), Apple Calendar, CalDAV (generic), ICS feeds
- Video conferencing: Zoom, Google Meet, Microsoft Teams, Daily.co, Jitsi
- Embed widget: React component for embedding scheduling in any website
- Workflow automation: Pre/post-booking actions (email, webhook, SMS)
- API: Full REST API for programmatic scheduling
- Team scheduling: Round-robin assignment, collective scheduling, managed event types
- Payments: Stripe integration for paid bookings
- Routing forms: Direct bookers to the right person/event type
Stack Requirements (Self-Hosted)#
- Node.js 18+
- PostgreSQL 15+
- Redis (for job queues)
- SMTP server (for email notifications)
- OAuth credentials for each calendar provider
- Recommended: 2+ GB RAM, dedicated host or container
What It Costs#
- Self-hosted (AGPL): Free, but AGPL requires sharing modifications
- cal.com Cloud: Free for 1 event type, paid plans from $12/user/month
- Enterprise license: Custom pricing (removes AGPL, adds SSO, audit logs)
Strengths#
- Most complete OSS scheduling platform by a wide margin
- Active development with frequent releases
- Large contributor community (600+) reduces bus factor
- VC funding ensures sustained development
- Comprehensive calendar provider integrations
- Embed widget allows integration without full deployment
- API enables building custom UIs on top of cal.com’s backend
Weaknesses#
- Heavy: Full Next.js monorepo, complex to self-host compared to simpler tools
- AGPL license: Requires sharing modifications; incompatible with some commercial use cases without purchasing enterprise license
- PostgreSQL + Redis required: Nontrivial infrastructure for self-hosting
- Opinionated architecture: Hard to extract just the scheduling engine without the full UI
- VC-funded risk: Business model depends on converting OSS users to paid; license could change (though AGPL is irrevocable for released versions)
When to Use#
- You want a complete Calendly replacement (self-hosted or cloud)
- You need team scheduling (round-robin, collective)
- You want an embed widget for your existing website
- You have the infrastructure to run a Next.js + PostgreSQL + Redis stack
- AGPL is acceptable for your use case (or you purchase enterprise license)
When to Skip#
- You need a lightweight scheduling widget (cal.com is a full platform)
- Your stack is Python/PHP and you want native integration
- AGPL is incompatible with your licensing requirements
- You need deep UI customization beyond what theming allows
- Your scheduling needs are simple enough that a booking form + Google Calendar API call would suffice
Competitive Position#
cal.com is to scheduling what WordPress is to CMS – the dominant open-source option that most people should evaluate first. Its main competition is Calendly (SaaS, not self-hostable) and SavvyCal (SaaS, not self-hostable). In the OSS space, nothing comes close to its feature completeness or community size.
Market Signals#
- 35K+ GitHub stars (growing steadily)
- Used by companies including Product Hunt, Vercel, Railway
- Active Discord community with 5K+ members
- Regular conference talks and blog posts
- Y Combinator backed
- Acquired Hyper.so (scheduling infrastructure) in 2023
Easy!Appointments - Rapid Assessment#
Identity#
| Field | Value |
|---|---|
| Name | Easy!Appointments |
| Repository | github.com/alextselegidis/easyappointments |
| Stars | ~3,200 |
| Contributors | ~60 |
| License | GPL-3.0 |
| Language | PHP (CodeIgniter 3), JavaScript |
| First release | 2013 |
| Last active | 2026 |
| Funding | Community / donation-supported |
What It Does#
Easy!Appointments is a self-hosted appointment booking system designed for service businesses – think hair salons, medical practices, tutoring services, and consultancies. It provides a web-based booking page where customers select a service, a provider, and an available time slot.
Unlike cal.com (which models individual scheduling links), Easy!Appointments models the service business domain: services have durations and prices, providers have working hours, and customers book specific services with specific providers.
Core Features#
- Service catalog: Define services with name, duration, price, description
- Provider management: Multiple providers with individual schedules
- Customer booking: Public-facing page for self-service booking
- Working hours: Per-provider availability with break periods
- Google Calendar sync: Two-way sync with Google Calendar
- Email notifications: Configurable templates for booking/cancellation
- Admin panel: Manage bookings, customers, services, providers
- Multi-language: 30+ translations
- REST API: CRUD operations on all entities
- Customizable UI: CSS theming, basic layout options
Stack Requirements (Self-Hosted)#
- PHP 8.1+
- MySQL 5.7+ or MariaDB
- Apache or Nginx
- SMTP server (for notifications)
- Optional: Google Calendar API credentials
- Modest resources: runs on shared hosting
What It Costs#
- Free (GPL-3.0)
- No commercial license option
- No hosted/cloud version offered by the maintainers
Strengths#
- Lightweight: Runs on any PHP hosting (no Node.js, no Redis)
- Service-business model: First-class support for services, providers, and customers (domain model that cal.com lacks)
- Mature: 10+ years of development, stable codebase
- Easy deployment: Upload files, configure database, done
- Google Calendar sync: Two-way sync for provider calendars
- Low resource requirements: Runs on $5/month shared hosting
- API available: REST API for custom integrations
Weaknesses#
- Dated architecture: CodeIgniter 3 (no longer maintained by CI team), jQuery-based frontend
- Limited calendar integrations: Only Google Calendar (no Outlook, no iCloud, no CalDAV)
- No team scheduling: No round-robin, no collective scheduling
- No embed widget: Must link to the booking page (no iframe/component)
- No video conferencing integration: Manual coordination needed
- Single maintainer risk: Primary development by one person
- No workflow automation: No webhooks, no pre/post-booking actions beyond email
- GPL-3.0: Copyleft may be restrictive for commercial integrations
When to Use#
- You run a service business (salon, clinic, tutoring, consulting)
- You want the simplest possible self-hosted booking system
- Your hosting is PHP-based (shared hosting, cPanel, LAMP stack)
- You need only Google Calendar integration
- Budget is minimal – need free, self-hosted, low-maintenance
When to Skip#
- You need Calendly-style personal scheduling links
- You need Outlook or iCloud calendar integration
- You want modern frontend architecture (React, Vue)
- You need team scheduling features (round-robin, collective)
- You need video conferencing integration
- You want embed widgets for your website
Competitive Position#
Easy!Appointments occupies the “simple PHP booking system” niche. It competes with commercial products like Acuity Scheduling, SimplyBook.me, and Setmore rather than with Calendly or cal.com. Its strength is simplicity and low hosting requirements; its weakness is limited integrations and aging architecture.
Market Signals#
- 3.2K GitHub stars (slow, steady growth)
- Active in service business communities
- Frequently recommended in “self-hosted alternatives” lists
- Docker images available from community contributors
- Translations maintained by community in 30+ languages
- Development pace: modest but consistent (2-3 releases/year)
Rallly - Rapid Assessment#
Identity#
| Field | Value |
|---|---|
| Name | Rallly |
| Repository | github.com/lukevella/rallly |
| Stars | ~3,600 |
| Contributors | ~80 |
| License | AGPL-3.0 |
| Language | TypeScript, Next.js, Prisma |
| First release | 2016 (rewritten 2022) |
| Last active | 2026 |
| Funding | Community sponsorship + rallly.co hosted service |
What It Does#
Rallly is an open-source Doodle alternative for scheduling group meetings. The organizer proposes several dates/times, participants vote on which work for them, and the organizer picks the winner based on overlap.
Unlike slot-based tools (cal.com, Calendly), Rallly does not read anyone’s calendar or enforce availability. It is a voting system for time preferences.
Core Features#
- Poll creation: Propose multiple date/time options for a meeting
- Participant voting: Vote yes/maybe/no on each proposed time
- No account required: Participants can vote without creating an account
- Timezone support: Each participant sees times in their local timezone
- Comments: Discussion thread on each poll
- Notifications: Email updates when participants vote
- Self-hosting: Docker Compose with PostgreSQL
- Admin controls: Lock polls, set deadlines, finalize decisions
- Clean UI: Modern, responsive design
Stack Requirements (Self-Hosted)#
- Node.js 18+
- PostgreSQL
- SMTP server (for email notifications)
- Docker Compose (recommended deployment)
- Modest resources: 512MB RAM sufficient
What It Costs#
- Self-hosted (AGPL): Free
- rallly.co hosted: Free with limits, paid plans available
- No enterprise license option
Strengths#
- Purpose-built for group scheduling: Does one thing well
- No calendar integration needed: Participants vote without connecting calendars (lower friction)
- No account required for participants: Reduces adoption friction to zero
- Clean, modern codebase: Next.js + Prisma + TypeScript (same stack as cal.com)
- Self-hosting is simple: Docker Compose with minimal configuration
- Active development: Regular releases, responsive maintainer
- Timezone-aware: Automatic timezone conversion for participants
Weaknesses#
- No calendar integration: Cannot read participants’ calendars to pre-populate availability
- Poll-only model: Cannot create Calendly-style booking links
- Limited to date/time voting: No integration with video conferencing, no automatic calendar event creation after decision
- AGPL license: Same commercial-use concerns as cal.com
- Single-maintainer risk: Primary development by Luke Vella
- No API: No programmatic poll creation or management
- No recurring polls: Each scheduling decision requires a new poll
When to Use#
- You need to schedule group meetings (3+ people)
- Participants do not want to connect their calendars
- You want the simplest possible group scheduling experience
- You need a self-hosted Doodle alternative
- Low-friction participation is critical (no accounts required)
When to Skip#
- You need slot-based scheduling (use cal.com instead)
- You need calendar integration for availability checking
- You need automatic calendar event creation after booking
- You need an API for programmatic scheduling
- You need recurring/repeated scheduling workflows
Competitive Position#
Rallly is the most mature OSS Doodle alternative. It competes with Doodle (SaaS, freemium), When2meet (free but not self-hostable), Crab.fit (OSS, minimalist), and LettuceMeet (OSS, visual overlap). Its advantage is the combination of clean design, self-hosting support, and no-account-required participation.
Market Signals#
- 3.6K GitHub stars (steady growth since 2022 rewrite)
- Active community on GitHub Discussions
- Frequently listed in self-hosted alternatives directories
- rallly.co hosted service provides revenue for development
- 80+ contributors across the project
- Regular mentions in “Doodle alternatives” comparisons
schej.it - Rapid Assessment#
Identity#
| Field | Value |
|---|---|
| Name | schej.it |
| Repository | github.com/schej-it/schej.it |
| Stars | ~200 |
| Contributors | ~10 |
| License | MIT |
| Language | Vue.js (frontend), Node.js/Express (backend) |
| First release | 2022 |
| Last active | 2025 |
| Funding | Unfunded (student/hobby project) |
What It Does#
schej.it is a When2meet-style group availability tool. Participants mark their available times on a visual grid, and the tool overlays everyone’s availability to find common free times. Unlike Rallly (which uses voting on proposed times), schej.it shows continuous availability on a time grid.
Core Features#
- Visual availability grid: Drag to mark available time blocks
- Calendar import: Connect Google Calendar to pre-fill busy times
- Group overlay: See overlapping availability with color intensity
- Event creation: Create events with date ranges for participants
- No account required: Participants can contribute without signing up
- Timezone support: Converts between participant timezones
- Responsive design: Works on mobile devices
Stack Requirements#
- Vue.js frontend
- Node.js/Express backend
- MongoDB
- Google OAuth (for calendar integration)
- Firebase (for authentication)
What It Costs#
- Free and open source (MIT license)
- Hosted version at schej.it
Strengths#
- Visual approach: Intuitive drag-to-select availability grid
- Calendar integration: Google Calendar import reduces manual entry
- MIT license: Most permissive license in this category
- Familiar UX: When2meet paradigm is well-understood by users
- Simple mental model: Mark when you are free, see overlap
Weaknesses#
- Small project: ~200 stars, ~10 contributors
- Student project origins: May not receive long-term maintenance
- Google-only calendar integration: No Outlook, iCloud, or CalDAV
- MongoDB + Firebase: Unusual stack for self-hosting
- No automatic booking: Shows overlap but does not book meetings
- No email notifications: Participants must check manually
- Limited documentation: Self-hosting instructions are minimal
- No API: No programmatic access
When to Use#
- You want When2meet-style visual availability for a small group
- Google Calendar integration is sufficient
- MIT license is important to your project
- You are comfortable with the Firebase + MongoDB stack
When to Skip#
- You need a production-ready self-hosted solution (use Rallly instead)
- You need booking/confirmation workflows
- You need multi-provider calendar integration
- You need email notifications
- Long-term maintenance assurance matters
Competitive Position#
schej.it occupies the “visual availability grid” niche alongside When2meet (the original, closed-source), Crab.fit (OSS, minimalist), and LettuceMeet (OSS, heat map approach). Its differentiator is Google Calendar import. However, its small community and student-project origins make it less suitable for production use than Rallly.
Market Signals#
- ~200 GitHub stars (modest but growing)
- Active in university/student communities
- MIT license makes it attractive for forks and derivatives
- When2meet’s popularity validates the UX paradigm
- Self-hosting adoption appears limited
CalDAV Scheduling Protocol Support - Rapid Assessment#
Identity#
This is not a single library but an assessment of scheduling protocol support across CalDAV client libraries. The relevant standards are:
| Standard | Purpose |
|---|---|
| RFC 6638 (CalDAV Scheduling) | Server-mediated scheduling via CalDAV |
| RFC 5546 (iTIP) | Transport-independent scheduling messages |
| RFC 6047 (iMIP) | Email-based scheduling (Accept/Decline buttons) |
| VFREEBUSY (RFC 5545) | Machine-readable free/busy data |
What Problem This Solves#
CalDAV scheduling lets calendar servers handle meeting invitations automatically. When a user creates a meeting with attendees, the CalDAV server:
- Sends invitations to attendees’ scheduling inboxes
- Collects RSVP responses
- Updates the organizer’s event with attendee status
- Optionally publishes free/busy data for availability queries
This is the standards-based approach to scheduling – no Calendly, no booking page, just calendar servers talking to each other.
Library Support#
tsdav (TypeScript)#
tsdav provides CalDAV client operations but scheduling-specific support is limited:
- Calendar CRUD: Full support (create, read, update, delete events)
- Free/busy queries: Supported via
freeBusyQuery()method - Scheduling inbox/outbox: Not directly exposed in API
- iTIP handling: Not implemented – application must construct iTIP messages manually
- Used by: cal.com (for calendar read/write, not for scheduling protocol)
caldav (Python)#
The Python caldav library has broader scheduling support:
- Calendar CRUD: Full support
- Free/busy queries: Supported via
freebusy_request()method - Scheduling:
save_event()with attendees triggers server-side scheduling (if server supports it) - VFREEBUSY parsing: Returns parsed free/busy data
- iTIP: Not directly implemented but server handles it transparently
icalendar (Python)#
The icalendar library handles the data format layer:
- VFREEBUSY components: Full parse/generate support
- VEVENT with attendees: Can create events with ATTENDEE properties
- iTIP METHOD: Can set METHOD property (REQUEST, REPLY, CANCEL)
- No protocol: Data format only – no sending/receiving
email + icalendar (iMIP)#
For email-based scheduling (the most universally supported approach):
- Create a VCALENDAR with METHOD:REQUEST and ATTENDEE properties
- Attach it to an email as
text/calendarcontent type - Recipients see Accept/Decline buttons in their email client
- Replies come back as METHOD:REPLY emails
This works with every major email/calendar client (Gmail, Outlook, Apple Mail, Thunderbird). Libraries needed: icalendar (Python) or ical-generator (JS) for the calendar data, plus any email library for sending.
Real-World Adoption#
CalDAV scheduling works well between CalDAV servers (Radicale, Baikal, Nextcloud) but is poorly supported by major providers:
| Provider | CalDAV Scheduling Support |
|---|---|
| Google Calendar | Partial (read/write via CalDAV, scheduling via API only) |
| Microsoft Outlook | None (Graph API only, no CalDAV at all) |
| Apple iCloud | Supported (CalDAV with scheduling extensions) |
| Fastmail | Supported |
| Nextcloud | Supported |
| Radicale | Partial (basic scheduling) |
This means CalDAV scheduling is viable for:
- Self-hosted environments (Nextcloud, Baikal, Radicale)
- Apple ecosystem users
- Enterprise environments with CalDAV servers
But NOT viable as a universal scheduling mechanism – Microsoft’s absence alone rules it out for many use cases.
When Standards-Based Scheduling Makes Sense#
- Internal tools where all users are on the same CalDAV server
- Self-hosted environments (Nextcloud-to-Nextcloud scheduling)
- Email-based invitations (iMIP works universally)
- Privacy-focused setups avoiding commercial APIs
When to Use Provider APIs Instead#
- Google Calendar API for Google users
- Microsoft Graph API for Outlook users
- CalDAV for Apple/Fastmail/self-hosted users
- Nylas or Cronofy to abstract all three
Key Takeaway#
CalDAV scheduling (RFC 6638) is technically sound but practically limited by major provider adoption. For real-world meeting scheduling tools, iMIP (email-based invitations) is the only universally supported standard. Everything else requires provider-specific API integration.
Calendar API Aggregators - Rapid Assessment#
The Problem They Solve#
Building a scheduling tool requires reading calendars from multiple providers. Each provider has a different API:
- Google Calendar: REST API with OAuth 2.0
- Microsoft Outlook: Microsoft Graph API with OAuth 2.0
- Apple iCloud: CalDAV with app-specific passwords
- Generic CalDAV: Various auth mechanisms
Implementing and maintaining three different calendar integrations is expensive. Calendar API aggregators provide a single unified API that abstracts the differences.
Nylas#
| Field | Value |
|---|---|
| Name | Nylas |
| Website | nylas.com |
| SDKs | nylas-nodejs, nylas-python, nylas-ruby, nylas-java |
| SDK License | MIT |
| API Model | Commercial (pay-per-connected-account) |
| Providers | Google, Microsoft, iCloud, Yahoo, generic IMAP/CalDAV |
| Founded | 2013 |
What it provides:
- Unified Calendar API (CRUD events across all providers)
- Unified Email API (read/send across providers)
- Scheduling API (availability calculation, booking pages)
- Webhook notifications for calendar changes
- Virtual calendars (no provider connection needed)
SDK quality: Well-documented, actively maintained, TypeScript types. The SDK itself is MIT-licensed and open source. The backend service is commercial.
Pricing: Free tier for testing. Production pricing starts at ~$0.50 per connected account per month (varies by plan).
Strengths:
- Most comprehensive multi-provider support
- Handles OAuth token refresh automatically
- Scheduling API includes availability calculation
- Battle-tested at scale (used by Brex, Dialpad, Upwork)
Weaknesses:
- Commercial dependency (single vendor)
- Per-account pricing can be expensive at scale
- Adds latency (API calls go through Nylas servers)
- Privacy concern: calendar data passes through third-party servers
- Company restructured in 2024; long-term stability uncertain
Cronofy#
| Field | Value |
|---|---|
| Name | Cronofy |
| Website | cronofy.com |
| SDKs | cronofy-node, cronofy-python, cronofy-ruby, cronofy-php |
| SDK License | MIT |
| API Model | Commercial (pay-per-connected-account) |
| Providers | Google, Microsoft, Apple, generic CalDAV |
| Founded | 2014 |
What it provides:
- Unified Calendar API
- Availability API (multi-person availability calculation)
- Scheduling API (booking links with embeddable UI)
- Real-Time Scheduling (embeddable scheduling widget)
- Conferencing integration (auto-create Zoom/Teams/Meet links)
SDK quality: Functional but less polished than Nylas. Documentation is adequate.
Pricing: Free for development. Production pricing varies (enterprise- focused, must contact sales for most plans).
Strengths:
- Availability API is purpose-built for scheduling use cases
- Embeddable scheduling UI components
- Strong in enterprise/HR scheduling market
- European company (GDPR-focused)
- Conferencing integration built-in
Weaknesses:
- Smaller ecosystem than Nylas
- Enterprise-focused pricing (expensive for startups)
- SDK community is smaller
- Less transparent pricing
Comparison#
| Feature | Nylas | Cronofy |
|---|---|---|
| Calendar providers | Google, Microsoft, Apple, Yahoo, CalDAV | Google, Microsoft, Apple, CalDAV |
| Email API | Yes | No |
| Availability API | Yes | Yes (stronger) |
| Scheduling UI | Basic | Advanced (embeddable) |
| Conferencing | No | Yes (Zoom, Teams, Meet) |
| Pricing model | Per-account + plan tier | Per-account + enterprise |
| SDK languages | JS, Python, Ruby, Java | JS, Python, Ruby, PHP |
| Company size | Larger | Smaller |
| Data residency | US-based | EU-based option |
When to Use an Aggregator#
- You need Google + Microsoft + Apple calendar access
- Building the integrations yourself would take 4-8 weeks
- Per-account costs are acceptable for your business model
- You need availability calculation across multiple providers
- Time-to-market is more important than infrastructure ownership
When to Build Direct Integrations#
- You only need one or two providers
- Per-account costs are prohibitive at your scale
- You need data to stay on your servers (privacy/compliance)
- You have the engineering capacity to maintain integrations
- You need features the aggregator does not expose
Key Takeaway#
Calendar API aggregators trade ongoing costs for development time. For startups building scheduling features, they can save 4-8 weeks of integration work. For mature products at scale, building direct integrations may be more cost-effective. The SDKs are open source (MIT) but the backend services are proprietary – you own the client code but depend on the vendor for the actual calendar access.
Commercial Scheduling Tools - Reference Assessment#
Purpose#
These are commercial (not self-hostable) scheduling tools included for market context. Understanding what the commercial leaders offer helps evaluate OSS alternatives and identify gaps.
Calendly#
| Field | Value |
|---|---|
| Type | SaaS |
| Pricing | Free (1 event type) to $16+/user/month |
| Providers | Google, Microsoft, Apple (via iCloud) |
| Self-hostable | No |
Why it matters: Calendly defined the modern scheduling link category. Every OSS alternative is compared against it. Key features that became table stakes because of Calendly:
- One-click booking links (share URL, guest picks a time)
- Automatic timezone detection
- Buffer time between meetings
- Round-robin team scheduling
- Embed widgets for websites
- Integration with video conferencing
- Payment collection (Stripe, PayPal)
Gap analysis vs cal.com: cal.com matches or exceeds Calendly on almost every feature. Calendly’s advantages are polish, reliability at scale, and zero-maintenance hosting. cal.com’s advantage is self-hosting, source access, and no per-user pricing for self-hosted.
SavvyCal#
| Field | Value |
|---|---|
| Type | SaaS |
| Pricing | From $12/user/month |
| Providers | Google, Microsoft |
| Self-hostable | No |
Why it matters: SavvyCal innovated on the scheduling UX with “overlay your calendar” – guests can overlay their own calendar on top of the host’s availability to find mutual free times. This is a hybrid between slot-based and visual-availability approaches.
Key innovation: Calendar overlay UX where the guest connects their calendar to see a combined view, rather than just seeing the host’s available slots. This reduces the “slot doesn’t actually work for me” problem.
Gap analysis vs OSS: No OSS tool replicates the calendar overlay UX. This represents an opportunity for the OSS scheduling ecosystem.
Zcal#
| Field | Value |
|---|---|
| Type | SaaS (free for individual use) |
| Pricing | Free (individuals), paid for teams |
| Providers | Google, Microsoft |
| Self-hostable | No |
Why it matters: Zcal positions itself as the “fast” scheduling tool with a focus on minimal UI and quick setup. Its free tier for individual use makes it a popular choice for freelancers and solo professionals.
Key differentiator: Speed and simplicity. While Calendly and cal.com offer extensive customization, Zcal focuses on getting a scheduling link live in under 60 seconds.
TidyCal#
| Field | Value |
|---|---|
| Type | SaaS with lifetime deal |
| Pricing | $29 one-time (lifetime access) |
| Providers | Google, Microsoft, Apple |
| Self-hostable | No |
Why it matters: TidyCal (by AppSumo) competes on pricing with a one-time fee instead of monthly subscriptions. Popular with bootstrappers and small businesses. Demonstrates that the market has room for simpler, cheaper alternatives to Calendly.
Appointlet#
| Field | Value |
|---|---|
| Type | SaaS |
| Pricing | Free tier, paid from $8/user/month |
| Providers | Google, Microsoft |
| Self-hostable | No |
Why it matters: Strong in the meeting scheduling space with good embed capabilities. Often compared alongside Calendly for sales team scheduling.
Market Context Summary#
The commercial scheduling market is mature and competitive:
- Leader: Calendly (market-defining, broadest features)
- Challenger: SavvyCal (UX innovation with calendar overlay)
- Budget: TidyCal (one-time pricing)
- Simplicity: Zcal (fastest setup)
- OSS alternative: cal.com (matches Calendly features, self-hostable)
The commercial market validates strong demand. For developers building scheduling features, the question is whether to build (using libraries), deploy (cal.com self-hosted), or buy (SaaS subscription).
S1: Rapid Discovery - Meeting Scheduling Libraries#
Scope#
Open-source and self-hostable meeting scheduling tools and libraries. Both full platforms (cal.com, Easy!Appointments) and lower-level components (CalDAV scheduling, availability calculation). Focus on what developers can install, self-host, and integrate – not pure SaaS reviews.
Key Questions#
- What are the leading open-source alternatives to Calendly and Doodle?
- How do slot-based (one host publishes) and poll-based (group votes) tools differ architecturally?
- What is the minimum viable scheduling link – what components are needed?
- How do OSS scheduling tools integrate with Google Calendar, Outlook, iCloud?
- What CalDAV scheduling protocol support exists in client libraries?
- Self-hosting requirements: database, email, calendar provider connections?
Search Strategy#
- GitHub search: “scheduling”, “calendly alternative”, “meeting scheduler”, “appointment booking”, “doodle alternative”
- npm search: “scheduling”, “booking”, “appointment”, “availability”
- PyPI search: “scheduling”, “caldav scheduling”, “free busy”
- Docker Hub: self-hostable scheduling solutions
- “Awesome self-hosted” lists for scheduling tools
- Cal.com ecosystem and API documentation
- RFC 6638, RFC 5546, RFC 6047 for scheduling protocol standards
Findings Summary#
The meeting scheduling space divides into two paradigms:
Slot-based (Calendly model):
- cal.com – dominant OSS option (35K+ stars, full-stack platform)
- Easy!Appointments – PHP-based, lighter weight (3.2K stars)
- Zcal – commercial reference (free tier, not self-hostable)
Poll-based (Doodle model):
- Rallly – leading OSS option (3.6K stars, Next.js)
- schej.it – visual availability overlay (200 stars, MIT)
Protocol layer:
- CalDAV scheduling (RFC 6638) is supported by tsdav and caldav but poorly adopted by major providers
- iMIP (RFC 6047) is universally used for email invitations
Calendar API aggregation:
- Nylas, Cronofy provide unified APIs across providers (commercial, OSS SDKs)
Tool Count#
- 3 full scheduling platforms evaluated (2 OSS, 1 commercial reference)
- 2 poll-based schedulers evaluated (both OSS)
- 2 CalDAV clients with scheduling support
- 2 calendar API aggregators with OSS SDKs
- 3 commercial references for market context
S1 Recommendation: Meeting Scheduling Libraries#
Executive Summary#
Meeting scheduling divides into two paradigms: slot-based (host publishes availability, guest picks) and poll-based (group votes on times). Each has a clear OSS leader. For most developers, the question is not “which library?” but “can I use an existing platform?”
Decision Tree#
Do you need scheduling in your application?
│
├─ Slot-based (one host, guests book)?
│ ├─ Full platform needed? → cal.com (self-hosted or cloud)
│ ├─ Service business (salon, clinic)? → Easy!Appointments
│ ├─ Just need an embed widget? → cal.com embed
│ └─ Building custom UI from scratch? → Calendar APIs + custom logic
│
├─ Poll-based (group finds common time)?
│ ├─ Vote on proposed times? → Rallly
│ └─ Visual availability grid? → schej.it (or build with When2meet UX)
│
└─ Both?
└─ No single tool does both well. Use cal.com + Rallly, or build custom.Top Picks#
Slot-Based Scheduling#
Default choice: cal.com
- 35K+ stars, 600+ contributors, VC-funded
- Complete Calendly replacement
- Self-hosted (AGPL) or cloud (paid plans)
- Embed widget for integration into existing sites
- REST API for programmatic scheduling
- All major calendar providers supported
Alternative: Easy!Appointments (if PHP stack, service business model)
- 3.2K stars, GPL-3.0
- Runs on basic PHP hosting
- Service/provider/customer model (salon, clinic, tutoring)
- Google Calendar only
Poll-Based Scheduling#
Default choice: Rallly
- 3.6K stars, AGPL-3.0
- Clean Doodle alternative
- No account needed for participants
- Self-hosted with Docker
Alternative: schej.it (if visual grid UX needed)
- 200 stars, MIT license
- When2meet-style availability overlay
- Google Calendar import
Building from Scratch#
Use calendar API aggregators (Nylas or Cronofy):
- Unified API across Google, Outlook, iCloud
- Availability calculation built in
- Trade ongoing costs for development time
Or build direct integrations:
- tsdav (TypeScript CalDAV client) for CalDAV providers
- Google Calendar API + Microsoft Graph API for major providers
- icalendar (Python) or ical.js (JS) for ICS format handling
Feature Comparison#
| Feature | cal.com | Easy!Appts | Rallly | schej.it |
|---|---|---|---|---|
| Scheduling model | Slot-based | Slot-based (service) | Poll-based | Visual grid |
| Google Calendar | Yes | Yes | No | Yes (import) |
| Outlook | Yes | No | No | No |
| Apple/CalDAV | Yes | No | No | No |
| Self-hosted | Yes (Docker) | Yes (PHP) | Yes (Docker) | Possible |
| License | AGPL-3.0 | GPL-3.0 | AGPL-3.0 | MIT |
| Stars | 35K | 3.2K | 3.6K | 200 |
| Embed widget | Yes | No | No | No |
| API | Yes (REST) | Yes (REST) | No | No |
| Video integration | Yes | No | No | No |
| Team scheduling | Yes | No | N/A | N/A |
What Is Missing in the OSS Ecosystem#
Lightweight scheduling component library: Something between “use cal.com’s entire stack” and “build from scratch.” A React component for availability display + booking with pluggable calendar backends.
Calendar overlay UX: SavvyCal’s innovation (guest overlays their calendar) has no OSS equivalent.
Unified slot + poll scheduling: No tool handles both paradigms well.
Scheduling as a microservice: cal.com is a monolith. A headless scheduling API (no UI) that handles availability, booking, and calendar sync would serve developers building custom UIs.
Proceed to S2#
Deep-dive candidates for S2 comprehensive analysis:
- cal.com architecture (how it works under the hood)
- Easy!Appointments architecture (for PHP ecosystem comparison)
- Rallly architecture (poll-based scheduling internals)
- CalDAV scheduling protocol (RFC 6638 implementation in libraries)
- Building a minimal scheduling link (architecture patterns)
S2: Comprehensive
cal.com - Architecture Deep Dive#
Overview#
cal.com is a monorepo TypeScript application built on Next.js with a layered architecture. Despite its size (~500K lines of code), the core scheduling logic follows clear patterns that can be understood in isolation.
Repository Structure#
The cal.com monorepo uses Turborepo for build orchestration:
apps/
web/ -- Next.js frontend (booking pages, dashboard)
api/ -- tRPC API routes
packages/
prisma/ -- Database schema and migrations
lib/ -- Core business logic
trpc/ -- tRPC router definitions
features/ -- Feature modules (event types, bookings, teams)
embeds/ -- Embed widget (React component)
platform/ -- Platform API (for third-party integrations)Data Model#
Core Entities#
EventType – the template for a bookable slot:
- Title, description, duration (15/30/60 min)
- Scheduling rules (availability, buffer, minimum notice)
- Integration settings (video conferencing, payment)
- Team assignment (round-robin, collective, managed)
Booking – a confirmed meeting:
- References an EventType
- Attendee information
- Start/end time
- Status (accepted, cancelled, rescheduled, pending)
- Calendar event references (external calendar event IDs)
- Payment status (if paid booking)
Availability – when a user can be booked:
- Schedule model: weekly recurring patterns
- Date-specific overrides (block off specific days)
- Combined with connected calendar busy times
Credential – calendar/video provider connections:
- OAuth tokens (Google, Microsoft)
- CalDAV credentials
- API keys (Zoom, Stripe)
- Encrypted storage in database
Relationships#
User 1--* EventType
User 1--* Credential
EventType 1--* Booking
Booking *--1 Attendee (guest)
Booking *--* CalendarEvent (external references)
User 1--* Schedule (availability patterns)Availability Engine#
The availability calculation is the heart of cal.com. It answers: “What time slots are available for this event type?”
Step 1: Base Availability#
Load the user’s schedule (weekly pattern):
- Monday: 9am-5pm
- Tuesday: 9am-5pm
- (etc.)
Apply date-specific overrides:
- March 15: blocked (vacation)
- March 20: 10am-2pm only (half day)
Step 2: Connected Calendar Busy Times#
For each connected calendar credential:
- Query the calendar provider API for busy times in the requested range
- Google Calendar:
freebusy.queryendpoint - Microsoft Graph:
calendar/getScheduleendpoint - CalDAV:
free-busy-queryREPORT (via tsdav) - ICS feeds: fetch and parse for events in range
Merge all busy times into a single busy-time list.
Step 3: Existing Bookings#
Load all confirmed bookings for the user in the requested date range. Add these to the busy-time list.
Step 4: Slot Generation#
Generate candidate slots based on event type configuration:
- Duration (e.g., 30 minutes)
- Slot interval (e.g., every 15 minutes)
- Buffer before/after (e.g., 10 minutes each side)
Step 5: Conflict Removal#
Remove any candidate slot that overlaps with:
- Connected calendar busy times
- Existing bookings (including buffers)
- Minimum booking notice (e.g., cannot book less than 4 hours ahead)
- Maximum days in advance (e.g., only next 60 days)
Step 6: Timezone Conversion#
Convert remaining available slots to the guest’s timezone for display. All internal calculations happen in UTC; timezone conversion is a presentation concern.
Implementation Detail#
The availability calculation uses interval arithmetic – representing
free and busy times as arrays of [start, end] intervals, then
performing set subtraction (available intervals minus busy intervals).
// Simplified: actual implementation in packages/lib/availability
type TimeRange = { start: Date; end: Date };
function getAvailableSlots(
baseAvailability: TimeRange[],
busyTimes: TimeRange[],
slotDuration: number,
bufferTime: number
): TimeRange[] {
// Subtract busy from available, generate slots
}Booking Flow#
What Happens When a Guest Books#
- Guest selects a time on the booking page
- Frontend sends booking request via tRPC mutation
- Server re-validates availability (critical – availability may have changed since page load)
- Optimistic lock: Check no other booking exists for this slot (database-level constraint via Prisma transaction)
- Create Booking record in database (status: accepted or pending)
- Create calendar events:
- On host’s connected calendars (Google/Outlook/CalDAV)
- Generate .ics attachment for email
- Send notifications:
- Confirmation email to guest
- Notification email to host
- Webhook triggers (if configured)
- Create video meeting (if configured – Zoom, Google Meet, etc.)
- Process payment (if paid event type – Stripe)
Concurrency Control#
The booking creation uses a database transaction with optimistic concurrency:
// Simplified booking creation
await prisma.$transaction(async (tx) => {
// Re-check availability within transaction
const conflicts = await tx.booking.findMany({
where: { userId, startTime: { lte: endTime }, endTime: { gte: startTime } }
});
if (conflicts.length > 0) throw new Error("Slot no longer available");
// Create booking atomically
await tx.booking.create({ data: bookingData });
});This prevents double-booking: if two guests try to book the same slot simultaneously, the database transaction ensures only one succeeds. The second guest gets a “slot no longer available” error.
Calendar Integration Architecture#
Provider Abstraction#
cal.com defines a CalendarService interface that each provider implements:
interface CalendarService {
createEvent(event: CalendarEvent): Promise<ExternalEvent>;
updateEvent(uid: string, event: CalendarEvent): Promise<ExternalEvent>;
deleteEvent(uid: string): Promise<void>;
getAvailability(dateFrom: string, dateTo: string): Promise<BusyTime[]>;
}Implementations exist for:
GoogleCalendarService(Google Calendar API)Office365CalendarService(Microsoft Graph API)CalDavCalendarService(tsdav, for CalDAV providers)ICSCalendarService(ICS feed polling)AppleCalendarService(iCloud-specific CalDAV)
OAuth Flow#
For Google and Microsoft:
- User clicks “Connect Google Calendar” in settings
- Redirect to provider’s OAuth consent screen
- Provider redirects back with authorization code
- cal.com exchanges code for access + refresh tokens
- Tokens stored as
Credentialin database (encrypted) - Automatic token refresh on expiry
CalDAV Integration#
For CalDAV providers (Apple, Fastmail, Nextcloud):
- User provides server URL and credentials
- cal.com discovers calendars via CalDAV autodiscovery
- Uses tsdav for all CalDAV operations
- Busy times fetched via CalDAV free-busy-query
Extension Points#
Embed Widget#
cal.com provides a React embed widget that can be added to any website:
<!-- Inline embed -->
<cal-inline calLink="username/30min"></cal-inline>
<script src="https://cal.com/embed.js"></script>The embed loads an iframe with the booking page. Configuration options include theme, layout, and pre-filled fields.
REST API#
cal.com exposes a REST API for programmatic scheduling:
- Create/manage event types
- List available slots
- Create bookings
- Manage calendars
- Webhook subscriptions
The API uses API key authentication and follows REST conventions.
Webhooks#
Webhooks fire on booking lifecycle events:
BOOKING_CREATEDBOOKING_CANCELLEDBOOKING_RESCHEDULEDBOOKING_PAYMENT_INITIATED
Apps/Integrations#
cal.com has a plugin system for adding new integrations:
- Video conferencing (Zoom, Meet, Teams, Jitsi, Daily.co)
- Payment (Stripe)
- CRM (HubSpot, Salesforce)
- Automation (Zapier, Make)
- Analytics (Plausible, PostHog)
Performance Characteristics#
Availability Calculation#
The most expensive operation is fetching busy times from connected calendars. Each provider API call adds 200-500ms latency. For users with multiple connected calendars, availability calculation can take 1-2 seconds.
cal.com mitigates this with:
- Parallel fetching from multiple providers
- Caching of availability data (short TTL, ~5 minutes)
- Background sync for ICS feeds
Database Load#
The primary database bottleneck is the booking creation transaction, which requires a read-then-write pattern. Under high booking volume, PostgreSQL row-level locking handles contention well.
Scaling#
- Horizontal: Stateless web tier scales with additional instances
- Database: Single PostgreSQL instance is the bottleneck; read replicas help for availability queries
- Redis: Used for job queues (email sending, webhook delivery) and caching
- Typical self-hosted deployment handles 100s of bookings/day without issues
Rallly - Architecture Deep Dive#
Overview#
Rallly is a poll-based scheduling tool built on Next.js + Prisma + PostgreSQL. Its architecture is simpler than cal.com because it solves a narrower problem: collecting time preferences from a group, not managing calendar integrations or real-time availability.
Repository Structure#
apps/
web/ -- Next.js application (both UI and API)
packages/
database/ -- Prisma schema and migrations
emails/ -- Email templates (React Email)
ui/ -- Shared UI componentsNotably simpler than cal.com’s monorepo – Rallly is essentially one Next.js application with shared packages.
Data Model#
Core Entities#
Poll – the scheduling question:
- Title, description, location
- Creator information
- Timezone
- Status (live, paused, finalized)
- Deadline (optional)
- Type: date-only or date-and-time
Option – a proposed time for the poll:
- References a Poll
- Start date/time (and optional end time)
- Duration (for time-specific options)
Participant – someone who votes:
- Name (no account required)
- Optional email
- Linked to a Poll
Vote – a participant’s response to an option:
- References a Participant and an Option
- Type: yes, no, or ifNeedBe (maybe)
Relationships#
Poll 1--* Option
Poll 1--* Participant
Participant 1--* Vote
Vote *--1 OptionThis is a classic voting/survey data model. The key design decision is that participants do not need accounts – they provide a name and optionally an email, reducing friction to near zero.
No Calendar Integration#
Unlike cal.com, Rallly does not connect to any calendar. Participants manually indicate their availability by voting. This is both a limitation (no automatic busy-time detection) and a feature (no OAuth setup, no privacy concerns about calendar access).
Poll Creation Flow#
- Organizer creates poll: Title, description, timezone
- Organizer proposes options: Select dates (or dates + times)
- Poll is created in database with options
- Shareable link generated: Unique URL for the poll
- Organizer shares link via email, chat, etc.
The poll creation form uses a calendar date picker for selecting proposed dates, with an optional time picker for specific time slots.
Voting Flow#
- Participant opens poll link: No login required
- Sees proposed options: Dates/times displayed in their timezone
- Votes on each option: Yes / If Need Be / No
- Submits votes: Stored in database, immediately visible to all
Timezone Handling#
Options are stored in UTC. When displaying to participants:
- Detect participant’s browser timezone (via
Intl.DateTimeFormat) - Convert all option times to participant’s local timezone
- Display converted times
For date-only polls (no specific times), timezone conversion is irrelevant – “March 15” means March 15 regardless of timezone.
For date-and-time polls, timezone conversion is critical. The organizer creates options in their timezone; each participant sees the equivalent time in theirs.
Results Display#
The results view shows a matrix:
- Columns: proposed options (dates/times)
- Rows: participants
- Cells: vote type (yes/maybe/no)
- Summary: count of yes/maybe/no votes per option
The organizer can identify the best option (most “yes” votes) and finalize the poll by selecting a winning time.
Notification System#
Rallly uses email notifications for:
- New participant voted (to poll creator)
- Poll finalized (to all participants with email)
- Poll reminder (manual trigger by creator)
Email templates use React Email for rendering, sent via configurable SMTP.
Authentication Model#
Rallly has two authentication layers:
Poll management: The poll creator authenticates via a magic link (email-based, no password). This grants them admin access to their polls (edit, pause, finalize, delete).
Voting: No authentication required. Participants provide a name and vote. This is deliberate – reducing friction for participants is the primary UX goal.
Trade-off: No authentication for voters means anyone with the poll link can vote, and participants could vote multiple times under different names. For the typical use case (scheduling a team meeting), this is acceptable. For high-stakes decisions, it would be a vulnerability.
Self-Hosting#
Rallly provides a Docker Compose configuration:
services:
rallly:
image: lukevella/rallly:latest
ports: ["3000:3000"]
env_file: .env
depends_on: [db]
db:
image: postgres:14
volumes: [db-data:/var/lib/postgresql/data]Configuration via environment variables:
DATABASE_URL– PostgreSQL connection stringSECRET_PASSWORD– Session encryption keySMTP_*– Email server configurationNEXT_PUBLIC_BASE_URL– Public URL for links
Self-hosting is straightforward – one container plus PostgreSQL. Resource requirements are minimal (512MB RAM, minimal CPU).
Limitations of the Architecture#
No API#
Rallly does not expose a public API. All operations go through the Next.js web interface. This means:
- No programmatic poll creation
- No integration with other tools
- No automated workflows
For developers who want to build on Rallly, the only option is forking the codebase.
No Calendar Event Creation#
After finalizing a poll, Rallly does not create a calendar event. The organizer must manually create the meeting in their calendar application. This is a significant gap for a scheduling tool – the workflow is incomplete.
No Recurring Polls#
Each scheduling decision requires a new poll. For recurring meetings (weekly team standups that need rescheduling), creating a new poll each time adds friction.
Single-Poll Focus#
Rallly handles one scheduling decision at a time. There is no concept of a “group” or “team” that repeatedly schedules together, no participant profiles across polls, and no history of scheduling decisions.
Extension Opportunities#
If forking or extending Rallly:
- Add calendar event creation: After finalization, create events via Google Calendar API / Microsoft Graph / CalDAV
- Add API: Expose tRPC routes as REST endpoints for programmatic access
- Add recurring polls: Template system for repeated scheduling decisions
- Add calendar import: Let participants import busy times from connected calendars to inform their voting
- Add webhook notifications: Fire events on poll creation, vote, and finalization
Comparison with cal.com#
| Dimension | cal.com | Rallly |
|---|---|---|
| Problem | 1-on-1 booking | Group time finding |
| Architecture | Full platform (monorepo) | Single app |
| Calendar integration | Yes (Google, Outlook, CalDAV) | No |
| Authentication | Full accounts | Magic link + anonymous |
| Data complexity | High (events, bookings, credentials) | Low (polls, votes) |
| Self-hosting complexity | High (PG + Redis + OAuth) | Low (PG only) |
| Extension surface | API + webhooks + apps | Fork only |
| Codebase size | ~500K lines | ~50K lines |
Building a Minimal Scheduling Link - Architecture Patterns#
Overview#
What does it take to build the simplest possible Calendly-like scheduling link? This analysis breaks down the minimum viable scheduling link into its component parts, estimates effort, and identifies where libraries can help.
The MVP Feature Set#
A minimal scheduling link must:
- Display available time slots based on the host’s schedule
- Let a guest select a slot and provide their name + email
- Book the slot (prevent double-booking)
- Create a calendar event on the host’s calendar
- Send a confirmation email to both parties
- Handle timezones correctly
That is the absolute minimum. Without any one of these, it is not a functioning scheduling link.
Architecture Components#
Component 1: Availability Configuration#
The host must define when they are available. Options:
Static schedule: “Monday-Friday, 9am-5pm EST”
- Store as a JSON schedule object
- Simple to implement, no calendar integration needed
- Limitation: does not account for existing meetings
Calendar-aware schedule: “9am-5pm except when my calendar shows busy”
- Requires calendar integration (Google API, Graph API, CalDAV)
- Adds 1-2 weeks of development for each provider
- Worth it for any real-world use
Hybrid: Static base schedule minus calendar busy times
- Most common approach
- Base schedule in your database, busy times from calendar API
Component 2: Slot Generation Engine#
Given a schedule and a date range, generate bookable time slots.
Inputs:
- Base availability (recurring weekly pattern)
- Date overrides (blocked days, modified hours)
- Busy times (from connected calendars)
- Event type configuration (duration, buffer, minimum notice)
Algorithm:
for each day in requested range:
base_slots = generate_slots(day, schedule, duration, interval)
busy = fetch_busy_times(day, connected_calendars)
existing = fetch_bookings(day, host)
available = base_slots - busy - existing - buffer_zones
apply_minimum_notice(available, now)
apply_maximum_advance(available, now)
yield availableKey decisions:
- Slot interval: every 15 min? 30 min? Same as duration?
- Buffer handling: before, after, or both?
- Timezone: calculate in UTC, display in guest’s timezone
Estimated effort: 2-3 days for basic implementation, 1-2 weeks for production quality (edge cases around DST, midnight crossings, multi-day events).
Component 3: Calendar Integration#
Connecting to a calendar provider for busy-time fetching and event creation.
Google Calendar (most common):
- OAuth 2.0 setup (Google Cloud Console, consent screen)
freebusy.queryfor availabilityevents.insertfor booking- Token refresh handling
- Libraries:
googleapis(Node.js),google-api-python-client(Python) - Effort: 3-5 days (mostly OAuth boilerplate)
Microsoft Outlook:
- Azure AD app registration
- Microsoft Graph API
/me/calendar/getSchedulefor availability/me/eventsfor booking- MSAL for auth
- Libraries:
@microsoft/microsoft-graph-client(Node.js),msgraph-sdk-python(Python) - Effort: 3-5 days
CalDAV (Apple, Fastmail, Nextcloud):
- CalDAV autodiscovery
- REPORT requests for busy times
- PUT for event creation
- Libraries: tsdav (TypeScript), caldav (Python)
- Effort: 2-3 days (simpler auth, standard protocol)
Shortcut: Calendar API aggregator (Nylas, Cronofy):
- One integration covers all providers
- 1-2 days to integrate
- Ongoing cost per connected account
Component 4: Booking Engine#
The transactional core that reserves a slot.
Requirements:
- Atomic check-and-book (prevent double-booking)
- Idempotency (retry-safe)
- Status tracking (confirmed, cancelled, rescheduled)
Database design:
CREATE TABLE bookings (
id UUID PRIMARY KEY,
host_id UUID REFERENCES users(id),
event_type_id UUID REFERENCES event_types(id),
guest_name TEXT NOT NULL,
guest_email TEXT NOT NULL,
start_time TIMESTAMPTZ NOT NULL,
end_time TIMESTAMPTZ NOT NULL,
status TEXT DEFAULT 'confirmed',
calendar_event_id TEXT, -- external calendar reference
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Prevent overlapping bookings
CREATE UNIQUE INDEX no_double_booking
ON bookings (host_id, start_time)
WHERE status = 'confirmed';The unique index on (host_id, start_time) prevents two confirmed
bookings at the same time for the same host. The database enforces
this constraint even under concurrent requests.
Effort: 1-2 days for basic implementation.
Component 5: Email Notifications#
Both parties need confirmation emails.
Requirements:
- Confirmation email to guest (meeting details, timezone-aware time)
- Notification email to host
- .ics attachment (so the meeting can be added to any calendar)
- Cancellation email (if cancellation is supported)
ICS attachment generation:
// Using ical-generator
const ical = require('ical-generator');
const calendar = ical({ name: 'Meeting' });
calendar.createEvent({
start: startTime,
end: endTime,
summary: eventTitle,
organizer: { name: hostName, email: hostEmail },
attendees: [{ name: guestName, email: guestEmail }]
});
// Attach calendar.toString() to email as text/calendar
Effort: 1-2 days (including email template design).
Component 6: Timezone Handling#
The most error-prone component.
Rules:
- Store all times in UTC (database column: TIMESTAMPTZ)
- Host defines schedule in their timezone
- Guest views slots in their timezone
- Emails include timezone-explicit times for both parties
- Handle DST transitions (a recurring slot may not exist during “spring forward”)
Libraries:
- JavaScript:
luxonordate-fns-tz(avoidmoment-timezone, deprecated) - Python:
zoneinfo(stdlib, Python 3.9+) orpytz
Effort: 1-2 days for basic implementation; DST edge cases add another 2-3 days of testing.
Total Estimated Effort#
| Component | Minimum | Production-Ready |
|---|---|---|
| Availability config | 1 day | 3 days |
| Slot generation | 2 days | 5 days |
| Calendar integration (1 provider) | 3 days | 5 days |
| Booking engine | 1 day | 3 days |
| Email notifications | 1 day | 3 days |
| Timezone handling | 1 day | 4 days |
| Frontend (booking page) | 2 days | 5 days |
| Total | ~11 days | ~28 days |
For a single developer, a minimum viable scheduling link is roughly 2-3 weeks of work. A production-ready version with edge case handling, testing, and polish is 5-6 weeks.
Build vs. Use cal.com#
| Factor | Build from scratch | Use cal.com |
|---|---|---|
| Time to working prototype | 2-3 weeks | 1 day (Docker) |
| Calendar integrations | 1 provider (3-5 days each) | All major providers |
| UI customization | Full control | Theme + embed options |
| Architecture control | Full | Limited (monolith) |
| Ongoing maintenance | Your responsibility | Community maintained |
| License constraints | Your choice | AGPL-3.0 |
| Infrastructure | Your choice | PG + Redis + Node.js |
Build from scratch when:
- You need deep UI/UX customization that cal.com theming cannot achieve
- AGPL is incompatible with your product licensing
- Your tech stack is fundamentally different (Python/Django, Ruby/Rails)
- You need only a tiny subset of scheduling functionality
- You want to integrate scheduling as a library, not deploy a platform
Use cal.com when:
- You need a full scheduling platform (most cases)
- Multiple calendar integrations are required
- Team scheduling is needed
- Time-to-market matters more than architectural control
- AGPL is acceptable (or you buy enterprise license)
Library Stack for Building from Scratch#
TypeScript#
Calendar: tsdav (CalDAV) or googleapis (Google)
ICS: ical-generator (create .ics attachments)
Timezone: luxon or date-fns-tz
Email: nodemailer + react-email (templates)
Database: Prisma + PostgreSQL
Framework: Next.js or ExpressPython#
Calendar: caldav (CalDAV) or google-api-python-client
ICS: icalendar + ical-generator alternative
Timezone: zoneinfo (stdlib)
Email: smtplib + jinja2 (templates)
Database: SQLAlchemy + PostgreSQL
Framework: FastAPI or DjangoEasy!Appointments - Architecture Overview#
Overview#
Easy!Appointments is a PHP application built on CodeIgniter 3, a traditional MVC framework. Its architecture reflects the service-business domain: services, providers, and customers are first-class entities, not bolted-on concepts.
Stack#
- Backend: PHP 8.1+ on CodeIgniter 3
- Frontend: jQuery + Bootstrap (server-rendered HTML)
- Database: MySQL / MariaDB
- Calendar sync: Google Calendar API (only provider)
- Email: PHPMailer via SMTP
Data Model#
Domain Entities#
Service
- name, duration, price, description
- category (optional grouping)
- availabilities per provider
Provider
- user account (admin, provider, secretary, customer roles)
- working plan (weekly schedule with breaks)
- assigned services
- Google Calendar sync settings
Customer
- name, email, phone, address
- notes, timezone
- booking history
Appointment
- service, provider, customer
- start_datetime, end_datetime
- hash (unique booking reference)
- notes, status
- Google Calendar event ID (if synced)Key Relationships#
Provider *--* Service (many providers can offer many services)
Appointment --1 Provider
Appointment --1 Service
Appointment --1 CustomerThis is fundamentally different from cal.com’s model. cal.com centers on “event types” owned by users. Easy!Appointments centers on “services” offered by “providers” to “customers.” The domain language matches service businesses.
Availability Calculation#
Working Plan#
Each provider has a working plan – a JSON structure defining weekly availability with break periods:
{
"monday": {
"start": "09:00",
"end": "17:00",
"breaks": [
{"start": "12:00", "end": "13:00"}
]
},
"tuesday": { "start": "09:00", "end": "17:00", "breaks": [] }
}Slot Generation#
Available slots for a service with a provider:
- Load provider’s working plan for the requested date
- Generate slots based on service duration
- Remove slots that overlap with existing appointments
- Remove slots that overlap with provider’s breaks
- Remove slots within Google Calendar busy times (if synced)
- Apply extra working plan rules (custom dates)
The algorithm is simpler than cal.com’s because:
- No buffer time between appointments (though breaks serve a similar role)
- No minimum booking notice
- No round-robin or collective scheduling
- Single calendar provider (Google only)
Booking Flow#
Customer-Facing#
- Customer selects a service from the catalog
- Customer selects a provider (or “any available provider”)
- Customer selects an available date and time
- Customer enters contact information
- Appointment created in database
- Confirmation email sent to customer and provider
- If Google Calendar sync enabled: event created in provider’s calendar
Backend (Admin/Provider)#
Providers and admins can also create appointments manually through the admin panel, a standard CRUD interface for managing the appointment book.
Google Calendar Sync#
Easy!Appointments implements two-way sync with Google Calendar:
Outbound: When an appointment is created/modified/deleted in Easy!Appointments, the corresponding event is created/updated/deleted in the provider’s Google Calendar.
Inbound: When the admin panel loads, it fetches events from Google Calendar and blocks those times as unavailable. This is a poll-based sync (no webhooks), so there is a delay between creating a Google Calendar event and it appearing as blocked in Easy!Appointments.
Limitations#
- Only Google Calendar supported (no Outlook, no CalDAV, no Apple)
- Sync requires manual OAuth setup in Google Cloud Console
- No real-time sync (poll on page load)
- No free/busy query optimization (fetches all events)
API#
Easy!Appointments exposes a REST API:
/api/v1/appointments– CRUD appointments/api/v1/availabilities– Query available slots/api/v1/services– CRUD services/api/v1/providers– CRUD providers/api/v1/customers– CRUD customers
Authentication via API key (bearer token). The API enables integration with external systems – a mobile app could use the API to build a custom booking UI.
Architecture Strengths#
Simplicity#
The entire application is a single PHP project with no build step, no transpilation, no bundler configuration. Deploy by copying files to a PHP host. This dramatically reduces operational complexity compared to cal.com’s Node.js + PostgreSQL + Redis + build pipeline.
Service Business Domain Model#
The service/provider/customer model is a natural fit for:
- Medical practices (services = exam types, providers = doctors)
- Salons (services = haircut/color/etc., providers = stylists)
- Tutoring (services = subjects, providers = tutors)
- Consulting (services = consultation types, providers = consultants)
cal.com can model these scenarios but requires mapping them onto its event-type/user model, which is less natural.
Low Resource Requirements#
- Runs on shared hosting ($5/month)
- No Redis, no background workers, no build pipeline
- MySQL is widely available on budget hosting
- PHP 8.1 is supported on nearly all hosting providers
Architecture Weaknesses#
Aging Technology Stack#
- CodeIgniter 3 is no longer maintained by the CI team
- jQuery-based frontend (no component architecture)
- Server-rendered HTML (no SPA, no embed widget)
- No TypeScript, no modern build tooling
Limited Extensibility#
- No plugin/app system (unlike cal.com)
- No webhook support
- No workflow automation
- Adding new calendar providers requires forking
Single-Provider Calendar Sync#
Only Google Calendar is supported. For businesses where staff use Outlook (common in healthcare, enterprise), this is a dealbreaker.
No Real-Time Features#
- No WebSocket updates (appointments appear on refresh)
- No real-time availability (calculated on page load)
- No push notifications
Comparison with cal.com#
| Dimension | cal.com | Easy!Appointments |
|---|---|---|
| Domain model | User + Event Type | Service + Provider + Customer |
| Best for | Individual scheduling | Service business booking |
| Stack | Next.js + PG + Redis | PHP + MySQL |
| Calendar providers | Google, Outlook, CalDAV | Google only |
| Self-hosting effort | High (Docker, env vars, OAuth) | Low (PHP hosting, copy files) |
| Embed capability | Yes (React widget) | No |
| API | Full REST + tRPC | Basic REST |
| Extension system | Apps/plugins | Fork only |
| Community size | 600+ contributors | ~60 contributors |
| License | AGPL-3.0 | GPL-3.0 |
When Easy!Appointments Is the Right Choice#
- You run a service business (the domain model fits naturally)
- You have PHP hosting (no Node.js available)
- Google Calendar is your only calendar provider
- You want the simplest possible deployment
- Budget is minimal (shared hosting is sufficient)
- You do not need embed widgets or modern frontend architecture
CalDAV Scheduling Protocol - Technical Analysis#
Overview#
CalDAV Scheduling (RFC 6638) extends the CalDAV protocol with server- mediated scheduling operations. When a CalDAV client creates an event with attendees, the server automatically handles invitation delivery, RSVP collection, and status updates.
This analysis covers how the protocol works, what library support exists, and why real-world adoption is limited.
How CalDAV Scheduling Works#
The iTIP Model (RFC 5546)#
All CalDAV scheduling is built on iTIP (iCalendar Transport-Independent Interoperability Protocol), which defines scheduling as message exchange:
| Message Type | Purpose |
|---|---|
| REQUEST | Organizer invites attendees |
| REPLY | Attendee responds (ACCEPTED, DECLINED, TENTATIVE) |
| CANCEL | Organizer cancels the meeting |
| COUNTER | Attendee proposes alternative time |
| DECLINECOUNTER | Organizer rejects counter-proposal |
Server-Side Processing#
When a CalDAV client creates or updates an event with ATTENDEE properties, the CalDAV server:
- Detects scheduling intent: Event has ORGANIZER and ATTENDEE properties
- Generates iTIP messages: Creates REQUEST/CANCEL/UPDATE messages
- Delivers to attendee inboxes: Places iTIP messages in each attendee’s scheduling inbox (a special CalDAV collection)
- Processes replies: When attendees respond, updates the organizer’s event with attendee status
Scheduling Inbox/Outbox#
RFC 6638 defines two special calendar collections per user:
Scheduling Outbox (/calendars/user/outbox/):
- Client POSTs iTIP messages here for delivery
- Server processes and routes to recipients
- Used for free/busy queries
Scheduling Inbox (/calendars/user/inbox/):
- Receives incoming iTIP messages from other users
- Client polls for new invitations/responses
- Must be processed and acknowledged by the client
Free/Busy Queries#
CalDAV scheduling supports querying user availability:
POST /calendars/user/outbox/ HTTP/1.1
Content-Type: text/calendar
BEGIN:VCALENDAR
METHOD:REQUEST
BEGIN:VFREEBUSY
DTSTART:20260310T000000Z
DTEND:20260317T000000Z
ORGANIZER:mailto:[email protected]
ATTENDEE:mailto:[email protected]
END:VFREEBUSY
END:VCALENDARThe server responds with the target user’s free/busy data for the requested range. This is how CalDAV-compatible scheduling tools check availability without reading actual event details.
Library Support#
tsdav (TypeScript)#
tsdav provides CalDAV client operations. Scheduling-specific capabilities:
Supported:
createCalendarObject()– create events (triggers server scheduling if attendees present)updateCalendarObject()– update events (triggers iTIP UPDATE)deleteCalendarObject()– delete events (triggers iTIP CANCEL)freeBusyQuery()– query free/busy via scheduling outbox
Not directly supported:
- Scheduling inbox polling (must query inbox collection manually)
- iTIP message parsing (application must handle raw iCalendar data)
- COUNTER/DECLINECOUNTER flow
In practice: cal.com uses tsdav for calendar CRUD but does NOT use CalDAV scheduling for meeting invitations. Instead, cal.com creates events directly on the host’s calendar and sends email notifications independently.
caldav (Python)#
The Python caldav library has broader scheduling awareness:
Supported:
freebusy_request()– server-side free/busy querysave_event()with attendees – triggers server scheduling- Calendar object manipulation with full ATTENDEE support
- Async operations (v3.0+)
Not directly supported:
- Inbox polling (possible via raw collection access)
- iTIP message construction
- COUNTER flow
In practice: Applications using caldav typically handle scheduling by creating events with attendees and letting the CalDAV server manage delivery. This works well between users on the same server (e.g., Nextcloud-to-Nextcloud) but fails for cross-provider scheduling.
icalendar (Python) + email#
For iMIP (email-based scheduling), which is the most universally supported approach:
- Create a VCALENDAR with METHOD and ATTENDEE properties
- Send as email attachment with content type
text/calendar - Recipients see Accept/Decline in their email client
This approach works with every major email/calendar client and requires no CalDAV infrastructure at all.
Server Support#
Which CalDAV Servers Support Scheduling#
| Server | RFC 6638 Support | Notes |
|---|---|---|
| Apple Calendar Server | Full | Reference implementation |
| Nextcloud | Full | Via SabreDAV |
| Baikal | Partial | Basic scheduling via SabreDAV |
| Radicale | Minimal | No server-side scheduling |
| None via CalDAV | Use Google Calendar API instead | |
| Microsoft | N/A | No CalDAV support at all |
| Fastmail | Full | Standards-compliant |
| Zimbra | Full | Enterprise CalDAV server |
The Provider Problem#
CalDAV scheduling works beautifully between users on the same server or between servers that both implement RFC 6638. The problem is cross- provider scheduling:
- Google does not use CalDAV scheduling (uses its own API)
- Microsoft does not support CalDAV at all
- Apple supports CalDAV scheduling but primarily for iCloud users
This means CalDAV scheduling is viable for:
- Self-hosted environments (all users on Nextcloud/Baikal)
- Apple ecosystem (iCloud + CalDAV servers)
- Enterprise (Zimbra, corporate CalDAV infrastructure)
But NOT viable as a universal scheduling mechanism.
iMIP: The Universal Alternative#
iMIP (RFC 6047) defines email-based meeting invitations:
- Organizer creates a VCALENDAR with METHOD:REQUEST
- Attaches to email as
text/calendar; method=REQUEST - Recipients see the invitation in their email client
- Accept/Decline buttons generate METHOD:REPLY emails
- Organizer’s client processes replies
Every major calendar application supports iMIP:
- Gmail / Google Calendar
- Outlook / Exchange
- Apple Mail / Calendar
- Thunderbird / Lightning
This makes iMIP the only universally adopted scheduling standard. No CalDAV support needed. No API integration needed. Just email.
Generating iMIP Messages#
Using icalendar (Python):
from icalendar import Calendar, Event
cal = Calendar()
cal.add('method', 'REQUEST')
cal.add('prodid', '-//My App//EN')
event = Event()
event.add('summary', 'Team Meeting')
event.add('dtstart', start_time)
event.add('dtend', end_time)
event.add('organizer', 'mailto:[email protected]')
event.add('attendee', 'mailto:[email protected]')
cal.add_component(event)
# Attach cal.to_ical() to email as text/calendarUsing ical-generator (JavaScript):
const ical = require('ical-generator');
const cal = ical({ method: 'REQUEST' });
cal.createEvent({
start: startTime, end: endTime,
summary: 'Team Meeting',
organizer: { email: '[email protected]' },
attendees: [{ email: '[email protected]' }]
});
// Attach cal.toString() to email
Strategic Implications#
For Scheduling Tool Developers#
Do not rely on CalDAV scheduling for universal scheduling. Major providers do not support it via CalDAV.
Use iMIP for email-based invitations. It works everywhere.
Use provider-specific APIs for calendar CRUD. Google Calendar API, Microsoft Graph, CalDAV (for Apple/Fastmail/self-hosted).
Consider CalDAV scheduling for self-hosted environments. If all users are on Nextcloud/Baikal, CalDAV scheduling provides a clean standards-based approach.
Free/busy queries via CalDAV are useful even when full scheduling is done via provider APIs. CalDAV free/busy works with any compliant server.
The Protocol Gap#
The calendar standards community designed a complete scheduling system (iTIP + CalDAV Scheduling). But market dynamics (Google and Microsoft building proprietary APIs) mean the standards-based approach is only viable in a subset of environments.
This gap is why platforms like cal.com exist – they bridge the protocol divide by implementing provider-specific integrations behind a unified scheduling interface.
S2: Comprehensive Analysis - Meeting Scheduling Libraries#
Objective#
Deep technical analysis of how meeting scheduling tools work internally. Focus on architecture, data models, integration patterns, and the technical decisions that differentiate the major options.
Scope#
Tier 1 (deep-dive):
- cal.com – architecture of the dominant OSS scheduling platform
- Rallly – poll-based scheduling internals
- Minimal scheduling link – architecture for building from scratch
Tier 2 (architecture overview):
- Easy!Appointments – PHP-based booking system internals
- CalDAV scheduling protocol – how RFC 6638 works in practice
Analysis Framework#
For each tool/pattern:
- Data model: How scheduling data is represented
- Availability engine: How free/busy times are calculated
- Booking flow: What happens from “guest clicks a time” to “meeting booked”
- Calendar integration: How external calendars are connected and synced
- Concurrency handling: How double-bookings are prevented
- Extension points: How developers can customize or extend behavior
S2 Recommendation: Meeting Scheduling Architecture#
Key Architectural Insights#
1. cal.com Is a Reference Architecture#
cal.com’s architecture – availability engine, provider abstraction, transactional booking, calendar CRUD, embed widget – represents the canonical approach to building a slot-based scheduling platform. Any custom scheduling system will likely reinvent most of these components.
The question is not “how should I architect a scheduling system?” but “do I need to architect one at all, or can I use cal.com?”
2. The Availability Engine Is the Hard Part#
Generating available slots sounds simple but involves:
- Multi-source busy-time aggregation
- Timezone conversion with DST handling
- Recurring pattern expansion with exceptions
- Buffer time calculation
- Concurrency-safe booking
This is where most custom implementations spend the majority of development time. Libraries can help with individual pieces (timezone handling, ICS parsing) but no library provides a complete availability engine.
3. Calendar Integration Is Expensive#
Each calendar provider requires:
- OAuth 2.0 implementation (Google, Microsoft)
- API-specific data mapping
- Token refresh handling
- Rate limit management
- Error handling for provider-specific quirks
Budget 3-5 days per provider for production-quality integration. Calendar API aggregators (Nylas, Cronofy) reduce this to 1-2 days total, at the cost of ongoing per-account fees.
4. CalDAV Scheduling Is Niche#
CalDAV scheduling (RFC 6638) works well in self-hosted and Apple environments but is not viable as a universal scheduling mechanism. iMIP (email-based invitations) is the only universally supported scheduling standard.
5. Poll-Based Is Architecturally Simpler#
Rallly demonstrates that poll-based scheduling has a much smaller architectural surface than slot-based scheduling:
- No calendar integration needed
- No availability engine
- No concurrency-critical booking
- Simple voting data model
The trade-off is functionality: poll-based tools require participants to manually indicate availability rather than automatically checking their calendars.
Recommended Architecture by Use Case#
Use Case A: Full Calendly Alternative#
Answer: Use cal.com. Do not build from scratch.
Rationale: cal.com’s architecture covers all the hard problems (availability engine, multi-provider calendar integration, concurrency- safe booking, embed widget, API). Rebuilding this is 3-6 months of engineering.
Use Case B: Scheduling as a Feature#
Answer: Use cal.com’s embed or API.
cal.com’s embed widget can be dropped into any website. The API allows programmatic scheduling. This avoids deploying a full platform while still leveraging its availability engine and calendar integrations.
Use Case C: Custom Scheduling UI#
Answer: Build availability engine + booking logic; use provider SDKs for calendar integration.
If you need full control over the scheduling UI and cal.com’s embed does not suffice:
- Build the availability engine (2-3 weeks)
- Integrate calendar providers (1-2 weeks per provider, or use Nylas/Cronofy)
- Build the booking engine (1 week)
- Build the UI (2-4 weeks)
Total: 6-10 weeks for a single developer.
Use Case D: Group Scheduling#
Answer: Use Rallly (self-hosted) or build a simple poll system.
Poll-based scheduling is simple enough to build from scratch (1-2 weeks) if Rallly’s AGPL license is not compatible. The core is just a voting system with timezone-aware time options.
Use Case E: Service Business Booking#
Answer: Evaluate Easy!Appointments first; fall back to cal.com.
Easy!Appointments’ service/provider/customer model is a natural fit. If you need more calendar integrations or modern frontend, use cal.com.
Library Recommendations for Custom Builds#
TypeScript Stack#
| Layer | Library | Purpose |
|---|---|---|
| Calendar (CalDAV) | tsdav | CalDAV client operations |
| Calendar (Google) | googleapis | Google Calendar API |
| Calendar (Microsoft) | @microsoft/microsoft-graph-client | Graph API |
| ICS generation | ical-generator | Create .ics attachments |
| Timezone | luxon or date-fns-tz | Timezone math |
| nodemailer + react-email | Send notifications | |
| Database | Prisma + PostgreSQL | Data persistence |
Python Stack#
| Layer | Library | Purpose |
|---|---|---|
| Calendar (CalDAV) | caldav | CalDAV client operations |
| Calendar (Google) | google-api-python-client | Google Calendar API |
| Calendar (Microsoft) | msgraph-sdk-python | Graph API |
| ICS generation | icalendar | Create .ics data |
| Timezone | zoneinfo (stdlib) | Timezone math |
| smtplib + jinja2 | Send notifications | |
| Database | SQLAlchemy + PostgreSQL | Data persistence |
S3: Need-Driven
Persona: Indie SaaS Developer Adding Scheduling#
Who They Are#
A developer (solo or small team, 2-5 engineers) building a SaaS product where scheduling is a core or important feature. Examples: a CRM that includes meeting booking, a coaching platform with session scheduling, a marketplace where service providers accept appointments.
They are technically skilled (full-stack, comfortable with APIs and infrastructure), resource-constrained (limited engineering hours, small infrastructure budget), and time-pressured (need to ship features, not build infrastructure).
Their product depends on scheduling as a FEATURE, not as the product itself. They are not building a Calendly competitor – they are building something else that needs scheduling capabilities.
What Pain They Experience#
The Build-vs-Buy Dilemma#
The core tension: building scheduling from scratch takes 6-10 weeks of engineering time (see S2 analysis), but using an existing platform introduces dependencies, license constraints, and limited customization.
They have evaluated Calendly/SavvyCal but:
- Monthly per-user pricing does not fit their business model
- Cannot embed deeply enough into their product
- Branding limitations (their users see “Powered by Calendly”)
- Feature limitations (cannot customize the booking flow)
They have looked at cal.com but:
- AGPL license may be incompatible with their product
- Deploying and maintaining another full-stack application adds ops burden
- Extracting just the scheduling engine from cal.com’s monorepo is impractical
The Multi-Provider Calendar Problem#
Their users have Google Calendar, Outlook, and sometimes Apple Calendar. Supporting all three requires implementing three different OAuth flows, three different APIs, and maintaining three sets of token refresh logic.
This is the single largest time sink in building custom scheduling. The actual availability calculation and booking logic is straightforward compared to the calendar integration work.
Timezone Edge Cases#
Every scheduling implementation encounters timezone bugs:
- DST transitions that move or eliminate time slots
- Users whose browser timezone does not match their actual timezone
- Recurring availability patterns that cross midnight in some timezones
- All-day events that span different dates in different timezones
These bugs are discovered by users in production, not during development.
What They Need#
Must-Have#
- Calendar integration with Google and Microsoft (covers 90%+ of users)
- Availability calculation that accounts for connected calendar busy times
- Booking API they can call from their own application
- Timezone handling that works globally
- Embed capability or API-first design (not a separate application)
Nice-to-Have#
- Apple Calendar / CalDAV support
- Video conferencing integration (Zoom, Google Meet)
- Team/round-robin scheduling
- Payment integration
- Webhook notifications for booking events
- White-label/branding
Recommended Path#
Option A: cal.com API + Embed (Recommended for Most)#
Use cal.com as a headless scheduling backend:
- Deploy cal.com (Docker) or use cal.com Cloud
- Create event types programmatically via API
- Embed scheduling widget in your product
- Receive booking events via webhooks
- Map cal.com users to your product’s users
Advantages: All calendar integrations handled, availability engine works, booking concurrency solved, video conferencing built-in.
Disadvantages: AGPL license (if self-hosted), dependency on cal.com API stability, limited UI customization in embed.
Cost: Self-hosted = infrastructure only. Cloud = per-user pricing.
Option B: Calendar API Aggregator + Custom Logic#
Use Nylas or Cronofy for calendar access, build your own scheduling:
- Integrate Nylas/Cronofy SDK (1-2 days)
- Build availability engine using their availability API
- Build booking logic and UI in your application
- Use ical-generator for .ics email attachments
Advantages: Full UI control, no AGPL concerns, unified calendar API, scheduling API included (Nylas Scheduler, Cronofy Real-Time Scheduling).
Disadvantages: Per-account ongoing costs ($0.50+/account/month), commercial dependency, calendar data flows through third-party servers.
Best for: Products where UI customization is critical and per- account cost is acceptable.
Option C: Build Direct Integrations#
Build calendar integrations yourself:
- Google Calendar API + googleapis SDK (3-5 days)
- Microsoft Graph API + msgraph SDK (3-5 days)
- Build availability engine (2-3 weeks)
- Build booking logic (1 week)
Advantages: No external dependencies, no per-account costs, full control.
Disadvantages: 5-8 weeks of development, ongoing maintenance of two API integrations, must handle OAuth token refresh and rate limits.
Best for: Teams with engineering capacity who need maximum control and cannot accept AGPL or per-account SaaS costs.
Anti-Recommendations#
Do not try to extract cal.com’s scheduling engine as a library. It is deeply coupled to the monorepo architecture. Using cal.com means deploying the full application.
Do not rely on CalDAV scheduling for universal scheduling. Google and Microsoft do not support it adequately. Use their proprietary APIs.
Do not underestimate timezone handling. Budget explicit time for DST edge cases and cross-timezone testing.
Do not build email notification infrastructure from scratch when you could use a transactional email service (SendGrid, Postmark, Resend). The complexity is in deliverability, not sending.
Cost Comparison#
| Approach | Development Time | Monthly Cost (100 users) |
|---|---|---|
| cal.com Cloud | 1-3 days | $1,200+ |
| cal.com Self-hosted | 3-5 days | Infrastructure only (~$20-50) |
| Nylas + custom | 2-4 weeks | $50-100 (Nylas) + infra |
| Direct integrations | 5-8 weeks | Infrastructure only |
Persona: Freelancer/Consultant Wanting Self-Hosted Scheduling#
Who They Are#
A solo professional – freelance developer, consultant, coach, therapist, or advisor – who currently uses Calendly’s free tier or manually coordinates meetings via email. They want to stop paying for Calendly (or stop being limited by the free tier) and host their own scheduling page.
They are technically competent (can run Docker, configure DNS, manage a VPS) but not a full-time developer. Their time is billed to clients, so every hour spent on infrastructure is an hour not billed.
They value: control over their data, professional appearance, no recurring SaaS fees, and the ability to customize their scheduling page to match their brand.
What Pain They Experience#
Calendly’s Free Tier Limitations#
Calendly’s free tier allows only one event type. A consultant who offers 30-minute intro calls AND 60-minute deep dives needs two event types – which means paying $8/month ($96/year). This is not expensive, but for someone who values self-hosting on principle, it grates.
Branding and Professional Image#
Calendly’s scheduling pages show “Powered by Calendly” and use Calendly’s domain (unless you pay for custom domains on premium plans). For a consultant whose brand IS their personal identity, sending clients to calendly.com/username feels impersonal.
Data Sovereignty#
Some consultants (especially in EU/healthcare) have concerns about meeting data flowing through US-based SaaS. Self-hosting keeps booking data, client emails, and meeting notes on their own server.
Feature Frustration#
Common complaints with Calendly’s free tier that push toward self-hosting:
- Cannot customize confirmation emails
- Cannot add questions to the booking form
- Limited integration with their specific tools
- Cannot create team scheduling (for consultants with assistants)
What They Need#
Must-Have#
- Scheduling page with professional appearance
- Google Calendar integration (most freelancers use Google Workspace)
- Multiple event types (different meeting durations/types)
- Timezone handling (clients in different timezones)
- Email confirmations to both parties
- Self-hostable on a VPS or home server
Nice-to-Have#
- Custom domain (schedule.myname.com)
- Custom branding (colors, logo)
- Booking form customization (additional questions)
- Video conferencing integration
- Calendar widget for their website
- Recurring availability patterns
Recommended Path#
Option A: cal.com Self-Hosted (Recommended)#
Deploy cal.com on a VPS with Docker:
- Provision a VPS ($5-10/month, 2GB RAM minimum)
- Docker Compose deployment (follow cal.com self-hosting guide)
- Configure Google Calendar OAuth credentials
- Set up DNS for custom domain
- Configure SMTP for email notifications
Time investment: 2-4 hours for initial setup, ongoing maintenance is minimal (pull new Docker images for updates).
Advantages: Complete Calendly replacement, unlimited event types, full customization, professional-grade features, active development.
Disadvantages: Requires VPS maintenance, AGPL license (not relevant for personal use), PostgreSQL + Redis adds complexity.
Option B: Easy!Appointments (If PHP Hosting Available)#
If the freelancer already has PHP hosting (common for those with WordPress sites):
- Upload Easy!Appointments files to hosting
- Configure MySQL database
- Set up services and working hours
- Configure Google Calendar sync
Time investment: 1-2 hours.
Advantages: Runs on existing PHP hosting (no additional VPS needed), simpler architecture, service-business model if they offer different service types.
Disadvantages: Dated UI, Google Calendar only, no embed widget, no video conferencing integration.
Option C: TidyCal / Zcal (When Self-Hosting Is Not Worth It)#
If the freelancer’s time is genuinely better spent on client work:
- TidyCal: $29 one-time (lifetime access, no recurring fees)
- Zcal: Free for individuals
Honesty check: For most freelancers, the hourly cost of setting up and maintaining self-hosted scheduling exceeds the cost of a commercial tool. Self-hosting makes sense primarily when motivated by principle (data sovereignty, anti-SaaS philosophy) rather than cost savings.
Anti-Recommendations#
Do not build from scratch. A freelancer’s time is billed at $100-300/hour. Even 10 hours of building scheduling infrastructure costs $1,000-3,000 in opportunity cost – far more than any SaaS subscription.
Do not deploy cal.com on a Raspberry Pi (tempting but underpowered for Next.js + PostgreSQL + Redis). Use a proper VPS.
Do not skip SMTP configuration. Without email notifications, bookings are silently lost. Use a transactional email service (SendGrid free tier, Mailgun, or Resend).
Cost Comparison#
| Approach | Setup Time | Monthly Cost | Annual Cost |
|---|---|---|---|
| Calendly free tier | 10 min | $0 | $0 |
| Calendly paid | 10 min | $8 | $96 |
| TidyCal lifetime | 20 min | $0 | $29 (one-time) |
| cal.com self-hosted | 2-4 hours | $5-10 (VPS) | $60-120 |
| Easy!Appointments | 1-2 hours | $0 (existing hosting) | $0 |
Persona: Service Business Owner Needing Appointment Booking#
Who They Are#
A small business owner or office manager at a service business: a hair salon, dental clinic, tutoring center, fitness studio, massage practice, or veterinary clinic. They need customers to book appointments online rather than calling.
They are NOT developers. They may have a web designer or IT contractor who helps with technology decisions. Their primary concerns are: reliability (bookings must not be lost), ease of use (staff must be able to manage it), and cost (small business margins are tight).
They think in terms of “services” and “providers,” not “event types” and “users.” A salon has haircuts (30 min, $40), coloring (90 min, $120), and consultations (15 min, free) – each offered by specific stylists with individual schedules.
What Pain They Experience#
Phone-Based Scheduling Is Expensive#
A receptionist answering phones and managing a paper appointment book costs $15-20/hour. During busy periods, phones go unanswered and bookings are lost. After hours, customers cannot book at all.
Online booking eliminates the phone bottleneck. Industry data suggests that 40-60% of bookings for service businesses happen outside business hours when phones are not answered.
No-Shows and Cancellations#
Service businesses lose 5-20% of revenue to no-shows. Automated reminders (email or SMS) reduce no-shows by 30-50%. Most scheduling tools include reminder functionality.
Multi-Provider Scheduling Complexity#
A salon with 5 stylists, each with different skills and schedules, creates a complex scheduling matrix. Customers want “any available stylist for a haircut on Saturday morning” – which requires checking all 5 stylists’ availability simultaneously.
Existing Calendar Integration#
Staff already use personal calendars (Google Calendar, Apple Calendar). They need the booking system to sync with these calendars so personal appointments block out booking time automatically.
What They Need#
Must-Have#
- Service catalog: Define services with duration and price
- Provider schedules: Individual working hours per staff member
- Online booking page: Customer-facing, mobile-friendly
- Email confirmations: To customer and provider
- Calendar sync: At least Google Calendar
- Admin panel: For staff to manage bookings, view schedules
- Reliability: Bookings must not be lost or double-booked
Nice-to-Have#
- SMS reminders
- Payment/deposit collection
- Customer accounts and history
- Multiple location support
- Walk-in management (track non-booked appointments)
- Reporting (revenue, utilization, no-show rates)
- Embed widget for existing website
Recommended Path#
Option A: Easy!Appointments (Best Fit for Domain)#
Easy!Appointments was designed for exactly this use case:
- Install on PHP hosting (existing web hosting likely works)
- Define services with duration and pricing
- Create provider accounts with individual schedules
- Configure Google Calendar sync per provider
- Share booking page URL with customers
- Staff manages via admin panel
Advantages:
- Domain model matches service businesses perfectly
- Runs on cheap PHP hosting
- Simple enough for non-technical staff
- Google Calendar sync for providers
- Free (GPL-3.0)
Disadvantages:
- Dated UI (may look unprofessional)
- Google Calendar only
- No SMS reminders
- No payment integration
- No embed widget
Option B: cal.com (If Modern UX Matters)#
If the business needs a modern, polished booking experience:
- Deploy cal.com (Docker on VPS, or use cal.com Cloud)
- Create event types for each service
- Set up team scheduling (round-robin for “any provider”)
- Configure calendar integrations for each provider
- Embed booking widget on business website
Advantages:
- Modern, professional UI
- Multiple calendar providers (Google, Outlook)
- Embed widget for existing website
- Video conferencing (for virtual consultations)
- Team scheduling
Disadvantages:
- Heavier infrastructure than Easy!Appointments
- Service/provider model must be mapped to cal.com’s event-type model
- More complex setup for non-technical staff
- AGPL license (not relevant for most service businesses)
Option C: Commercial Booking Software (When DIY Is Wrong)#
For businesses where reliability is paramount and budget allows:
- Acuity Scheduling ($16/month): Full-featured, designed for service businesses
- Square Appointments (free for solo, $29/month for teams): If already using Square for payments
- SimplyBook.me ($8.25/month): European, GDPR-focused
Honesty check: Most service businesses should use commercial booking software unless they have a specific reason to self-host (data sovereignty, customization needs, principle). The cost of commercial tools is less than the cost of troubleshooting self-hosted infrastructure.
Anti-Recommendations#
Do not build from scratch. A service business has zero reason to custom-develop scheduling software.
Do not use Calendly/cal.com without adaptation. Their event-type model works for consultants but is awkward for service businesses with multiple providers and services. Easy!Appointments or commercial booking software fits better.
Do not deploy without email/SMS reminders. The single biggest ROI from online booking is reduced no-shows via automated reminders. If the chosen tool does not support this, add it via a third-party service (Twilio for SMS, transactional email for email).
Do not ignore mobile. 60-70% of service business bookings happen on mobile devices. The booking page must be mobile-responsive.
Cost Comparison#
| Approach | Setup Effort | Monthly Cost | No-Show Reduction |
|---|---|---|---|
| Easy!Appointments | 2-4 hours (IT person) | $0-5 (hosting) | Moderate (email only) |
| cal.com self-hosted | 4-8 hours (IT person) | $10-20 (VPS) | Moderate (email) |
| Acuity Scheduling | 30 min | $16+ | High (email + SMS) |
| Square Appointments | 30 min | $0-29 | High (email + SMS) |
Persona: Team Lead Coordinating Group Meetings#
Who They Are#
A team lead, project manager, or office manager who regularly needs to schedule meetings with 3-15 people. They organize weekly team standups, sprint planning sessions, retrospectives, cross-team syncs, and all-hands meetings.
They are not necessarily technical. They use Google Calendar or Outlook daily. Their primary frustration is the time spent coordinating schedules across multiple people, especially when participants are in different timezones.
They are looking for something better than the “email chain asking for availability” pattern, and ideally something that does not require everyone to sign up for yet another service.
What Pain They Experience#
The Coordination Tax#
Scheduling a meeting with 8 people currently looks like:
- Send email asking for availability next week
- Wait 1-3 days for responses (some never respond)
- Manually cross-reference 8 schedules
- Find a time that works for most (rarely all)
- Send meeting invitation
- Handle “actually that doesn’t work” replies
- Repeat
This process takes 30-60 minutes per meeting and may need to be repeated weekly. For a team lead scheduling 3-5 group meetings per week, this is 2-5 hours/week of pure coordination overhead.
The Timezone Problem#
Distributed teams across timezones make the coordination exponentially harder. “Tuesday afternoon” means different things in San Francisco, London, and Tokyo. The team lead must mentally convert between 3+ timezones while cross-referencing availability.
The Tool Fatigue Problem#
Team members already use email, Slack, Jira, Google Calendar, and numerous other tools. Asking them to sign up for another scheduling service meets resistance. The ideal tool requires zero accounts from participants.
Recurring Meeting Rescheduling#
When a recurring meeting needs to be moved (holiday, conflict), the team lead must re-coordinate everyone’s schedule for the new time. There is no good tool for “find a new time for this week’s standup.”
What They Need#
Must-Have#
- Group availability finding across 3-15 people
- No-account participation (share a link, people respond)
- Timezone-aware (automatic conversion for distributed teams)
- Fast response cycle (results in hours, not days)
- Simple UX (no training needed for participants)
Nice-to-Have#
- Calendar integration (auto-fill busy times from Google/Outlook)
- Automatic meeting invitation creation after decision
- Recurring poll templates
- Slack/Teams integration (share polls in channels)
- Mobile-friendly
Recommended Path#
Option A: Rallly (Best Fit)#
Rallly directly addresses this use case:
- Create a poll with proposed times
- Share the link in Slack/email
- Participants vote (no account needed)
- See which time has the most votes
- Finalize and manually create calendar event
Advantages:
- No accounts required for participants
- Timezone-aware (each participant sees their local time)
- Self-hostable for data control
- Clean, simple UX
- Free (AGPL self-hosted, or free tier on rallly.co)
Disadvantages:
- No calendar integration (participants vote manually)
- No automatic calendar event creation after decision
- No Slack integration
- Each scheduling decision requires a new poll
- Organizer must manually check that the chosen time actually works for everyone’s calendar
Option B: schej.it (If Visual Overlap Matters)#
For teams that prefer the When2meet paradigm:
- Create an event with a date/time range
- Share link with team
- Participants mark available times on a grid
- Visual overlay shows common free times
Advantages:
- Visual approach is intuitive
- Google Calendar import reduces manual entry
- MIT license
Disadvantages:
- Small project, uncertain maintenance
- Google Calendar only
- No automatic booking
- Less polished than Rallly
Option C: Microsoft FindTime (If on Microsoft 365)#
For teams fully in the Microsoft ecosystem:
- FindTime is a Microsoft add-in that integrates into Outlook
- Automatically reads participants’ Outlook calendars
- Proposes times based on actual availability
- Creates meeting when consensus is reached
This is the closest to “magic” for group scheduling, but requires everyone to be on Microsoft 365.
Option D: Doodle (When Self-Hosting Is Not Required)#
If self-hosting is not a requirement:
- Doodle remains the most recognized group scheduling tool
- Free tier allows basic polls
- Premium ($6.95/user/month) adds calendar integration
- No self-hosting option
Anti-Recommendations#
Do not use Calendly/cal.com for group scheduling. They are designed for 1-on-1 booking (one host, one guest), not finding a time that works for 8 people. cal.com’s “collective” event type requires all participants to be cal.com users.
Do not send email polls (“Reply with your availability”). The replies are unstructured, hard to cross-reference, and people forget to respond. Even a simple Google Form is better than email.
Do not build a custom tool for this use case unless you have very specific requirements. Rallly or Doodle covers 95% of group scheduling needs.
Do not require participants to create accounts. The friction of account creation kills response rates. Rallly’s no-account design is a key advantage.
The Missing Tool#
What team leads actually want does not fully exist:
- Reads all participants’ calendars automatically
- Proposes times based on actual availability (not manual voting)
- Works across Google Calendar AND Outlook
- Requires no accounts for participants
- Creates the calendar event automatically
Microsoft FindTime comes closest but is Microsoft-only. Google Calendar has “Find a time” but is Google-only. No cross-provider tool does this for external participants without requiring accounts.
This gap represents a significant opportunity in the scheduling tool space.
Persona: Privacy-Conscious Developer Avoiding SaaS#
Who They Are#
A developer who is philosophically committed to self-hosting and data sovereignty. They run their own email server (or use Fastmail/Proton), use CalDAV for calendaring (Nextcloud, Radicale, Baikal), and avoid sending data to commercial cloud services when alternatives exist.
They may be motivated by:
- GDPR compliance requirements (EU-based, handling EU citizen data)
- Security work (handling sensitive client data)
- Philosophical commitment to software freedom
- Institutional policy (academic, government, healthcare)
- Simply wanting to understand and control their infrastructure
They are highly technical and willing to trade convenience for control. They will spend a weekend setting up infrastructure that a SaaS product would provide in 10 minutes, because the SaaS product does not meet their data handling requirements.
What Pain They Experience#
Calendar Data Is Sensitive#
Meeting schedules reveal:
- Who you meet with (relationships, business dealings)
- When you are busy vs. free (activity patterns)
- Where meetings happen (locations, travel patterns)
- What meetings are about (titles, descriptions)
Sending this data to Calendly, Google, or any SaaS is a privacy exposure. For lawyers, therapists, journalists, and activists, this exposure can have real consequences.
Most Scheduling Tools Require Cloud Accounts#
Every mainstream scheduling tool requires connecting to Google Calendar or Microsoft Outlook via OAuth. This means:
- Calendar data flows through the scheduling tool’s servers
- OAuth tokens give the tool ongoing access to the calendar
- The scheduling tool can read ALL calendar data, not just availability
Even cal.com (self-hosted) requires OAuth tokens for Google/Microsoft, though the tokens stay on your server rather than a SaaS provider’s.
CalDAV Scheduling Is Underserved#
If they already use CalDAV (Nextcloud, Baikal, Radicale), they want scheduling that works within the CalDAV ecosystem. But CalDAV scheduling (RFC 6638) is poorly implemented in client tools, and most scheduling platforms do not support it as a primary integration.
Self-Hosted Options Leak Data#
Even self-hosted scheduling tools often depend on external services:
- Google OAuth requires talking to Google’s servers
- Email delivery often uses commercial services (SendGrid, SES)
- Video conferencing links require Zoom/Meet/Teams accounts
- DNS and domain registration create metadata trails
True self-hosting requires careful evaluation of every external dependency.
What They Need#
Must-Have#
- Self-hostable with no external service dependencies (or minimal)
- CalDAV integration (their primary calendar protocol)
- No Google/Microsoft OAuth required (or at minimum, optional)
- Data stays on their server (no data exfiltration to third parties)
- Open source with auditable code
- Standard protocols (CalDAV, iMIP) over proprietary APIs
Nice-to-Have#
- Federation support (scheduling across CalDAV servers)
- Free/busy without revealing event details
- Encryption at rest for booking data
- Tor/onion service compatibility
- No JavaScript required for booking (progressive enhancement)
Recommended Path#
Option A: cal.com Self-Hosted + CalDAV Only (Recommended)#
cal.com supports CalDAV as a calendar provider:
- Deploy cal.com on your own server (Docker)
- Connect CalDAV calendar (Nextcloud/Baikal/Radicale)
- Skip Google/Microsoft OAuth (not needed if you only use CalDAV)
- Configure SMTP via your own mail server
- Use a self-hosted video solution (Jitsi) if needed
Data flow: All data stays on your server. CalDAV connection is direct to your calendar server. No external API calls required.
Disadvantage: Guests who book must interact with your cal.com instance (their data passes through your server, which is fine – you control it).
Option B: iMIP (Email-Based Scheduling)#
For the most privacy-conscious setup – scheduling via email:
- Define availability on a static web page or CalDAV VAVAILABILITY
- Guests email you with preferred times
- You respond with a METHOD:REQUEST iCalendar attachment
- They Accept/Decline via their email client (iMIP)
- Calendar event created on both sides via standard email
Technical implementation:
- Python: icalendar library to generate iMIP messages
- Email: Your own SMTP server for delivery
- No web application needed
Advantages: Maximum privacy. No web app, no database, no OAuth. Just email and standard calendar protocols.
Disadvantages: Manual process. No automated availability display. Does not scale beyond a few meetings per week.
Option C: CalDAV Free/Busy + Simple Booking Page#
Build a minimal scheduling page that reads CalDAV free/busy:
- Backend queries your CalDAV server for free/busy data
- Frontend displays available slots (derived from free/busy)
- Guest selects a slot and provides email
- Backend creates event on your CalDAV calendar
- Backend sends iMIP invitation to guest via email
Libraries needed:
- Python: caldav (CalDAV client), icalendar (ICS generation), Flask/FastAPI (web framework)
- OR TypeScript: tsdav (CalDAV client), ical-generator (ICS), Express/Next.js
Advantages: Standard protocols only. No Google/Microsoft OAuth. All data on your server. Free/busy reveals only busy/free status, not event details.
Disadvantages: 2-3 weeks of development. Only works with CalDAV calendars.
Option D: Rallly Self-Hosted (For Group Scheduling)#
If the need is group scheduling (not individual booking):
- Deploy Rallly (Docker)
- No calendar integration needed (participants vote manually)
- No OAuth, no external services
- SMTP via your own mail server
Advantages: Simple deployment, no external dependencies, participants share no calendar data.
Disadvantages: No calendar integration, manual process, AGPL license.
Anti-Recommendations#
Do not assume CalDAV scheduling (RFC 6638) will work with external participants. If your guests use Google or Microsoft calendars, CalDAV scheduling will not reach them. Use iMIP (email) for cross-provider invitations.
Do not deploy cal.com with Google/Microsoft OAuth if your goal is avoiding those platforms. The CalDAV-only setup is sufficient for CalDAV users.
Do not over-engineer privacy. If the threat model is “I don’t want SaaS companies reading my calendar,” self-hosted cal.com with CalDAV is sufficient. If the threat model is “state-level adversary,” that requires a different conversation beyond scheduling tools.
Do not sacrifice usability completely for privacy. If your scheduling process is so difficult that people resort to email back-and-forth, you have not improved anything.
Persona: Enterprise IT Administrator Deploying Scheduling#
Who They Are#
An IT administrator or DevOps engineer at a mid-to-large organization (100-5,000 employees) tasked with deploying a scheduling solution for the company. The request typically comes from sales teams, customer success, or recruiting – departments where external meeting scheduling is a daily workflow.
They care about: SSO integration, audit logging, compliance (SOC 2, GDPR, HIPAA), scalability, supportability, and total cost of ownership. They will choose a solution they can maintain, secure, and support with their existing infrastructure.
They are evaluating “buy vs. build vs. deploy-and-configure” and need to present options to management with clear cost/benefit analysis.
What Pain They Experience#
Shadow IT Scheduling#
Without an official scheduling tool, employees sign up for Calendly, TidyCal, SavvyCal, and other tools using personal accounts. This creates:
- Data scattered across multiple SaaS vendors
- No central audit trail
- Inconsistent branding
- Compliance risks (customer data in unvetted SaaS)
- No SSO (users create separate passwords)
Microsoft/Google Calendar Dependency#
The organization uses Microsoft 365 or Google Workspace. Any scheduling tool must integrate deeply with the corporate calendar provider. IT needs to control which app permissions are granted via OAuth admin consent, not per-user consent.
Scale and Multi-Team Requirements#
A sales team of 50 people needs round-robin scheduling. Recruiting needs interview scheduling with panel coordination. Customer success needs one-on-one check-in booking. Each department has different scheduling requirements.
Compliance Requirements#
Depending on industry:
- SOC 2: Audit logging, access controls, data encryption
- GDPR: Data residency, deletion on request, consent management
- HIPAA: PHI protection, business associate agreements
- Data sovereignty: Data must stay in specific geographic regions
Most SaaS scheduling tools can provide SOC 2 reports. Self-hosted solutions put compliance in the organization’s hands.
What They Need#
Must-Have#
- SSO integration (SAML/OIDC with corporate IdP)
- Admin controls (manage event types, users, permissions centrally)
- Calendar integration (Microsoft 365 or Google Workspace)
- Audit logging (who booked what, when, changes)
- Scalable (50-500 users without architectural changes)
- Supportable (documentation, SLA, or responsive maintainers)
- Embeddable (for corporate website booking pages)
Nice-to-Have#
- SCIM provisioning (auto-create/disable accounts from IdP)
- Data residency controls (EU, US, etc.)
- Custom compliance reporting
- API for integration with CRM (Salesforce, HubSpot)
- White-labeling (remove vendor branding)
- Multi-tenant (separate configurations per department)
Recommended Path#
Option A: cal.com Enterprise (Recommended for Most)#
cal.com offers an enterprise tier with features specifically for organizational deployment:
Enterprise features:
- SSO (SAML, OIDC)
- SCIM provisioning
- Audit logging
- Admin console (manage users, event types, organization settings)
- Managed event types (admin-created templates for the organization)
- Directory sync
- Custom compliance configurations
- Dedicated support
Deployment options:
- cal.com Cloud Enterprise (managed, SOC 2 compliant)
- Self-hosted with Enterprise license (data stays on your infra)
Licensing: Commercial enterprise license (removes AGPL, adds enterprise features). Pricing is per-user, contact sales.
Advantages:
- Most complete enterprise scheduling platform
- Both cloud and self-hosted options
- Active development (weekly releases)
- Large community reduces single-vendor risk
- API for CRM/HR system integration
Disadvantages:
- Enterprise pricing may be significant (comparable to Calendly Teams)
- Self-hosted still requires PostgreSQL + Redis + Node.js infrastructure
- AGPL for non-enterprise self-hosting is a legal concern
Option B: Calendly Teams / Enterprise (Buy)#
If self-hosting is not required and budget allows:
- Calendly Teams: $16/user/month
- Calendly Enterprise: Custom pricing (SSO, admin, analytics)
- SOC 2 Type II certified
- No infrastructure to manage
Advantages: Zero maintenance, proven at scale, comprehensive feature set, dedicated support.
Disadvantages: Per-user monthly cost (50 users = $800+/month), no data sovereignty, vendor lock-in.
Option C: Self-Hosted cal.com (AGPL) with Custom SSO#
For organizations that cannot purchase enterprise license but need self-hosting:
- Deploy cal.com under AGPL (must share modifications)
- Add SSO via reverse proxy (OAuth2-proxy or similar)
- Manage users manually or via API scripts
- No enterprise admin console, audit logging, or SCIM
Advantages: Free (no licensing cost), full data control.
Disadvantages: No enterprise features, AGPL compliance required (must share modifications), limited central administration, no vendor support.
Suitable for: Non-commercial organizations (universities, non- profits) where AGPL is acceptable and enterprise features are not mandatory.
Anti-Recommendations#
Do not deploy Easy!Appointments for enterprise use. It lacks SSO, audit logging, team scheduling, and the architecture does not scale to 100+ users with different scheduling needs.
Do not underestimate OAuth admin consent. Connecting cal.com to Microsoft 365 requires Azure AD app registration with admin consent (not just user consent). Coordinate with the Azure AD admin before deployment.
Do not deploy self-hosted AGPL cal.com and assume it is equivalent to Enterprise. The enterprise features (SSO, SCIM, audit logging, admin console) are not in the AGPL version. Evaluate whether these features are must-have for your compliance requirements.
Do not build a custom scheduling tool. The engineering cost of building enterprise-grade scheduling (SSO, audit logging, multi- provider calendar integration, team scheduling) far exceeds the cost of licensing cal.com Enterprise or subscribing to Calendly Enterprise.
Total Cost of Ownership (50 Users, Annual)#
| Approach | Licensing | Infrastructure | Engineering | Total |
|---|---|---|---|---|
| Calendly Enterprise | ~$15K+ | $0 | $0 | ~$15K+ |
| cal.com Cloud Enterprise | Similar | $0 | $0 | Similar |
| cal.com Self-Hosted Enterprise | License + hosting | ~$1.2K | ~$5K (setup) | Varies |
| cal.com AGPL (no enterprise) | $0 | ~$1.2K | ~$10K (setup + SSO) | ~$11K |
| Build from scratch | $0 | ~$2K | ~$100K+ | $100K+ |
S3: Need-Driven Discovery - Meeting Scheduling Libraries#
Objective#
Identify WHO needs meeting scheduling tools and WHY. Map personas to specific library/platform recommendations based on their constraints, not just their feature wish lists.
Personas Analyzed#
- Indie SaaS developer building a product with scheduling as a core feature
- Freelancer/consultant wanting a self-hosted Calendly alternative for personal use
- Service business owner (salon, clinic, tutoring) needing appointment booking
- Team lead/office manager coordinating recurring group meetings
- Privacy-conscious developer avoiding SaaS data collection
- Enterprise IT administrator deploying scheduling for an organization
Analysis Framework#
For each persona:
- Who they are (background, technical skill, constraints)
- What pain they experience (specific problems, not generic)
- What they need (must-have vs. nice-to-have)
- Recommended path (specific tools/libraries with rationale)
- Anti-recommendations (what looks tempting but will waste their time)
S3 Recommendation: Meeting Scheduling by Persona#
Persona-to-Tool Mapping#
| Persona | Primary Recommendation | Alternative |
|---|---|---|
| Indie SaaS developer | cal.com API/embed | Nylas/Cronofy + custom |
| Freelancer/consultant | cal.com self-hosted | TidyCal ($29 one-time) |
| Service business | Easy!Appointments | cal.com (if modern UX needed) |
| Team lead (group scheduling) | Rallly | Doodle (if no self-hosting need) |
| Privacy-conscious developer | cal.com + CalDAV only | iMIP (email-based) |
| Enterprise IT admin | cal.com Enterprise | Calendly Enterprise |
Cross-Cutting Insights#
1. cal.com Is the Default Answer#
For 4 of 6 personas, cal.com is the primary or alternative recommendation. Its breadth of features and deployment flexibility (self-hosted, cloud, enterprise, embed, API) make it the “safe” choice for most scheduling needs.
2. The Build-vs-Deploy Line Is Clear#
Building scheduling from scratch makes sense only when:
- AGPL is incompatible with your licensing (and enterprise license budget is not available)
- Your tech stack cannot accommodate a Node.js application
- You need a tiny subset of scheduling functionality
- You are building scheduling as the product (not as a feature)
For everyone else, deploying cal.com or using its API is more cost-effective.
3. Group Scheduling Is a Different Problem#
Slot-based tools (cal.com, Calendly) are wrong for group scheduling. Poll-based tools (Rallly, Doodle) are right. These are fundamentally different paradigms, not a feature gap in slot-based tools.
4. Calendar Integration Is the Hard Tax#
Every persona except the team lead (Rallly) needs calendar integration. This is the most expensive component in any scheduling solution:
- Google Calendar API: 3-5 days to integrate
- Microsoft Graph API: 3-5 days to integrate
- CalDAV: 2-3 days to integrate
- All three: 8-13 days, plus ongoing maintenance
Using a platform (cal.com) or aggregator (Nylas, Cronofy) avoids this tax.
5. Privacy Needs Are Addressable#
Self-hosted cal.com with CalDAV-only configuration (no Google/Microsoft OAuth) provides a genuinely privacy-respecting scheduling solution. The common perception that scheduling tools require handing data to cloud providers is false – it just requires more careful configuration.
6. The Service Business Gap#
cal.com’s event-type model does not naturally map to service businesses (services + providers + customers). Easy!Appointments fills this gap but with dated architecture. There is room for a modern, self-hosted booking system with a service-business domain model.
Unserved Needs#
- Cross-provider group availability (read Google + Outlook calendars without accounts, find common free time)
- Calendar overlay UX (SavvyCal’s innovation, no OSS equivalent)
- Lightweight scheduling component (React/Vue component, not full platform)
- Modern service-business booking (Easy!Appointments’ domain model with modern architecture)
- Recurring group scheduling (find a new time for this week’s standup, not just one-off polls)
S4: Strategic
Platform Viability Assessment#
cal.com#
Maintainer Health#
- Bus factor: High (600+ contributors, core team of 15-20)
- Funding: VC-backed (Series A, $25M+), sustainable runway
- Governance: Company-led open source (Cal.com, Inc.)
- Release cadence: Weekly releases, active development
- Community: 5K+ Discord members, active GitHub discussions
Ecosystem Momentum#
- Stars: 35K+ (top 500 on GitHub by stars)
- Growth: ~50% YoY star growth (2024-2025)
- Adoption: Used by recognizable companies (Product Hunt, Vercel)
- Ecosystem: Growing app marketplace (40+ integrations)
- Talent: TypeScript/Next.js stack attracts contributors
Risk Assessment#
License change risk (Medium): cal.com uses AGPL-3.0, which is irrevocable for released versions. However, the company controls the codebase and could change the license for future versions (as other VC-backed OSS companies have done – Redis, Elastic, MongoDB). The AGPL already limits commercial use, reducing the pressure for license tightening.
Business model sustainability (Low-Medium): VC funding creates pressure to grow revenue. cal.com monetizes through cloud hosting and enterprise licenses. If cloud revenue underperforms VC expectations, the company could: (a) raise prices, (b) move features from OSS to proprietary, or (c) pivot. All are survivable for self-hosters because AGPL guarantees access to the last open-source version.
Technical debt accumulation (Medium): The monorepo has grown significantly (~500K lines). Rapid feature development may accumulate technical debt that makes self-hosting harder over time (more dependencies, more complex configuration, higher resource requirements).
Competition from Calendly (Low): Calendly is a mature SaaS product with a different market (convenience buyers vs. control/cost-conscious buyers). The two products serve overlapping but distinct markets. Calendly going free would hurt cal.com’s cloud business but not the self-hosted use case.
Strategic Assessment#
3-year outlook: Strong. VC funding, large community, and growing enterprise adoption provide a solid foundation. The AGPL license ensures the OSS version remains available even if the company pivots.
5-year outlook: Moderate. VC-backed OSS companies face a reckoning between community expectations and investor returns. cal.com is better positioned than most (AGPL already limits freeloading, enterprise tier provides revenue), but the pressure exists.
Recommendation: Use cal.com with confidence for 3-year planning horizons. For 5+ year bets, prefer self-hosted deployment with version pinning over cloud dependency.
Rallly#
Maintainer Health#
- Bus factor: Low (primary developer: Luke Vella)
- Funding: Sponsorships + rallly.co hosted service revenue
- Governance: Single-maintainer open source
- Release cadence: Regular but not frequent (monthly)
- Community: 80+ contributors, active GitHub Discussions
Ecosystem Momentum#
- Stars: 3.6K (modest but growing)
- Growth: Steady since 2022 rewrite
- Adoption: Self-hosted community, rallly.co hosted users
- Niche: Clear leader in OSS poll-based scheduling
Risk Assessment#
Single maintainer (High): Luke Vella is the primary developer. If he steps away, the project’s future is uncertain. The Next.js/Prisma codebase is accessible to other developers, but no succession plan is visible.
Revenue sustainability (Medium): rallly.co hosted service provides some revenue, but poll-based scheduling has low willingness-to-pay (Doodle’s free tier is the main competitor). Sustained development depends on the maintainer’s motivation.
Feature stagnation (Medium): Rallly does one thing well but has clear feature gaps (no API, no calendar integration, no event creation). If these gaps are not addressed, users may look elsewhere.
Strategic Assessment#
3-year outlook: Moderate. The project is healthy today but depends heavily on one person. For production use, fork insurance is advisable.
5-year outlook: Uncertain. Single-maintainer projects have unpredictable lifespans. The codebase is small enough (~50K lines) that forking and maintaining is feasible.
Recommendation: Use Rallly for self-hosted group scheduling. Maintain a fork as insurance. Contribute back to improve sustainability.
Easy!Appointments#
Maintainer Health#
- Bus factor: Low (primary developer: Alex Tselegidis)
- Funding: Donations only
- Governance: Single-maintainer open source
- Release cadence: 2-3 releases per year
- Community: 60+ contributors, mostly translators
Ecosystem Momentum#
- Stars: 3.2K (stable, slow growth)
- Growth: Minimal (mature project, stable feature set)
- Adoption: Service businesses, self-hosted community
- Niche: PHP appointment booking
Risk Assessment#
Architecture aging (High): CodeIgniter 3 is no longer maintained. jQuery frontend is dated. The architecture will increasingly struggle to attract contributors who expect modern frameworks.
Stagnation (High): The feature set has been stable for years. No new calendar integrations (still Google-only), no embed widget, no modern frontend. The project is functional but not evolving.
Migration risk (Low for existing users): The application is stable and works. Existing deployments will continue to function. The risk is for new adopters who may inherit technical debt.
Strategic Assessment#
3-year outlook: Stable but declining. Existing deployments will continue working. New deployments should consider alternatives.
5-year outlook: Uncertain. The aging architecture limits the project’s future unless a major rewrite occurs.
Recommendation: Use Easy!Appointments for existing PHP deployments where the service-business model fits. For new projects, evaluate cal.com first. Do not invest heavily in Easy!Appointments extensions or customizations.
CalDAV Client Libraries (tsdav, caldav)#
tsdav (TypeScript)#
- Maintainer: Nate Lin (+ cal.com team contributions)
- Bus factor: Low-Medium (maintainer + cal.com dependency ensures attention)
- Stars: 334, growing
- Critical dependent: cal.com uses tsdav for CalDAV operations
- Risk: If cal.com forks or replaces tsdav, the library may lose its primary driver of maintenance
3-year outlook: Strong (cal.com dependency ensures maintenance). 5-year outlook: Dependent on cal.com’s continued use.
caldav (Python)#
- Maintainer: Tobias Brox (python-caldav project)
- Bus factor: Low-Medium (primary maintainer + contributor community)
- Stars: 393, 186K monthly PyPI downloads
- Ecosystem anchor: Primary Python CalDAV client
- Risk: Single maintainer, but CalDAV protocol is stable (no new features to implement, just maintenance)
3-year outlook: Strong (stable protocol, active maintenance). 5-year outlook: Moderate (depends on maintainer availability, but CalDAV protocol stability means less maintenance needed).
Calendar API Aggregators (Nylas, Cronofy)#
Nylas#
- Company restructured in 2024 (acquired by Oracle calendar assets, management changes)
- Risk: Corporate restructuring creates uncertainty about API stability and pricing
- SDK: MIT-licensed (survives company changes)
- Recommendation: Use with caution; have a migration plan to direct integrations if Nylas changes terms
Cronofy#
- Stable European company focused on scheduling APIs
- Risk: Smaller company, less public financial information
- SDK: MIT-licensed
- Recommendation: Viable alternative to Nylas, especially for EU data residency requirements
Strategic Implication#
Calendar API aggregators solve a real problem (multi-provider integration) but create vendor dependency. The strategic hedge is:
- Use the aggregator for speed-to-market
- Abstract the aggregator behind your own interface
- Maintain the ability to replace with direct integrations if needed
Ecosystem Trends and Strategic Outlook#
Trend 1: Scheduling as Infrastructure#
What Is Happening#
Scheduling is moving from a standalone product category (Calendly, SavvyCal) to an infrastructure layer that other products embed. cal.com’s API and embed widget, Nylas’s Scheduler component, and Cronofy’s Real-Time Scheduling all point toward scheduling-as-a-service.
Why It Matters#
Developers increasingly want to ADD scheduling to their product, not DEPLOY a scheduling product. The winners in this space will be the tools that are easiest to embed, not the tools with the most standalone features.
Implications for Library Choice#
- Favor tools with APIs and embed capabilities (cal.com, Nylas, Cronofy)
- Avoid tools that are standalone-only (Easy!Appointments, Rallly)
- Watch for headless scheduling engines (scheduling logic without UI, API-first) – this is the gap in the current ecosystem
Timeline#
Already happening. cal.com’s Platform product (headless scheduling API) launched in 2024. Expect this trend to accelerate through 2026-2028.
Trend 2: AI-Assisted Scheduling#
What Is Happening#
AI assistants (ChatGPT, Claude, Google Gemini) are being integrated into scheduling workflows:
- “Schedule a meeting with Alice next week” (natural language booking)
- AI assistants that negotiate meeting times across email
- Automated meeting preparation (find mutual availability, suggest times)
- Smart scheduling that learns preferences over time
Why It Matters#
AI-assisted scheduling could reduce or eliminate the need for scheduling links entirely. Instead of sharing a booking page, you tell your AI assistant to “find a time with Bob” and it handles the negotiation.
Implications for Library Choice#
- Tools with APIs will benefit (AI needs programmatic access)
- Scheduling pages may become less important (AI replaces the UI)
- Calendar integration becomes MORE important (AI needs to read/write calendars)
- iMIP may get a renaissance (AI-to-AI scheduling over email using standard protocols)
Timeline#
Early stages (2025-2026). Google Calendar’s “Help me schedule” and Microsoft Copilot’s calendar features are the vanguard. Expect meaningful impact on scheduling workflows by 2027-2028.
Trend 3: Standards Convergence (Slow)#
What Is Happening#
The IETF is working on JMAP for Calendars (draft-ietf-jmap-calendars), a modern JSON-based protocol intended to replace/supplement CalDAV. JMAP promises simpler implementation and better compatibility with modern web architectures.
Additionally, CalDAV adoption is slowly improving as more services implement it (Fastmail, Proton Mail, Nextcloud growth).
Why It Matters#
If JMAP for Calendars gains adoption, it could provide a unified protocol for calendar operations that works across providers – the dream that CalDAV partially fulfilled but failed to universalize.
Implications for Library Choice#
- Do not bet on JMAP yet (still in draft, minimal implementation)
- CalDAV remains the pragmatic standards-based choice
- Provider-specific APIs (Google, Microsoft) will dominate for years
- Watch Fastmail (JMAP pioneer, their calendar JMAP implementation is the reference)
Timeline#
Long-term (2028+). JMAP for Calendars needs Google or Microsoft adoption to matter. This is unlikely before 2028.
Trend 4: Self-Hosted Renaissance#
What Is Happening#
Growing distrust of SaaS (privacy concerns, vendor lock-in, enshittification) is driving interest in self-hosted alternatives. Docker and infrastructure- as-code make self-hosting more accessible than ever.
Why It Matters#
Projects like cal.com and Rallly benefit directly from this trend. The gap between SaaS UX and self-hosted UX is narrowing – cal.com self-hosted is arguably as polished as Calendly.
Implications for Library Choice#
- Self-hostable tools have a structural tailwind
- Docker Compose deployment is the minimum bar for self-hosted adoption
- Documentation quality for self-hosting is a differentiator
- AGPL license is increasingly accepted in the self-hosting community
Timeline#
Ongoing trend. Expect continued growth in self-hosted scheduling adoption through 2026-2030.
Trend 5: Vertical Specialization#
What Is Happening#
General-purpose scheduling tools (Calendly, cal.com) compete with vertical-specific booking systems:
- Healthcare: Jane, Cliniko, SimplePractice (HIPAA-compliant booking)
- Beauty/Wellness: Fresha, Vagaro, Booksy (salon-specific features)
- Education: Calendly + LMS integration, TutorBird
- Fitness: Mindbody, Glofox
Why It Matters#
General-purpose scheduling tools cannot match vertical-specific features (insurance verification for healthcare, product inventory for salons, class capacity for fitness). Vertical tools bundle scheduling with domain-specific features.
Implications for Library Choice#
- For horizontal scheduling needs: cal.com is sufficient
- For vertical needs: Evaluate vertical SaaS first, then cal.com with customization
- Easy!Appointments’ service model is closer to vertical needs than cal.com’s event-type model, but lacks the depth of true vertical tools
Timeline#
Ongoing. Vertical specialization has been happening for years and will continue.
Strategic Summary#
| Trend | Impact on OSS Scheduling | Timing |
|---|---|---|
| Scheduling as infrastructure | High – favors API-first tools | Now |
| AI-assisted scheduling | Medium – reduces need for booking pages | 2027-2028 |
| Standards convergence (JMAP) | Low – too early to matter | 2028+ |
| Self-hosted renaissance | High – tailwind for cal.com, Rallly | Ongoing |
| Vertical specialization | Medium – limits general tools in niches | Ongoing |
The 3-Year Bet#
If you are choosing scheduling infrastructure today for a 3-year horizon:
- cal.com is the safe bet for slot-based scheduling (strong community, funding, feature set)
- Rallly is adequate for poll-based scheduling (fork insurance recommended)
- Direct calendar integrations (Google API + Graph API) are more future-proof than any aggregator
- Standards-based protocols (CalDAV, iMIP) are stable but insufficient alone for universal scheduling
- Watch AI scheduling – it may change the paradigm faster than expected
S4: Strategic Discovery - Meeting Scheduling Libraries#
Objective#
Assess the long-term viability of the key meeting scheduling tools and libraries. Which projects will still be maintained in 3-5 years? Which face existential risks? What ecosystem trends will reshape the landscape?
Scope#
Tier 1 (critical path – must evaluate):
- cal.com (dominant OSS scheduling platform)
- Rallly (leading OSS poll-based scheduler)
- tsdav (CalDAV client, used by cal.com)
Tier 2 (important alternatives):
- Easy!Appointments (PHP booking system)
- caldav (Python CalDAV client)
- Calendar API aggregators (Nylas, Cronofy)
Tier 3 (emerging/niche):
- schej.it (visual availability)
- CalDAV scheduling protocol adoption
Analysis Framework#
For each tool or trend:
- Maintainer health: Bus factor, funding, governance model
- Ecosystem momentum: Growth trajectory, community, adoption
- Risk assessment: What could go wrong in 2-3 years
- Strategic path: Conservative, adaptive, or aggressive recommendation
S4 Recommendation: Strategic Guidance#
Executive Summary#
The meeting scheduling ecosystem is dominated by cal.com for slot-based scheduling and Rallly for poll-based scheduling. Both are viable for 3-year planning horizons. The major ecosystem trends (scheduling-as-infrastructure, AI-assisted scheduling, self-hosting growth) favor tools with APIs, embed capabilities, and self-hosting support – all of which cal.com provides.
Strategic Paths by Risk Tolerance#
Conservative Path (Minimize Risk)#
Goal: Minimize dependency on any single project or vendor.
Approach:
- Use cal.com self-hosted with version pinning
- Maintain your own fork as insurance
- Build calendar integrations directly (Google API, Graph API) rather than through aggregators
- Use CalDAV + iMIP for standards-based scheduling where possible
- Keep scheduling logic in your own application, use cal.com only for the booking UI
Trade-off: More engineering effort upfront, maximum long-term control.
Best for: Organizations with engineering capacity that need 5+ year scheduling infrastructure.
Adaptive Path (Balance Risk and Speed)#
Goal: Ship quickly while maintaining the ability to change direction.
Approach:
- Use cal.com (cloud or self-hosted) as primary scheduling platform
- Use cal.com API for programmatic scheduling
- Abstract calendar integrations behind your own interface (even if cal.com handles them today)
- Monitor cal.com’s license and business trajectory
- Have a migration plan (know what it would take to replace cal.com)
Trade-off: Faster time-to-market, moderate dependency on cal.com.
Best for: Startups and mid-stage companies where scheduling is a feature, not the product.
Aggressive Path (Maximize Speed)#
Goal: Ship scheduling as fast as possible, optimize later.
Approach:
- Use cal.com Cloud (managed service)
- Embed scheduling widget in your application
- Use Nylas or Cronofy for any custom calendar integrations
- Accept vendor dependencies in exchange for development speed
Trade-off: Maximum speed, maximum dependency.
Best for: Early-stage startups validating product-market fit where scheduling is important but not the core value proposition.
Library-Level Strategic Recommendations#
cal.com#
| Dimension | Assessment |
|---|---|
| 3-year viability | Strong |
| 5-year viability | Moderate-Strong |
| Lock-in risk | Medium (AGPL ensures access to OSS version) |
| Migration difficulty | High (deeply integrated platform) |
| Recommendation | Use with confidence; prefer self-hosted for control |
Rallly#
| Dimension | Assessment |
|---|---|
| 3-year viability | Moderate |
| 5-year viability | Uncertain (single maintainer) |
| Lock-in risk | Low (simple data model, easy to replace) |
| Migration difficulty | Low (polls are ephemeral by nature) |
| Recommendation | Use for group scheduling; maintain a fork |
Easy!Appointments#
| Dimension | Assessment |
|---|---|
| 3-year viability | Moderate (stable but stagnating) |
| 5-year viability | Low (aging architecture) |
| Lock-in risk | Low |
| Migration difficulty | Low-Medium |
| Recommendation | Use for existing PHP deployments only; do not start new projects |
tsdav#
| Dimension | Assessment |
|---|---|
| 3-year viability | Strong (cal.com dependency ensures maintenance) |
| 5-year viability | Moderate (dependent on cal.com’s continued use) |
| Lock-in risk | Low (standard CalDAV protocol, replaceable) |
| Migration difficulty | Low |
| Recommendation | Use for TypeScript CalDAV operations |
caldav (Python)#
| Dimension | Assessment |
|---|---|
| 3-year viability | Strong |
| 5-year viability | Moderate (stable protocol reduces maintenance need) |
| Lock-in risk | Low (standard protocol) |
| Migration difficulty | Low |
| Recommendation | Use as the Python CalDAV client |
Nylas / Cronofy#
| Dimension | Assessment |
|---|---|
| 3-year viability | Moderate (commercial companies, restructuring risks) |
| 5-year viability | Uncertain (dependent on business viability) |
| Lock-in risk | High (proprietary backend, difficult to replace) |
| Migration difficulty | High (must rebuild all calendar integrations) |
| Recommendation | Use for speed-to-market; abstract behind interface for migration readiness |
The Key Strategic Insight#
The meeting scheduling space is unusual in open source: a single project (cal.com) is so far ahead of alternatives that the strategic question is rarely “which library?” but rather “can I use cal.com, and if not, why not?”
The valid reasons NOT to use cal.com are:
- AGPL is incompatible with your licensing
- You need a non-Node.js tech stack
- You need only poll-based scheduling (use Rallly)
- You need only a tiny scheduling feature (building from scratch is simpler)
- You need deep service-business domain modeling (use Easy!Appointments or a vertical SaaS)
For everything else, cal.com is the strategic default.