Blog

How to Build a Calendly Clone with Bubble

Sep 20, 2025

Calculating...

Calculating...

Harish Malhi - founder of Goodspeed

Founder of Goodspeed

How to Build a Calendly Clone with Bubble – Goodspeed Studio blog

A technical guide to building a Calendly-style scheduling app on Bubble, covering availability rules, time slot generation, calendar integration, and booking workflows.

A technical guide to building a Calendly-style scheduling app on Bubble, covering availability rules, time slot generation, calendar integration, and booking workflows.

What Calendly Actually Does

Calendly is a scheduling tool that eliminates the back-and-forth of finding meeting times. You define your availability, share a booking link, and invitees pick a time that works. The system checks your connected calendars for conflicts, respects buffer times between meetings, handles timezone conversion, and sends confirmation emails to everyone. The output is simple: a confirmed meeting on both calendars with zero email exchanges about scheduling.

The product looks simple but the logic underneath is surprisingly detailed. Availability rules, calendar conflict checking, timezone handling, recurring schedules, buffer times, and multi-calendar support all need to work together without errors. A wrong timezone conversion or missed conflict check means double-bookings, which destroys user trust immediately.

Core Features Worth Cloning

A functional scheduling tool needs event type creation with duration and description settings, availability rules defining when you are bookable, a public booking page where invitees select a time, timezone detection and conversion, email confirmations and calendar invites, booking management with reschedule and cancel options, buffer time settings between meetings, and basic integration with Google Calendar or Outlook for conflict checking. Skip round-robin team scheduling, routing forms, workflows that chain multiple event types, analytics dashboards, and custom branding on paid plans. Those are upsell features, not core functionality.

Data Architecture in Bubble

Scheduling data needs to handle time precisely. Every date and time field must account for timezones, and Bubble stores all dates in UTC internally, which actually helps.

The User extends Bubble's default with timezone (text, like "America/New_York"), booking_slug (text, for their personal booking URL), profile_photo (image), bio (text), and connected_calendar_token (text, for OAuth tokens from Google Calendar).

The Event Type data type stores host (User), event_name (text), slug (text), duration_minutes (number), description (text), location_type (option set: zoom, google_meet, phone, in_person, custom), location_details (text), colour (text for calendar display), is_active (yes/no), buffer_before (number, minutes), buffer_after (number, minutes), max_bookings_per_day (number), min_notice_hours (number, how far in advance someone can book), and max_future_days (number, how far ahead the calendar shows). Each event type gets its own booking page URL based on the user's slug and event type slug.

The Availability Rule data type defines when the host is bookable. It stores event_type (Event Type, or User for default availability), day_of_week (number 0 to 6), start_time (text in HH:MM format or number of minutes from midnight), end_time (text or number), and is_active (yes/no). A user might be available Monday to Friday 9:00 to 17:00, which creates five Availability Rule records, one per day. Using number format for times (540 for 9:00 AM, 1020 for 17:00) makes time arithmetic much easier in Bubble than parsing time strings.

The Date Override data type handles exceptions. It stores user (User), specific_date (date), is_available (yes/no, false for blocked days, true for added availability), start_time (number), and end_time (number). This lets users block holidays or add availability on typically unavailable days.

The Booking data type is the confirmed meeting record. It needs event_type (Event Type), host (User), invitee_name (text), invitee_email (text), start_time (date, stored in UTC), end_time (date, stored in UTC), invitee_timezone (text), status (option set: confirmed, cancelled, rescheduled), notes (text, from the invitee), cancellation_reason (text), google_event_id (text, for synced calendar events), and created_date (date).

The Blocked Time data type stores user (User), start_time (date), end_time (date), and source (option set: manual, google_calendar, outlook). This holds external calendar events that should block availability.

The Time Slot Generation Logic

This is the core algorithm and the trickiest part of the build. When an invitee opens a booking page, the system needs to show available time slots for each visible day. Here is the logic flow for generating available slots on a given date.

First, determine the day of week for the target date. Look up Availability Rules for that day of week where the event type or user matches. If no rules exist or are inactive, the day has no availability. If a Date Override exists for that specific date with is_available set to false, the day is blocked entirely. If an override with is_available set to true exists, use the override times instead of the regular rules.

Second, generate candidate time slots. Starting from the availability start_time, create slots at intervals equal to the event type's duration (or a fixed interval like 15 or 30 minutes). Each slot has a start and end time based on the event duration. Stop generating when the next slot's end time would exceed the availability end_time.

Third, filter out conflicts. For each candidate slot, check if it overlaps with any existing Bookings for this host (where status is confirmed and the time ranges overlap) or any Blocked Time records. Also check buffer times. If the event type has a 15-minute buffer_after, extend each existing booking's blocked range by 15 minutes when checking for conflicts. Also enforce min_notice_hours by removing slots that start within that many hours from now, and max_bookings_per_day by counting confirmed bookings on this date.

In Bubble, implement this using a backend API workflow that accepts a date and event type, runs the logic, and returns a list of available start times. Or handle it client-side using custom states and Bubble's list processing operators. The client-side approach is faster for the user but more complex to build. The backend approach is cleaner but adds API call latency.

Timezone Handling

Timezones are the silent killer of scheduling apps. Bubble stores all dates in UTC, which is actually ideal. The flow works like this: detect the invitee's timezone using the browser's timezone (Bubble can access this). Display available times in the invitee's local timezone by converting from UTC. When they book, store the time in UTC. When displaying to the host, convert from UTC to the host's timezone. When sending confirmation emails, include times in both parties' timezones.

