Skip to Content
Getting started

timeslottr

timeslottr is a zero-dependency TypeScript library for interval arithmetic over calendar time. It turns working hours into bookable slots, subtracts already-booked events, and intersects multiple participants’ calendars to find the windows where everyone is free.

It does the interval math that sits underneath a scheduling product like Calendly or cal.com. The calendar sync, storage, and UI stay yours.

What can you use it for?

  • A booking page. Turn “Monday to Thursday, 9 to 5, 30-minute meetings” into the list of times a customer can click.
  • Interview loops, where the slot has to work for the candidate and three interviewers at once.
  • Appointments that need prep or cleanup time around them, using the before and after buffers.
  • Room, court, and equipment reservations. Same interval math, different noun.
  • Shift and on-call rotas built from a per-weekday schedule across a date range.
  • Delivery and pickup windows, with a cap on how far ahead people can book so nobody reserves a slot six months out.

Features

  • Slot generation. Split a working day into fixed-length slots, with per-weekday hours, buffers, breaks, and overlapping starts.
  • Availability math. Remove the time that is already booked, then keep only the windows where everyone is free.
  • Timezones and daylight saving. Handled with what Node and browsers already ship, so no date library and no timezone database in your bundle.
  • Half-open intervals. A slot that ends at 10:00 does not collide with one that starts at 10:00, so adjacent slots never double-book.
  • Typed and portable. Fully typed, no runtime dependencies, ES modules and CommonJS. Runs in Node, edge runtimes, and browsers.

Installation

npm install timeslottr

Requires Node.js ≥ 18.

Your first slots

Generate 30-minute slots for a single day, skipping a lunch break:

import { generateTimeslots } from 'timeslottr' const slots = generateTimeslots({ day: '2024-01-01', timezone: 'America/New_York', range: { start: '09:00', end: '17:00' }, slotDurationMinutes: 30, excludedWindows: [{ start: '12:00', end: '13:00' }], }) console.log(slots.length) // 14 slots: 9 to 12 and 1 to 5, every 30 minutes console.log(slots[0].start.toISOString())

Each slot is a Timeslot with an inclusive start, an exclusive end, and some metadata. Start and end are real Date objects.

Find a time that works for a team

Take a base schedule, remove what is already booked, and keep only the windows where everyone is free.

import { generateAvailableTimeslots } from 'timeslottr' const slots = generateAvailableTimeslots({ day: '2024-01-01', timezone: 'America/New_York', range: { start: '09:00', end: '17:00' }, slotDurationMinutes: 30, busy: [{ start: '12:00', end: '13:00' }], // already-booked participantsBusy: [ [{ start: '09:00', end: '10:00' }], // Alice [{ start: '16:00', end: '17:00' }], // Bob ], }) // → 30-min slots only where the host, Alice, and Bob are all free

Where to next

Last updated on