Platform / Headless core and React bindings

Headless core and React bindings

The engine without the UI, to build your own calendar.

The engine behind the <Scheduler> is published on its own as calendarkit-pro/core: no React, no DOM, usable on the server and from any framework. Use it to build a calendar UI of your own, or to drive the calendar's state from outside.

import { createCalendar, selectTimeGrid } from 'calendarkit-pro/core'

const calendar = createCalendar({ defaultEvents: events, onEventsChange: save })
calendar.subscribe(() => draw(selectTimeGrid(calendar.getState(), { maxColumns: 3 })))

calendar.openSlot(new Date(2026, 9, 15, 14))
calendar.updateDraft({ title: 'Lunch with Lea tomorrow 1pm for 2h' }) // moves the draft
calendar.saveDraft() // creates "Lunch with Lea", then calls onEventsChange
calendar.undo()
  • createCalendar keeps the view, the date, the events (controlled with events, or uncontrolled with defaultEvents), dialogs and drafts. Moving, resizing, deleting and duplicating call the 1.x callbacks, then onEventsChange with the full list; undo() reverts the last change.
  • selectTimeGrid, selectMonth, selectAgenda, selectFlowDay and selectResources turn a state into plain data ready to render (overlaps laid out, extra events grouped into "+N").
  • parseEventSentence reads dates, times, durations and repetition in a title, in English and French.

React bindings

calendarkit-pro/react connects the engine to React (the <Scheduler> itself now runs on it):

import { useCalendar, useCalendarSelector, getEventProps, CalendarDndContext } from 'calendarkit-pro/react'
import { selectTimeGrid } from 'calendarkit-pro/core'

function MyWeek({ events, onEventsChange }) {
  const calendar = useCalendar({ events, onEventsChange })
  const grid = useCalendarSelector(calendar, (s) => selectTimeGrid(s, { maxColumns: 3 }))
  return (
    <CalendarDndContext calendar={calendar}>
      {grid.columns.map((column) => column.blocks.map((b) => <button key={b.event.id} {...getEventProps(calendar, b.event)}>{b.event.title}</button>))}
    </CalendarDndContext>
  )
}
  • useCalendar(options) creates the store once and keeps it in sync with your props; useCalendarSelector re-renders only when the selected slice changes. CalendarProvider / useCalendarContext share the store without passing it down.
  • getEventProps, getSlotProps and getResizeHandleProps return the props of an accessible event button, an empty slot and a resize handle.
  • CalendarDndContext, useDraggableEvent, useDroppableSlot and useActiveDrag wire dnd-kit to the store (drops call calendar.move, dragging is off in readOnly).
From docs/guide.md at v2.0.0 · Last updated 2026-10-24Edit on GitHub