Bubble handles UTC storage automatically. For display conversion, use Bubble's date formatting with the timezone parameter. The ":formatted as" operator on dates accepts a timezone argument. For more precise timezone handling, especially around DST transitions, consider using the Moment.js plugin or a timezone API via the API Connector.

Calendar Integration

Syncing with Google Calendar requires OAuth authentication. Use Bubble's API Connector to set up Google Calendar as an API provider with OAuth2 authentication. The key endpoints you need are the Events list endpoint (to fetch existing events for conflict checking), the Events insert endpoint (to create calendar events when bookings are confirmed), and the Events delete/update endpoint (for cancellations and reschedules). When a user connects their Google Calendar, fetch their events for the next 30 to 60 days and create Blocked Time records. Set up a recurring backend workflow that re-syncs every 15 to 30 minutes to pick up newly added calendar events.

Booking Page UI

The booking page is the public-facing interface. Show the host's name, photo, and event description on the left. On the right, display a calendar widget (month view) where available dates are highlighted and unavailable dates are greyed out. When the invitee clicks a date, show the available time slots for that date in a scrollable list. When they select a time, show a confirmation form with name, email, and optional notes fields. On submission, create the Booking, send confirmation emails using Bubble's email workflows or SendGrid via API Connector, and create the Google Calendar event if the host has a connected calendar.

Privacy Rules

Event types should only be fully editable by their host. The public booking page only exposes the event name, duration, and description. Availability rules should only be visible to the host. Booking details should be visible to the host and accessible via a unique link sent to the invitee's email (using a unique token on the Booking record). Connected calendar data and OAuth tokens should never be exposed on the frontend. Blocked Time records from external calendars should only be visible to the host.

Cost and Timeline

A scheduling tool takes 6 to 10 weeks for an experienced Bubble developer. The time slot generation algorithm and timezone handling are the most time-intensive parts. Google Calendar integration adds 1 to 2 weeks. Bubble's Growth plan at $119 per month is needed for backend API workflows and scheduled syncs. If you integrate with Google Calendar, factor in Google Cloud API costs (free tier covers most early-stage usage). Annual costs run $1,500 to $3,000.

Build or Hire

The scheduling logic is mathematically precise and needs thorough testing across timezones, edge cases (DST transitions, midnight boundaries, max booking limits), and conflict scenarios. If you have a methodical approach to testing and are comfortable with time arithmetic, this is a satisfying intermediate-to-advanced Bubble project. If timezone handling makes your head spin, hire someone who has built scheduling tools before.

Related guides:

  • Bubble google sheets integration guide

  • how to build a telemedicine app with Bubble

Need a scheduling or booking tool built on Bubble? Reach out to Goodspeed Studio and let us handle the timezone headaches.

Solve the Scheduling Problem for Your Niche

Calendly works because it eliminates scheduling friction. Your clone should solve the same problem for a specific context Calendly does not serve well. Maybe it is scheduling with intake forms, paid consultations, multi-resource booking, or industry-specific workflows. Build the core booking loop first, nail timezone handling, and layer on niche-specific features after validation. Talk to our Bubble developers.

Harish Malhi - founder of Goodspeed

Harish Malhi

Founder of Goodspeed

Harish Malhi is the founder of Goodspeed, one of the top-rated Bubble agencies globally and winner of Bubble’s Agency of the Year award in 2024. He left Google to launch his first app, Diaspo, built entirely on Bubble, which gained press coverage from the BBC, ITV and more. Since then, he has helped ship over 200 products using Bubble, Framer, n8n and more - from internal tools to full-scale SaaS platforms. Harish now leads a team that helps founders and operators replace clunky workflows with fast, flexible software without writing a line of code.

Frequently Asked Questions (FAQs)

How does timezone handling work in a Bubble scheduling app?

Bubble stores all dates in UTC internally. Display times in the user's local timezone using the formatted-as operator with a timezone parameter. Detect the invitee's timezone from their browser and convert all displayed times accordingly.

Can I integrate Google Calendar with a Bubble app?

Yes. Use the API Connector plugin with Google Calendar's OAuth2 API. Fetch existing events for conflict checking, create calendar events on booking confirmation, and set up recurring syncs to keep blocked times updated.

How do I generate available time slots in Bubble?

Query the host's availability rules for the target day, generate candidate slots at fixed intervals, then filter out slots that conflict with existing bookings or blocked times. Account for buffer times, minimum notice, and max daily bookings.

How long does it take to build a Calendly clone?

Six to 10 weeks for an experienced Bubble developer. Calendar integration adds one to two weeks. The time slot generation algorithm and timezone handling are the most complex parts of the build.

Can I add payment collection to a scheduling app on Bubble?

Yes. Add Stripe payment during the booking confirmation step. Create a PaymentIntent before confirming the booking. Only create the Booking record after successful payment. This works well for paid consultations or coaching sessions.

How do I handle cancellations and rescheduling?

Include a unique token on each Booking record. Send the invitee a link with this token for managing their booking. On cancellation, update the booking status, delete the Google Calendar event, and send notification emails to both parties.

The smartest AI builds, in your inbox

Every week, you'll get first hand insights of building with no code and AI so you get a competitive advantage