Back

Documentation

Installation

CalendarKit offers two versions: Basic and Pro. Both are free and open source!

Basic (Free - Open Source)

Install directly from npm - no purchase needed! Full-featured calendar with modern UI and mobile support.

  • ✓ Month, Week, Day views
  • ✓ Event creation & editing
  • ✓ Event overlap detection
  • ✓ Custom event renderer
  • ✓ Week start configuration
  • ✓ Mobile swipe gestures
  • ✓ Loading skeletons & empty states
  • ✓ Calendar filtering
  • ✓ Dark mode support
  • ✓ Full TypeScript support
  • ✓ MIT License

Pro (Premium - Open Source)

Install directly from npm! Professional features for production apps.

  • ✓ Everything in Basic
  • ✓ Drag & drop events
  • ✓ Event resizing with 15-min snapping
  • ✓ Agenda & Resource views
  • ✓ Dark mode & i18n
  • ✓ Timezone support
  • ✓ Recurring events (RRULE)
  • ✓ Event reminders & notifications
  • ✓ ICS import/export
  • ✓ Context menus (right-click)
  • ✓ Mobile swipe gestures
  • ✓ Skeleton loading & empty states
  • ✓ Event attachments & guests
  • ✓ MIT License
# Basic (Free - Open Source)
npm install calendarkit-basic
# or
yarn add calendarkit-basic
# or
pnpm add calendarkit-basic

# Pro (Premium - Open Source)
npm install calendarkit-pro
# or
yarn add calendarkit-pro
# or
pnpm add calendarkit-pro

Basic Usage

The BasicScheduler component provides essential calendar functionality with month, week, and day views.

BasicScheduler Example
import { BasicScheduler } from 'calendarkit-basic';
import { CalendarEvent, ViewType } from 'calendarkit-basic';
import { useState } from 'react';

export default function MyCalendar() {
  const [events, setEvents] = useState<CalendarEvent[]>([]);
  const [view, setView] = useState<ViewType>('week');
  const [date, setDate] = useState(new Date());

  return (
    <BasicScheduler
      events={events}
      view={view}
      onViewChange={setView}
      date={date}
      onDateChange={setDate}
      onEventCreate={(event) => {
        setEvents([...events, { ...event, id: Date.now().toString() }]);
      }}
    />
  );
}

Pro UsagePro

The ProScheduler includes all Basic features plus drag & drop, agenda view, resource view, timezone support, dark mode, i18n, and recurring events.

ProScheduler Example
import { Scheduler, CalendarEvent, ViewType, Resource } from 'calendarkit-pro';
import { useState } from 'react';

export default function MyCalendar() {
  const [events, setEvents] = useState<CalendarEvent[]>([]);
  const [view, setView] = useState<ViewType>('week');
  const [date, setDate] = useState(new Date());
  const [isDarkMode, setIsDarkMode] = useState(false);

  return (
    <Scheduler
      events={events}
      view={view}
      onViewChange={setView}
      date={date}
      onDateChange={setDate}
      isDarkMode={isDarkMode}
      onThemeToggle={() => setIsDarkMode(!isDarkMode)}
      onEventCreate={(event) => {
        setEvents([...events, { ...event, id: Date.now().toString() }]);
      }}
    />
  );
}

Events

Events are the core data structure in CalendarKit. Each event must have a unique ID, title, start, and end date.

CalendarEvent Interface
interface CalendarEvent {
  id: string;           // Unique identifier
  title: string;        // Event title
  start: Date;          // Start date/time
  end: Date;            // End date/time
  description?: string; // Optional description
  color?: string;       // Hex color (e.g., '#3b82f6')
  allDay?: boolean;     // Is all-day event
  calendarId?: string;  // Associated calendar ID
  resourceId?: string;  // For resource view (Pro only)
  guests?: string[];    // Email addresses (Pro only)
  attachments?: EventAttachment[]; // Files (Pro only)
  recurrence?: {        // Recurring rules (Pro only)
    freq: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
    interval?: number;
    count?: number;     // Number of occurrences
    until?: Date;       // End date
  };
}

Required Fields

  • id - Unique identifier for the event
  • title - Display name of the event
  • start - JavaScript Date object for start time
  • end - JavaScript Date object for end time

Calendars

Calendars allow users to organize and filter events by category. Each calendar has a color and can be toggled on/off.

Calendar Filtering
const calendars = [
  { id: 'work', label: 'Work', color: '#3b82f6', active: true },
  { id: 'personal', label: 'Personal', color: '#10b981', active: true },
  { id: 'family', label: 'Family', color: '#8b5cf6', active: false },
];

