TidyCal

tidycal.comcontributed by Samuele Ongaro

YES

Replaceable in one session with an AI coding agent.

A booking page bought once rather than rented: availability, calendar connections, paid bookings and a simple page, at a fraction of the usual price.

Promptfree, for everyone, and the only version there is
Build me a booking page that replaces TidyCal and Calendly: my real availability, somebody picks a slot, both calendars update, nobody emails about times.

STACK
- Node 20+ with Fastify, server-rendered HTML
- SQLite through better-sqlite3, WAL mode
- CalDAV or the Google Calendar API for the calendar link, and .ics for everything else
- Caddy in front

THE DATA MODEL
- users: id, email, name, timezone, slug, avatar_path
- event_types: id, user_id, slug, title, description, duration_minutes, buffer_before, buffer_after, min_notice_minutes, max_days_ahead, location_kind, location, is_active, colour
- availability: id, user_id, weekday, starts_at_local, ends_at_local — the weekly pattern
- availability_overrides: id, user_id, date, starts_at_local, ends_at_local, is_closed — holidays and one-off changes
- bookings: id, event_type_id, invitee_name, invitee_email, invitee_timezone, starts_at, ends_at, status, answers_json, cancel_token, created_at, cancelled_at, rescheduled_from_id
- calendar_connections: id, user_id, kind, credentials_encrypted, calendar_id, read_busy, write_events
- Everything stored in UTC; the local pattern is stored as local time plus the user's zone, because 9am stays 9am across a clock change

SLOT COMPUTATION, WHICH IS THE WHOLE PRODUCT
- Start from the weekly pattern, apply overrides, subtract busy blocks from every connected calendar, subtract existing bookings with their buffers, apply minimum notice and maximum horizon, then slice into slots of the event's duration
- Slots align to the hour or half hour by default, not to the first free minute
- Compute in the owner's timezone, present in the invitee's, and never let the two conversions happen in different places in the code
- Cache nothing that a calendar can change underneath you; a busy check is one request per calendar per page load, and the page says when it was last refreshed
- The double-booking guard is a unique constraint on (event_type_id, starts_at) plus a re-check inside the transaction that writes the booking. A booking page that can double-book is worse than no booking page

BOOKING
- Pick a day, pick a slot, give a name and an email, answer any questions the event type asks, confirm
- The invitee's timezone is detected and shown prominently, with a switcher, because the single most common failure here is a meeting booked an hour out
- Confirmation with an .ics attached, correct VTIMEZONE, stable UID, and the organiser set
- Reschedule and cancel from a signed link that never expires, both of which send an update with the same UID and a higher SEQUENCE
- A cancelled slot returns to availability immediately

THE CALENDAR LINK
- Read busy from as many calendars as the owner connects; write the booking to exactly one
- Store credentials encrypted at rest, and say in the README where the key lives
- A calendar that fails to answer blocks bookings rather than showing slots it cannot verify — being unavailable is recoverable, double-booking is not
- Two-way: an event created in the calendar makes those minutes unavailable within a minute

MORE THAN ONE PERSON
- Round robin across a group, with a rule: least recently booked, or most available
- Collective: a slot exists only when everybody in the group is free
- Both are one flag on the event type and one change to the slot computation, not a second product

MONEY, IF NEEDED
- Optional payment before confirmation through Stripe Checkout, with the webhook confirming — never the redirect
- A slot is held for ten minutes while payment completes, then released

NOTIFICATIONS
- Confirmation to both sides, reminders at the intervals the owner sets, a message on cancellation or reschedule
- Reminders from a worker that wakes every minute and is safe to run twice: mark sent inside the sending transaction
- Every email states the time in both timezones

THE INTERFACE
- The booking page is one column: the days, then the slots, then the form. It is opened on a phone more often than not
- Times in big type. The timezone under them, always visible
- The owner's admin is one page per event type plus one weekly grid for availability
- Dark and light, one accent

OPERATIONS
- .env: DATABASE_PATH, BASE_URL, SMTP_URL, ENCRYPTION_KEY, GOOGLE_CLIENT_ID and SECRET, STRIPE keys
- Migrations on boot, each once
- Nightly backup off the machine, restore script
- Health endpoint that checks the database and one calendar connection

WHAT MATTERS MOST
Slot computation and the double-booking guard. Write those first with tests: a week with an override, a clock change, two calendars, and two people booking the same slot in the same second. Everything else is forms.

Give me the repository, migrations, .env.example, a seed user with two event types, and a README with deploy steps behind Caddy and instructions for connecting a Google calendar.

What you lose

  • A one-off price that no build can beat on cost
  • Calendar connections already written and maintained
  • Paid bookings through Stripe without configuration

If you would rather not build

  • A booking page you write, which the prompt covers
  • TidyCal itself, which is genuinely cheap

What it costs

read from their page 17 Aug 2026

PlanBilled monthlyBilled yearlyLast read
—$2.50/mo—17 Aug 2026

Their pricing page is where these came from. Seeing a different price? Tell us.

The escape hatch

open source · no votes, no paid placement

Cal.com

$0

Open scheduling with calendar connections already built.

calcom/cal.diyfree · open source

Easy!Appointments

$0

A booking system that runs on ordinary shared hosting.

alextselegidis/easyappointmentsfree · open source

Why this verdict

our own opinion · changed only by a person

84/100

Verdict yes at 84 for control rather than cost — a one-off $29 is hard to beat. The daylight-saving tests are the part to actually write.

History

tracked since 10 Aug 2026 · nothing is ever overwritten

Interest · last 30 dayspeak 2/day
views01230 Aug4 Sept9 Sept14 Sept19 Sept24 Sept28 Sept
— views— prompt copies none yet— votes none yet

Questions about TidyCal

answered from the record above

Is TidyCal free?

No — the plan we track is $2.50 a month. A one-off lifetime purchase of around $29 rather than a subscription; the figure shown spreads that over a year.

Can you replace TidyCal by building your own?

YES. Replaceable in one session with an AI coding agent. Replacement score 84 out of 100, build time one session. Read what you lose before you decide.

How much does TidyCal cost?

$2.50 a month on Lifetime — $30 a year. Recorded 10 Aug 2026.

What do you lose by replacing TidyCal?

A one-off price that no build can beat on cost; Calendar connections already written and maintained; Paid bookings through Stripe without configuration. If any of those carry weight for you, keep paying.

Is there an open-source alternative to TidyCal?

Yes: Cal.com, Easy!Appointments. The prompt on this page is for when you want it your way instead.

Related entries

same category first, most replaced first

All 14 in Scheduling

Not sending yet

Every week, something stops being worth paying for.

New verdicts, prices that moved, entries added. One email a week. Unsubscribe in one click. Nothing is being sent yet — your address is kept here, and the first issue is the first thing it is used for.

free forever · no tracking pixel · stored here, never passed to anyone

Esc