Your first calendar
Build a navigable month with one hook.
Enable a view with true, pass your events, and tell the calendar where each event belongs.
import type { Temporal } from '@js-temporal/polyfill'
import { useCreateCalendar } from '@gobrand/react-calendar'
type Event = {
id: string
title: string
date: Temporal.PlainDate
}
function Calendar({ events }: { events: Event[] }) {
const calendar = useCreateCalendar({
views: { month: true },
items: events,
getDate: event => event.date,
})
return (
<section>
<h2>{calendar.title()}</h2>
{calendar.activeView.weeks.flat().map(day => (
<div key={day.id}>
{day.date.toString()}: {day.items.map(event => event.title).join(', ')}
</div>
))}
</section>
)
}That is the whole setup. TypeScript infers the event type, and calendar.activeView is a MonthView because month is the only enabled view.
July 2026
Sun
Mon
Tue
Wed
Thu
Fri
Sat
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
The preview is live. Its source uses small website-only components for markup and styles; its calendar state and month data come directly from useCreateCalendar.
What the library does
- Keeps the current date and active view.
- Moves with
previous(),next(), andtoday(). - Gives you a localized
title()and timezone-awarevisibleRange. - Builds the month, week, or day data you render.
Your app owns the markup, styles, data fetching, and caching.
Add week and day views
const calendar = useCreateCalendar({
views: {
month: true,
week: true,
day: true,
},
items: events,
getDate: event => event.date,
})An omitted view is unavailable. Use an options object instead of true when a timed week or day needs custom hours or slot length.