<BasicScheduler
  events={events}
  calendars={calendars}
  onCalendarToggle={(id, active) => {
    setCalendars(cals =>
      cals.map(c => c.id === id ? { ...c, active } : c)
    );
  }}
/>

Event Handlers

CalendarKit provides callback functions for all user interactions. Use these to sync with your backend or state management.

Event Handlers
<ProScheduler
  events={events}
  // Called when user clicks on an event
  onEventClick={(event) => {
    console.log('Event clicked:', event);
  }}
  // Called when user creates a new event
  onEventCreate={(event) => {
    setEvents([...events, { ...event, id: Date.now().toString() }]);
  }}
  // Called when user updates an existing event
  onEventUpdate={(updatedEvent) => {
    setEvents(events.map(e =>
      e.id === updatedEvent.id ? updatedEvent : e
    ));
  }}
  // Called when user deletes an event
  onEventDelete={(eventId) => {
    setEvents(events.filter(e => e.id !== eventId));
  }}
  // Called when user drags an event to a new time (Pro only)
  onEventDrop={(event, newStart, newEnd) => {
    setEvents(events.map(e =>
      e.id === event.id ? { ...e, start: newStart, end: newEnd } : e
    ));
  }}
/>

BasicScheduler Props

Complete reference of all props available in BasicScheduler.

BasicScheduler Props Interface
// BasicScheduler Props
interface BasicSchedulerProps {
  // Data
  events?: CalendarEvent[];
  calendars?: Calendar[];

  // View Control
  view?: 'month' | 'week' | 'day';
  onViewChange?: (view: ViewType) => void;
  date?: Date;
  onDateChange?: (date: Date) => void;

  // Week Start Configuration
  weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;  // 0 = Sunday, 1 = Monday, etc.

  // Event Handlers
  onEventClick?: (event: CalendarEvent) => void;
  onEventCreate?: (event: Partial<CalendarEvent>) => void;
  onEventUpdate?: (event: CalendarEvent) => void;
  onEventDelete?: (eventId: string) => void;
  onCalendarToggle?: (calendarId: string, active: boolean) => void;

  // Customization
  theme?: CalendarTheme;
  locale?: Locale;
  className?: string;
  readOnly?: boolean;
  isLoading?: boolean;

  // Custom Rendering
  renderEventForm?: (props: EventFormProps) => React.ReactNode;
  renderEvent?: (props: {
    event: CalendarEvent;
    view: ViewType;
    onClick: () => void;
  }) => React.ReactNode;
}
PropTypeDefaultDescription
eventsCalendarEvent[][]Array of events to display
view'month' | 'week' | 'day''week'Current calendar view
dateDatenew Date()Currently focused date
calendarsCalendar[]undefinedCalendar categories for filtering
localeLocaleundefineddate-fns locale for date formatting
readOnlybooleanfalseDisable event creation/editing
isLoadingbooleanfalseShow loading skeleton
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 60First day of week (0=Sunday, 1=Monday)
renderEventfunctionundefinedCustom event renderer component

BasicScheduler Views

Month View

Traditional calendar grid showing all days in the current month. Events are displayed as colored bars. Respects weekStartsOn configuration.

Week View

7-day view with hourly grid. Smart event overlap detection displays overlapping events side-by-side. Virtualized for performance.

Day View

Single day view with detailed hourly breakdown. 15-minute time slots with event collision detection for overlapping events.

New in v1.0.0

  • ✓ Event overlap detection with side-by-side display
  • ✓ Configurable week start (Sunday through Saturday)
  • ✓ Custom event renderer for complete control
  • ✓ Event view modal with edit/delete actions
  • ✓ Mobile swipe gestures for navigation
  • ✓ Loading skeletons and empty states

Week Start Configuration

Configure which day the week starts on. Affects Week view, Month view, and Mini Calendar.

Week Start Configuration
// Configure which day the week starts on
<BasicScheduler
  events={events}
  weekStartsOn={1}  // 0 = Sunday (default), 1 = Monday, etc.
  // Affects Week view, Month view, and Mini Calendar
/>

// Common configurations:
// weekStartsOn={0}  // Sunday (US default)
// weekStartsOn={1}  // Monday (EU/ISO standard)
// weekStartsOn={6}  // Saturday (Middle East)
ValueDayCommon Usage
0SundayUS, Canada, Japan (default)
1MondayEurope, ISO standard
6SaturdayMiddle East

Custom Event Renderer

Use the renderEvent prop for complete control over event appearance across all views.

