A scheduling link that lets the person booking overlay their own calendar on yours, so they pick a time that works for both instead of guessing from a list of slots.
Build me a scheduling link that replaces SavvyCal: the person booking can lay their own calendar over mine and pick a time that works for both. STACK - Node 20+ with Fastify, server-rendered HTML with a little vanilla JS - SQLite through better-sqlite3, WAL mode - Caddy in front THE FEATURE THAT IS THE WHOLE PRODUCT - A normal booking page shows a list of slots and makes the other person cross-reference it against their own week. That is work you have pushed onto them, which is why receiving a scheduling link feels slightly rude - Here, the person booking connects or pastes their own calendar and sees both availabilities on one grid. The times that work for both are obvious, and nobody does arithmetic - Two ways in, and both matter: connect a calendar with OAuth, or paste a read-only ICS URL. And a third for the reluctant — upload nothing, and just use the ordinary slot list - Whatever they connect is used in the browser and for that session only. Never stored, never sent to the organiser, discarded when the page closes. Say that on the page, in one sentence, at the moment you ask — otherwise nobody connects anything THE DATA MODEL - users: id, name, slug, email, timezone - event_types: id, user_id, slug, title, description_md, duration_minutes, buffer_before, buffer_after, min_notice_minutes, max_days_ahead, max_per_day, location_kind, location_value, requires_confirmation, is_active - schedules and availability_rules: weekday, start_local, end_local, with a named zone - ranked_windows: id, event_type_id, weekday, start_local, end_local, weight — the preferred times - date_overrides: id, user_id, date, is_unavailable, start_local, end_local - bookings: id, event_type_id, uid, starts_at_utc, ends_at_utc, attendee_name, attendee_email, attendee_timezone, answers_json, status, cancel_token, reschedule_token, external_event_id, created_at - calendar_connections and busy_blocks — only intervals, never event details - The guest's calendar has no table. That is deliberate and it is the promise RANKED AVAILABILITY - Not every free hour is equally welcome. Windows carry a weight, and preferred times are shown prominently while the rest are available but quieter - The other person still sees everything, so nothing is hidden — they are simply nudged. That is the honest version of the feature, and hiding real availability to force a preferred slot is the dishonest one - Weights per event type, so a sales call and a deep-work review can prefer different halves of the day TIME, WHICH IS WHERE HOMEMADE SCHEDULERS DIE - Every instant in UTC. Availability rules as local times with a named zone, because 09:00 in Europe/Rome is a different instant in July and in January - A real time zone library and the IANA database; never an offset - The test suite includes a spring-forward day, an autumn-back day, and a zone whose rules changed - The guest sees their own zone by default with the organiser's shown beside it, and the overlay grid is drawn in the guest's zone SLOT GENERATION - One pure function: take the rules, subtract busy blocks, subtract existing bookings with their buffers, apply notice, horizon and daily cap, round to an increment, and return slots with their weights - No database access inside it, and tested heavily. Everything else in this product is forms CALENDARS - Two-way with the major providers, and read-only ICS for anything else - Incremental sync with the provider's sync token plus a full reconcile on a schedule, because incremental sync drifts - Recurring events expanded properly — recurrence rules with exceptions are what break naive implementations, and a wrongly expanded weekly meeting means double bookings for a year - Only busy intervals stored from the read side. The organiser's meeting titles are none of this tool's business BOOKING - Pick, fill, confirm. No account, ever - A hold on the slot while the form is filled, released after a few minutes; the final insert re-checks availability inside the transaction, which is the actual guarantee - Custom questions, validated on the server - Cancel and reschedule from long random tokens in the email, no account NOTIFICATIONS - Confirmation to both sides with an ICS attachment and hand-built add-to-calendar links - Reminders at configurable offsets, each recorded so nobody is reminded twice - A one-click cancellation link in every one OPERATIONS - .env: DATABASE_PATH, BASE_URL, ENCRYPTION_KEY, SESSION_SECRET, SMTP_URL, provider client ids and secrets - Migrations on boot, each once - Nightly backup off the machine, restore script - Health endpoint that generates tomorrow's slots WHAT MATTERS MOST The overlay and the promise about the guest's calendar. Build the two-calendar grid first and make the discard-after-session behaviour real, then have two browsers book the same slot at once and confirm exactly one wins. The overlay is the only reason to build this instead of any other scheduler, and the promise is the only reason anyone will use it. Give me the repository, migrations, .env.example, a seed user with ranked windows, and a README with deploy steps behind Caddy and the OAuth setup for each provider.
What you lose
- The calendar overlay itself, which is the whole reason to choose this over a plain slot list
- Ranked availability, where you nudge people toward the times you actually prefer
- Two-way sync with several calendar providers, maintained as their APIs move
- Scheduling links that work for a team round-robin as well as for one person
If you would rather not build
- Calendly, for the plain version of the same job
- A shared Google Calendar with an appointment schedule, which costs nothing
What it costs
as published on their pricing page
| Plan | Billed monthly | Billed yearly | Last read |
|---|---|---|---|
| — | $12/mo | — | — |
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
$0Open-source scheduling with calendar connections already built.
calcom/cal.diyfree · open source
Easy!Appointments
$0A PHP booking system that runs on ordinary shared hosting.
alextselegidis/easyappointmentsfree · open source
Why this verdict
our own opinion · changed only by a person
76/100
Verdict yes at 76. The scheduling half is ordinary; the overlay is the part worth building carefully, and doing it without storing anything of the visitor's calendar is the detail that makes it defensible.
History
tracked since 10 Aug 2026 · nothing is ever overwritten
Questions about SavvyCal
answered from the record above
Is SavvyCal free?
No — the plan we track is $12 a month. Basic at $12/month billed monthly, $10 annually.
Can you replace SavvyCal by building your own?
YES. Replaceable in one session with an AI coding agent. Replacement score 76 out of 100, build time one session. Read what you lose before you decide.
How much does SavvyCal cost?
$12 a month on Basic — $144 a year. Recorded 9 Aug 2026.
What do you lose by replacing SavvyCal?
The calendar overlay itself, which is the whole reason to choose this over a plain slot list; Ranked availability, where you nudge people toward the times you actually prefer; Two-way sync with several calendar providers, maintained as their APIs move; Scheduling links that work for a team round-robin as well as for one person. If any of those carry weight for you, keep paying.
Is there an open-source alternative to SavvyCal?
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
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

