react-calendar: a headless-ish date grid for React, and what it refuses to do
Ultimate calendar for your React app.
At a glance
- What is it?
- wojtekmaj/react-calendar renders a calendar grid and hands you the selected value; it does not ship an input, a popover, or an event layer. Here is what that means for a project that needs a date picker.
- Who is it for?
- Adopt react-calendar if you are rendering a calendar grid inside a page, an inline booking surface, or a filter panel, and you intend to wrap it in your own input, popover or modal. Do not adopt it if you need a text field that opens a calendar on focus, or a scheduler with timed events laid out across columns; the README lists neither, and the props table does not cover them.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 21 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What react-calendar actually renders, and who it is for
The README opens with a one-line pitch and a four-item list: pick days, months, years, or even decades; range selection; support for virtually any language; no moment.js needed. That list is the whole scope. There is no input field in it, no popover, no time component, no event model. What you get is an interactive grid that displays a period and reports the value a user picked through onChange.
That places the library in a specific niche. If you are building a dashboard filter, an inline availability view, or a booking surface where the calendar is already visible on the page, the component is the finished piece. If you are building a form field that looks like a text box until the user clicks it, react-calendar is the inside of that widget and you still have to build the outside: the input, the focus handling, the popover positioning, the close-on-outside-click behaviour. The README does not describe any of that, and the props table it does publish is about the grid, not about a trigger.
The scope also explains the dependency stance. Dropping moment.js is not a stylistic preference here; the README says the project uses modern web technologies and supports only modern browsers, linking to a caniuse.com page for internationalization. Date formatting and locale data come from the platform, which is why the bundle stays small and why old browsers are out of the question without a polyfill.
How the value flows: one controlled prop, one callback
The usage example in the README is the architecture in miniature. State holds a value, the Calendar receives it as value, and onChange writes back into that state. It is a controlled component in the ordinary React sense, and the README also notes an uncontrolled path: use defaultActiveStartDate instead of activeStartDate when you do not want to drive the displayed period yourself.
The interesting part is the value type. The README's example declares ValuePiece as Date | null and Value as a single piece or a two-element tuple of pieces. So the same prop carries either one date or a range, and null is a legitimate member of the type, meaning an empty selection has a representation rather than being an error case. Range mode is switched on with the selectRange prop, and allowPartialRange controls whether onChange fires with a one-sided result before the user has picked the second date. That last prop is the one people miss: without it, a range selection stays silent until both ends exist.
Beyond the grid, calendarType changes the calendar system rather than the locale. The README lists gregory, hebrew, islamic and iso8601, and spells out the knock-on effects: gregory and hebrew move the first day of the week to Sunday, islamic moves it to Saturday, and islamic or hebrew put the weekend on Friday and Saturday. This is a real behavioural difference, not a label, and it is the kind of thing that is easy to forget when a product expands beyond its first market.
Installing react-calendar and getting a first selection working
Installation is one command, per the README's tl;dr: npm install react-calendar, or yarn add react-calendar if you are on Yarn. Nothing else is required to get the grid on screen.
npm install react-calendarImport the component and render it. The README's own example uses a state hook and a typed value, so the calendar is controlled from the first render rather than being left to manage itself.
import { useState } from 'react';
import Calendar from 'react-calendar';
type ValuePiece = Date | null;
type Value = ValuePiece | [ValuePiece, ValuePiece];
function MyApp() {
const [value, onChange] = useState<Value>(new Date());
return (
<div>
<Calendar onChange={onChange} value={value} />
</div>
);
}What you should see is an interactive calendar with today's date selected, because the initial state is new Date(). Clicking another day replaces the selection and updates the state through onChange. There is no submit button and no confirmation step; the callback fires on the click.
The component ships unstyled unless you opt in. The README gives the import path for the default stylesheet, which you add once, typically at your app entry point.
import 'react-calendar/dist/Calendar.css';If you would rather build your own look, skip that import and style the rendered markup yourself. The README frames the stylesheet as a base to build upon, not as a requirement.
For a working end-to-end example, the README points at the sample directory in the repository, which contains Sample.tsx, Sample.css, index.tsx and a Vite config. More advanced cases live in the Recipes page of the project wiki, which the README links but does not reproduce.
The gaps: no input, no events, and a documentation version mismatch
The most common mismatch between expectation and reality is the picker. A react-calendar picker, in the sense of a field that opens a calendar, does not exist in this package. The README's props table describes the calendar itself; there is no trigger prop, no open state, no render-prop for an input. Teams that install it expecting a drop-in form control end up writing the wrapper, and that wrapper is where the accessibility work lives too, which the README does not cover.
The second gap is scheduling. The README lists days, months, years and decades as selection granularities. It says nothing about hours, event durations, overlapping events, or resource columns. If your requirement is a day view with appointments stacked by time, this component gives you the day grid and nothing above it.
The third issue is documentation drift, and it is stated plainly in the README rather than hidden: the project says it is under constant development and that the documentation is written for the 4.x branch, with links to v3.x and v2.x docs for older versions. Meanwhile the release list shows v6.0.1 published on 2026-04-07, following v6.0.0 on 2025-05-29 and v5.1.0 on 2024-10-23. So the prose you are reading, including the props table, may not match the version npm resolves when you install. Treat the installed package's own type definitions as the authority and check the prop names against them before you build on a specific one.
Finally, browser support is a hard boundary, not a soft one. The README says the project supports only modern browsers and links to caniuse for internationalization, and it offers Intl.js or another Intl polyfill as the workaround for unsupported locales. If you ship to an environment without Intl, you are adding a polyfill, and that changes your bundle story.
Where react-calendar sits next to react-big-calendar
The closest thing to a direct alternative in the same ecosystem is react-big-calendar, and the difference is structural rather than cosmetic. react-big-calendar is built around events and views: month, week, day and agenda layouts, with events positioned on a time axis. react-calendar has no event concept at all. It reports the date or range the user selected and stops there.
That makes the choice fairly mechanical. If your data is a list of things that happen at times, and the calendar's job is to lay those things out, react-calendar is the wrong tool and you will spend your time rebuilding what react-big-calendar already does. If your data is a selection, a filter, or a single date the user is choosing, react-big-calendar brings an event model you will not use and a heavier surface to style around.
There is a middle path worth knowing about. Because react-calendar is a grid with a value and a callback, you can render it and place your own content in the tile, or use it purely as a date selector above a list you render yourself. That keeps the event rendering under your control. It is more work than picking an event-first library, and the README does not walk through it, but it is the natural consequence of the component's narrow scope.
The same reasoning applies to comparisons against date-picker libraries. The distinction is not features versus simplicity; it is whether the calendar is the visible surface or the hidden half of an input. react-calendar is the former.
Maintenance, upgrades and the MIT licence
The repository is not archived, and the last push was on 2026-09-09, roughly two weeks before this writing. Releases, however, are sparse: v5.1.0 on 2024-10-23, v6.0.0 on 2025-05-29, and v6.0.1 on 2026-04-07. There is a gap of more than a year between the v5.1.0 and v6.0.0 releases, and the jump from 5.x to 6.x is a major version, which by convention means breaking changes. The README does not include a migration guide, and it does not document rollback, so the upgrade path from 5.x to 6.x has to be reconstructed from the release notes and the type definitions in the installed package.
The repository is a Yarn 4 monorepo, with packages/ holding the published library and separate test and sample workspaces, plus biome.json for formatting and linting and a husky postinstall hook. That layout matters if you intend to contribute rather than consume: the build, test and type-check scripts are per-workspace, and the root package.json is private, so you cannot publish from the root.
The licence is MIT. In practical terms that permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained, but this is a description of the licence identifier, not legal advice, and your organisation's own review is the thing that decides whether MIT fits your distribution model. The README does not discuss licensing beyond the repository's LICENSE file.
Editorial conclusion
Adopt react-calendar if you are rendering a calendar grid inside a page, an inline booking surface, or a filter panel, and you intend to wrap it in your own input, popover or modal. Do not adopt it if you need a text field that opens a calendar on focus, or a scheduler with timed events laid out across columns; the README lists neither, and the props table does not cover them. Before committing, verify two things yourself: that your target browsers support the Intl internationalization features the README points at on caniuse.com, and that the prop names you plan to use match the version you install, because the README states it documents the 4.x branch while the newest release listed is v6.0.1.
Frequently asked questions
How do I install react-calendar?
Run npm install react-calendar, or yarn add react-calendar if you use Yarn. Then import the component with import Calendar from 'react-calendar' and render it. The README notes your project needs React 16.8 or later.
What is react-calendar and what does it do?
It is a React component that displays an interactive calendar and reports the selected value through onChange. According to the README you can pick days, months, years or decades, and range selection is supported.
How do I use react-calendar in a component?
The README's example holds the value in useState, passes it to the value prop and passes the setter to onChange. The initial value there is new Date(), so today starts selected. A full working example sits in the sample directory of the repository.
Does react-calendar include a time picker?
The README lists days, months, years and decades as the selectable granularities, and its props table covers the calendar grid. It does not document any hour or time selection, so a time picker would have to come from somewhere else.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wojtekmaj-react-calendar)