Custom Event Renderer
// Custom event renderer for complete control over appearance
<BasicScheduler
  events={events}
  renderEvent={({ event, view, onClick }) => (
    <div
      onClick={onClick}
      className="p-2 rounded cursor-pointer hover:opacity-80"
      style={{ backgroundColor: event.color }}
    >
      <div className="font-semibold text-white truncate">
        {event.title}
      </div>
      {view !== 'month' && (
        <div className="text-xs text-white/80">
          {format(event.start, 'h:mm a')} - {format(event.end, 'h:mm a')}
        </div>
      )}
    </div>
  )}
/>

Render Props

  • event - The CalendarEvent object with all event data
  • view - Current view type ('month' | 'week' | 'day')
  • onClick - Click handler to open event modal

Mobile Features

Built-in mobile support with swipe gestures, bottom sheet, and floating action buttons.

Mobile Features
// Mobile features are built-in:
// - Swipe left/right to navigate dates
// - Mobile bottom sheet for calendar/filters
// - Floating action buttons (FAB)

// Swipe gestures work automatically on touch devices
<BasicScheduler
  events={events}
  view={view}
  onViewChange={setView}
/>

// Mobile Bottom Sheet provides:
// - Mini calendar for date selection
// - Calendar filter toggles
// - View switcher (Month/Week/Day)

Swipe Gestures

Swipe left/right to navigate between time periods. Works on all views with configurable threshold.

Mobile Bottom Sheet

Quick access to mini calendar, calendar filters, and view switcher. Opens via the calendar FAB.

Floating Action Buttons

Calendar/filter button and create event FAB. The create button respects the readOnly prop.

Loading States

Beautiful skeleton loading animations and empty state components for a polished UX.

Loading & Empty States
import {
  BasicScheduler,
  CalendarSkeleton,
  MonthViewSkeleton,
  WeekViewSkeleton,
  DayViewSkeleton,
  EmptyState
} from 'calendarkit-basic';

// Use isLoading prop for built-in skeleton
<BasicScheduler
  events={events}
  isLoading={isLoadingEvents}
/>

// Or use skeleton components directly
{isLoading ? (
  <CalendarSkeleton />
) : (
  <BasicScheduler events={events} />
)}

// Empty state component
<EmptyState
  title="No events scheduled"
  description="Create your first event to get started"
  actionLabel="Create Event"
  onAction={() => setIsModalOpen(true)}
/>

Skeleton Components

CalendarSkeleton, MonthViewSkeleton, WeekViewSkeleton, DayViewSkeleton - Animated shimmer effect placeholders.

Empty State

Customizable component with icon, title, description, and optional action button.

ProScheduler PropsPro

ProScheduler extends BasicScheduler with additional features. All Basic props are available plus:

ProScheduler Props Interface
// ProScheduler Props (includes all BasicScheduler props)
interface ProSchedulerProps extends BasicSchedulerProps {
  // Additional Views
  view?: 'month' | 'week' | 'day' | 'agenda' | 'resource';
  resources?: Resource[];

  // Drag & Drop
  onEventDrop?: (event: CalendarEvent, start: Date, end: Date) => void;
  onEventResize?: (event: CalendarEvent, start: Date, end: Date) => void;

  // Timezone
  timezone?: string;
  onTimezoneChange?: (timezone: string) => void;

  // Theme
  isDarkMode?: boolean;
  onThemeToggle?: () => void;

  // i18n
  language?: 'en' | 'fr';
  onLanguageChange?: (lang: 'en' | 'fr') => void;
  translations?: Partial<CalendarTranslations>;

  // Pro Features
  eventTypes?: EventType[];
  hideViewSwitcher?: boolean;
}
PropTypeDescription
timezonestringIANA timezone (e.g., 'America/New_York')
isDarkModebooleanEnable dark theme
language'en' | 'fr'UI language for built-in translations
translationsCalendarTranslationsCustom translation overrides
resourcesResource[]Resources for resource view
onEventDropfunctionCallback when event is dragged
onEventResizefunctionCallback when event is resized
hideViewSwitcherbooleanHide the view toggle buttons

ProScheduler ViewsPro

All Basic Views

Month, Week, and Day views with drag & drop support.

Agenda View Pro

List view showing upcoming events in chronological order. Perfect for quick overview.

Resource View Pro

Display events by resource (rooms, people, equipment). Ideal for booking systems.

Drag & DropPro

Smoothly drag events to reschedule them. Works across Month, Week, Day, and Resource views.

Drag & Drop Events
// Drag & drop is built-in to ProScheduler
<ProScheduler
  events={events}
  // Called when an event is dragged to a new time
  onEventDrop={(event, newStart, newEnd) => {
    setEvents(events.map(e =>
      e.id === event.id
        ? { ...e, start: newStart, end: newEnd }
        : e
    ));
  }}
  // Optional: disable drag for specific scenarios
  readOnly={false}
