Features
Recurring Events
Define events that repeat daily, weekly, monthly, or yearly with optional count and until rules.
Recurring Events
CalendarKit Pro supports recurring events via the recurrence field on a CalendarEvent. The scheduler automatically expands recurring events into individual occurrences for the visible date range.
Recurrence model
recurrence?: {
freq: 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
interval?: number; // repeat every N units (default: 1)
count?: number; // stop after N occurrences
until?: Date; // stop on this date (inclusive)
byweekday?: number[]; // 0=Monday … 6=Sunday
}
countanduntilare mutually exclusive. If both are set,counttakes precedence.
Examples
Every day
const dailyEvent: CalendarEvent = {
id: 'daily',
title: 'Morning Standup',
start: new Date('2026-07-21T09:00:00'),
end: new Date('2026-07-21T09:30:00'),
recurrence: { freq: 'DAILY' },
};Every 2 weeks, on Monday and Wednesday, for 8 occurrences
const biweekly: CalendarEvent = {
id: 'biweekly',
title: 'Team Sync',
start: new Date('2026-07-21T10:00:00'),
end: new Date('2026-07-21T11:00:00'),
recurrence: {
freq: 'WEEKLY',
interval: 2,
byweekday: [0, 2], // 0=Monday, 2=Wednesday
count: 8,
},
};Every month until end of year
const monthly: CalendarEvent = {
id: 'monthly',
title: 'Monthly All-Hands',
start: new Date('2026-07-07T14:00:00'),
end: new Date('2026-07-07T15:00:00'),
recurrence: {
freq: 'MONTHLY',
until: new Date('2026-12-31'),
},
};Every year (anniversary)
const anniversary: CalendarEvent = {
id: 'anniversary',
title: 'Company Anniversary 🎉',
start: new Date('2026-03-15'),
end: new Date('2026-03-16'),
allDay: true,
recurrence: { freq: 'YEARLY' },
};Weekly gym — no end
const gym: CalendarEvent = {
id: 'gym',
title: 'Gym',
start: new Date('2026-07-21T18:00:00'),
end: new Date('2026-07-21T19:00:00'),
color: '#10b981',
recurrence: {
freq: 'WEEKLY',
interval: 1,
byweekday: [1, 3, 5], // Tuesday, Thursday, Saturday
},
};byweekday reference
| Value | Day |
|---|---|
0 | Monday |
1 | Tuesday |
2 | Wednesday |
3 | Thursday |
4 | Friday |
5 | Saturday |
6 | Sunday |
Full example
'use client';
import { useState } from 'react';
import { ProScheduler } from 'calendarkit-prov2';
import type { CalendarEvent } from 'calendarkit-prov2';
const recurringEvents: CalendarEvent[] = [
{
id: 'standup',
title: '☕ Daily Standup',
start: new Date('2026-07-21T09:00:00'),
end: new Date('2026-07-21T09:15:00'),
color: '#3b82f6',
recurrence: { freq: 'DAILY' },
},
{
id: 'gym',
title: '🏋️ Gym',
start: new Date('2026-07-21T18:00:00'),
end: new Date('2026-07-21T19:00:00'),
color: '#10b981',
recurrence: {
freq: 'WEEKLY',
byweekday: [1, 3, 5], // Tue, Thu, Sat
},
},
{
id: 'retro',
title: 'Sprint Retrospective',
start: new Date('2026-07-24T15:00:00'),
end: new Date('2026-07-24T16:00:00'),
color: '#8b5cf6',
recurrence: {
freq: 'WEEKLY',
interval: 2, // every 2 weeks (biweekly)
},
},
{
id: 'monthly',
title: '📊 Monthly Review',
start: new Date('2026-07-07T14:00:00'),
end: new Date('2026-07-07T15:30:00'),
color: '#f59e0b',
recurrence: {
freq: 'MONTHLY',
count: 12, // 12 months
},
},
];
export default function RecurringExample() {
const [events, setEvents] = useState<CalendarEvent[]>(recurringEvents);
return (
<div className="h-[700px] border rounded-xl overflow-hidden">
<ProScheduler
view="week"
events={events}
date={new Date()}
onEventCreate={(e) =>
setEvents((prev) => [...prev, { ...e, id: crypto.randomUUID() } as CalendarEvent])
}
onEventUpdate={(updated) =>
setEvents((prev) => prev.map((e) => (e.id === updated.id ? updated : e)))
}
onEventDelete={(id) =>
setEvents((prev) => prev.filter((e) => e.id !== id))
}
/>
</div>
);
}How recurrence expansion works
When the calendar renders, it looks at all events with a recurrence field and generates virtual occurrence instances for the visible range. These instances share the same base id (e.g. 'standup') and are rendered identically to regular events. Modifying an occurrence in the modal edits the base event (updating all future occurrences).