/>

// Drag features:
// - Smooth drag with snap-to-grid (15-min intervals)
// - Visual drag preview with event color
// - Works in Month, Week, Day, and Resource views

Features

  • ✓ Snap-to-grid (15-minute intervals)
  • ✓ Visual drag preview with event color and shadow
  • ✓ Works in all views including Resource view
  • ✓ Respects readOnly prop

Event ResizingPro

Drag the bottom edge of events to resize them directly in the week and day views. Events snap to 15-minute intervals with visual feedback during resize.

Event Resizing
// Event resizing is enabled by default in ProScheduler
// Users can drag the bottom edge of events to resize them

<Scheduler
  events={events}
  // Called when user resizes an event by dragging
  onEventResize={(event, newStart, newEnd) => {
    setEvents(events.map(e =>
      e.id === event.id ? { ...e, start: newStart, end: newEnd } : e
    ));
  }}
/>

// The ResizableEvent component handles:
// - 15-minute snap intervals for precise scheduling
// - Visual feedback during resize (cursor, preview)
// - Minimum duration constraints

Features

  • ✓ Drag bottom edge to resize events
  • ✓ 15-minute snap intervals
  • ✓ Visual feedback during resize
  • ✓ Works in Week and Day views

Timezone SupportPro

Display events in any timezone. Users can switch timezones on the fly.

Timezone Configuration
<ProScheduler
  events={events}
  timezone="America/New_York"      // IANA timezone
  onTimezoneChange={(tz) => {
    setTimezone(tz);
    // Events will automatically adjust to new timezone
  }}
/>

// Supported timezones include:
// - America/New_York
// - America/Los_Angeles
// - Europe/London
// - Europe/Paris
// - Asia/Tokyo
// - And all IANA timezone identifiers

InternationalizationPro

Built-in support for English and French. Add custom translations for any language.

i18n Configuration
import { fr, de, es } from 'date-fns/locale';

// Custom translations
const customTranslations = {
  today: 'Heute',
  month: 'Monat',
  week: 'Woche',
  day: 'Tag',
  createEvent: 'Ereignis erstellen',
  editEvent: 'Ereignis bearbeiten',
  delete: 'Löschen',
  save: 'Speichern',
  cancel: 'Abbrechen',
  // ... more translations
};

<ProScheduler
  events={events}
  language="fr"                    // Built-in: 'en' | 'fr'
  locale={fr}                      // date-fns locale for date formatting
  translations={customTranslations} // Override specific strings
  onLanguageChange={(lang) => setLanguage(lang)}
/>

Recurring EventsPro

Create events that repeat daily, weekly, monthly, or yearly. Supports count-based and date-based end rules.

Recurring Event Examples
const recurringEvents = [
  {
    id: '1',
    title: 'Daily Standup',
    start: new Date(2025, 0, 6, 9, 0),
    end: new Date(2025, 0, 6, 9, 30),
    recurrence: {
      freq: 'DAILY',
      interval: 1,      // Every 1 day
      count: 30,        // Repeat 30 times
    },
  },
  {
    id: '2',
    title: 'Weekly Team Meeting',
    start: new Date(2025, 0, 6, 14, 0),
    end: new Date(2025, 0, 6, 15, 0),
    recurrence: {
      freq: 'WEEKLY',
      interval: 1,
      until: new Date(2025, 12, 31), // End date
    },
  },
  {
    id: '3',
    title: 'Monthly Report',
    start: new Date(2025, 0, 1, 10, 0),
    end: new Date(2025, 0, 1, 11, 0),
    recurrence: {
      freq: 'MONTHLY',
      interval: 1,
      count: 12,
    },
  },
];

Recurrence Options

  • freq - Frequency: DAILY, WEEKLY, MONTHLY, YEARLY
  • interval - Repeat every N periods (default: 1)
  • count - Total number of occurrences
  • until - End date for recurrence

Resource ViewPro

Display events by resource - perfect for room booking, team scheduling, or equipment allocation.

Resource View Setup
const resources = [
  { id: 'room-a', label: 'Conference Room A', color: '#3b82f6' },
  { id: 'room-b', label: 'Conference Room B', color: '#10b981' },
  { id: 'john', label: 'John Doe', color: '#f59e0b', avatar: '/avatars/john.jpg' },
];

const events = [
  {
    id: '1',
    title: 'Client Meeting',
    start: new Date(2025, 0, 15, 10, 0),
    end: new Date(2025, 0, 15, 11, 0),
    resourceId: 'room-a',  // Link event to resource
  },
];

<ProScheduler
  events={events}
  resources={resources}
  view="resource"
/>

ICS Import/ExportPro

Import and export calendar events in the standard ICS format. Compatible with Google Calendar, Apple Calendar, Outlook, and more.

ICS Import/Export
// ICS utilities are included in calendarkit-pro
// You can implement your own ICS handling like this:

// Export events to ICS file
const handleExport = () => {
  const icsContent = generateICS(events, calendars);
  const blob = new Blob([icsContent], { type: 'text/calendar' });
  const url = URL.createObjectURL(blob);

  const link = document.createElement('a');
  link.href = url;
  link.download = 'calendar.ics';
  link.click();
};

// Import events from ICS file
const handleImport = async (file: File) => {
  const text = await file.text();
  const importedEvents = parseICS(text);
  setEvents([...events, ...importedEvents]);
};

// Supports:
// - Recurring events (RRULE)
// - All-day events
// - Event attachments
// - Multiple calendars

Supported Features

  • ✓ Full ICS generation and parsing
  • ✓ Recurring events support
  • ✓ All-day events
  • ✓ Attachments support
  • ✓ Import/Export buttons in Sidebar

Context MenusPro

Right-click on events to access quick actions like edit, delete, and duplicate.

Context Menu Usage
// Context menus appear on right-click in calendarkit-pro
// Built-in actions include Edit, Delete, and Duplicate

import { Scheduler } from 'calendarkit-pro';

function MyScheduler() {
  return (
    <Scheduler
      events={events}
      // Built-in context menu actions
      onEventUpdate={(event) => updateEvent(event)}
      onEventDelete={(eventId) => deleteEvent(eventId)}
    />
  );
}

Available Actions

  • ✓ Edit event
  • ✓ Delete event
  • ✓ Duplicate event

Notification RemindersPro

Add reminder notifications to events with predefined intervals. Users can set multiple reminders per event.

Event Reminders
// Events can have multiple reminders
interface EventReminder {
  id: string;
  minutes: number;  // Minutes before event
  type: 'notification' | 'email';
}

const event: CalendarEvent = {
  id: '1',
  title: 'Team Meeting',
  start: new Date(2025, 0, 15, 14, 0),
  end: new Date(2025, 0, 15, 15, 0),
  reminders: [
    { id: 'r1', minutes: 15, type: 'notification' },  // 15 min before
    { id: 'r2', minutes: 60, type: 'email' },         // 1 hour before
  ],
};

// Built-in reminder options in EventModal:
// - 5 minutes before
// - 10 minutes before
// - 15 minutes before
// - 30 minutes before
// - 1 hour before
// - 1 day before

Reminder Options

  • ✓ 5, 10, 15, 30 minutes before
  • ✓ 1 hour before
  • ✓ 1 day before
  • ✓ Multiple reminders per event

Theming

Customize colors, fonts, and border radius. Both Basic and Pro support custom themes.

Custom Theme Configuration
const customTheme = {
  colors: {
    primary: '#6366f1',      // Primary accent color
    secondary: '#ec4899',    // Secondary color
    background: '#ffffff',   // Background color
    foreground: '#0f172a',   // Text color
    border: '#e2e8f0',       // Border color
    muted: '#f1f5f9',        // Muted backgrounds
    accent: '#f1f5f9',       // Accent backgrounds
  },
  fontFamily: 'Inter, sans-serif',
  borderRadius: '0.75rem',
};

<ProScheduler
  events={events}
  theme={customTheme}
  isDarkMode={isDarkMode}
  onThemeToggle={() => setIsDarkMode(!isDarkMode)}
/>

Custom Event Form

Replace the built-in event form with your own custom component. Works with both Basic and Pro schedulers.

Custom Event Form
<ProScheduler
  events={events}
  renderEventForm={({ isOpen, onClose, event, initialDate, onSave, onDelete }) => (
    <MyCustomModal isOpen={isOpen} onClose={onClose}>
      <MyEventForm
        event={event}
        initialDate={initialDate}
        onSave={(data) => {
          onSave(data);
          onClose();
        }}
        onDelete={event?.id ? () => {
          onDelete?.(event.id);
          onClose();
        } : undefined}
      />
    </MyCustomModal>
  )}
/>

Render Props

  • isOpen - Whether the form should be visible
  • onClose - Function to close the form
  • event - Existing event (for edit mode) or null
  • initialDate - Pre-filled date for new events
  • onSave - Function to save the event
  • onDelete - Function to delete the event