How to Create a Calendar in React JS?

author
Vishal Gothi Frontend Development Specialist, WPWeb Infotech

Quick Summary: This guide explains how to create a calendar in React.js using the `react-calendar` library. It covers the prerequisites, installation, basic calendar setup, CSS customization, date selection, date-range pickers, date restrictions, event markers, and custom navigation labels. The guide also compares using `react-calendar` with building a calendar from scratch to help developers choose an approach based on their project’s customization and complexity requirements.

You can create a functional calendar in React.js quickly by using a library such as `react-calendar`, rather than building the calendar grid and date-handling logic from scratch. It provides built-in support for date selection, navigation, accessibility, and customization, while React state and props let you adapt the calendar to your application’s requirements.

React calendars can support much more than simple date selection. Depending on the application, you may need features such as date-range selection, disabled past dates, event markers, custom styling, or booking-related restrictions. A suitable calendar component can provide these capabilities while reducing the amount of custom logic you need to develop.

In this guide, you’ll learn how to create a React calendar step by step, starting with the basic setup and `react-calendar` installation. You can consult a React JS development company to build a custom calendar for your business.

What is a React Calendar Component?

A React Calendar Component is a reusable user interface (UI) element built for a React application that allows users to view, select, and interact with dates in a structured calendar format. 

Instead of building a date-selector grid from scratch, developers use these pre-made components to implement features ranging from a simple birthdate picker to a complex enterprise event scheduler. The following are the core features of the calendar in React JS: 

  • Flexible Views: Most components offer toggleable views for individual days, weeks, months, years, or entire decades. 
  • State Management: In React, a calendar dynamically tracks state changes, such as the current date view, active selections, or highlighted date ranges. 
  • Restrictions & Validation: Developers can easily block out specific dates, such as weekends, past dates, or corporate holidays. 
  • High Customization: You can style individual calendar cells or apply themes to blend seamlessly with the rest of your web application. 

The following is a comparison of the popular React JS calendar components: 

Library Primary Use Case Licensing Model Built for Custom UI 
react-datepickerBasic form date inputs Free (MIT) Standard theme 
react-calendar Inline custom widgets Free (MIT) Highly flexible 
react-big-calendarHeavy event scheduling Free (MIT) Layout mimics Google Calendar 
FullCalendar Full event dashboards Freemium (paid plugins)Highly Modular 
SVAR Calendar Modern dashboard views Freemium (paid PRO features) Modern & React-first
Bryntum Calendar Scale resource management Commercial licenses JSX custom layout cells 

Prerequisites and Project Overview

You should have a React project setup using:

  • Basic knowledge of React (components, props, state, hooks)
  • Node.js (v14+ recommended)
  • npm or yarn installed
  • A React project setup using:
npx create-react-app react-calendar-app
cd react-calendar-app
npm start

Overview: Use the React-Calendar library to quickly build a functional calendar, add styling and customization and extend it with advanced features like:

  • Event markers
  • Date range selection
  • Navigation labels (Next/Prev)

Step-by-Step Guide to Create a Custom Calendar in React JS

The following are the steps to create a custom calendar in React JS: 

Step 1: Install the Library 

We will use the react-calendar library, which handles complex layout logic and date mechanisms. Open your terminal and run one of the following commands: 

Install via npm:  npm install react-calendar

Install via yarn: yarn add react-calendar

Running this command fetches the library’s pre-written code files and adds them straight into your project’s node_modules folder. Once the installation is finished, you will immediately have access to three core features built directly into your library without needing to code them from scratch. 

  • Date Selection: The engine that handles user clicks and tracks exactly which day, or a range of days, users selected. 
  • Month/year Navigation: The functional logic and React button components required to shift views backward and forward through time seamlessly. 
  • Built-in Accessibility: Standardized keyboard navigation controls and screen-reader-friendly tags (ARIA attributes) to ensure the calendar is usable for everyone. 

Step 2: Adding a Calendar with React-Calendar

To display the calendar, import the components and bind it to the local state variable. This tracks the active date selection context.

import React, { useState } from "react";
import Calendar from "react-calendar";
import "react-calendar/dist/Calendar.css";

function App() {
  const [date, setDate] = useState(new Date());

  return (
    <div>
      <h2>React Calendar</h2>

      <Calendar
        onChange={setDate}
        value={date}
      />

      <p>Selected Date: {date.toDateString()}</p>
    </div>
  );
}

export default App;

What’s Happening Here: 

  • useState: Stores the selected date object. 
  • noChange: Updates state dynamically when the user selects a specific date tile. 
  • Value: Binds the currently selected date state directly back to the calendar UI. 

Step 3: Add CSS to Your React Calendar

The default layout looks unstyled unless you import the package’s default sheet. Add this import to the top of your component file, then override classes in your local CSS file to match your project branding.

.react-calendar {
  width: 350px;
  max-width: 100%;
  background: #fff;
  border: 1px solid #ddd;
  font-family: Arial, sans-serif;
}

.react-calendar__tile--active {
  background: #007bff;
  color: white;
}

.react-calendar__tile:hover {
  background: #f0f0f0;
}

You are not restricted to using a standard, raw CSS file. Depending on how your React project is structured, you can use the following alternative styling methods to improve your UI:  

  • Use Tailwind CSS: If your project uses Tailwind, you can target the calendar’s global classes inside your core configuration or layer styles to rapidly customize the design using utility classes. 
  • Use CSS Modules: You can isolate your calendar style by using module files such as calendar.module.css. This prevents your calendar’s custom styles from accidentally leaking into or breaking other parts of your website. 
  • Apply Dynamic Classes for Better UI: You can use conditional logic in JavaScript to add specific classes on the fly, such as giving completely unique background colors to weekends, holidays, or fully booked dates. 

Step 4: Customize Your React-Calendar

The final step focuses on the configuration settings built directly into the library. While CSS lets you change the look of your calendar, you can change how it behaves and functions by using Props (properties passed directly to the <Calendar /> component). 

This allows you to customize your calendar to your application’s specific business logic without writing complex custom JavaScript code. The following are some core customization options you will get: 

(I) Select a Date Range: By default, the calendar only lets a user click and select one single day. If your application requires a user to book a stay or choose a timeline, you can turn on range selection by adding the selectRange={true} prop.

<Calendar
  selectRange={true}
  onChange={setDate}
  value={date}
/>

Now the date will be stored as: [startDate, endDate] 

Once you turn on range selection, React manages the calendar’s state differently. Instead of storing a single Date object, your useState variable will now automatically save an array containing exactly two items: the first clicked date (startDate) and the second clicked date (endDate). You can safely use this array to calculate the duration of the selection or display a total price for the selected days.

(II) Disable Past Dates: If you are building a booking form, an appointment scheduler, or a ticket reservation app, you usually want to prevent users from selecting a date that has already passed. You can achieve this by using the minDate prop and setting it to the current time (new Date()). This automatically greys out and disables every calendar cell prior to today, preventing accidental backward bookings.

<Calendar
  minDate={new Date()}
/>

(III) Show Month Picker Only: Sometimes, you do not need the user to choose a specific day of the week; for example, when selecting a credit card expiration date, choosing a graduation month, or filtering a financial report by month. You can force the calendar to skip the day grid entirely and only show the month view by setting the maxDetail prop to “year“. This locks the UI so users can only click and select entire months.

<Calendar
  view="month"
/>

Adding Advanced Features to the React Calendar

The following are some alternatives to add advanced features to the React calendar: 

1. Adding Events/Markers to Calendar Days

Using tileContent to Add Markers: 

The tileContent prop acts as an automated injector that lets you insert custom HTML or components inside individual calendar tiles.

import React, { useState } from "react";
import Calendar from "react-calendar";
import "react-calendar/dist/Calendar.css";

function App() {
  const [date, setDate] = useState(new Date());

  const events = [
    new Date(2026, 3, 25),
    new Date(2026, 3, 28),
  ];

  const hasEvent = (date) => {
    return events.some(
      (event) => event.toDateString() === date.toDateString()
    );
  };

  return (
    <div>
      <Calendar
        onChange={setDate}
        value={date}
        tileContent={({ date, view }) =>
          view === "month" && hasEvent(date) ? (
            <div style={{ textAlign: "center", color: "red" }}>•</div>
          ) : null
        }
      />
    </div>
  );
}

export default App;

How It Works: 

  • Runs for Every Tile: As the calendar loads or updates, it loops through every visible day tile on the screen. 
  • Date Matching Logic: For each file, it provides you with a specific date and view object. You use this date to search through your local events array.  
  • Dynamic Reminding: If a match is found, you return a React element such as a dot, icon, or status badge that renders directly beneath the day number. If no match is found, you will return null. 

Use tileClassName for Styling:

<Calendar
  tileClassName={({ date, view }) => {
    if (
      view === "month" &&
      events.some(
        (event) => event.toDateString() === date.toDateString()
      )
    ) {
      return "highlight";
    }
  }}
/>
.highlight {
  background: #ffeb3b;
  border-radius: 50%;
}

While tileContent is used to inject extra visual elements inside a tile, tileClassName changes the background, borders, or text properties of the tile wrapper itself. It loops through every day tile and dynamically applies custom CSS classes (e.g., adding has-event, weekend-tile, or holiday-tile) based on evaluation logic.

2. Building a Date Range Picker

Basic Date Range Picker Implementation

import React, { useState } from "react";
import Calendar from "react-calendar";
import "react-calendar/dist/Calendar.css";

function App() {
  const [range, setRange] = useState([new Date(), new Date()]);

  return (
    <div>
      <h2>Select Date Range</h2>

      <Calendar
        selectRange={true}
        onChange={setRange}
        value={range}
      />

      <p>
        Start: {range[0]?.toDateString()} <br />
        End: {range[1]?.toDateString()}
      </p>
    </div>
  );
}

export default App;

How It Works: 

  • selectRange={true}: Enabling this built-in prop converts the single-date selector into a dual-action picker.
  • Selection Workflow: The first click establishes the starting date bound. The second click captures the terminal date bound.
  • State Shape: Instead of a single date object, your state update automatically provides an array containing exactly two parameters: [startDate, endDate].

Handle Partial Selection:

When a user clicks the first date, the calendar is in a partial state. You must handle instances where only a single element ([startDate, null]) exists in your state array before calculating durations or applying dependent application logic.

<p>
  Start: {range[0]?.toDateString()} <br />
  End: {range[1] ? range[1].toDateString() : "Not selected"}
</p>

Restrict Date Range:

You can bound user selections by passing parameters to the calendar:

  • minDate: Prevents selecting past dates or historical records.
  • maxDate: Prevents selections too far into the future.
<Calendar
  selectRange
  onChange={setRange}
  value={range}
  minDate={new Date()} // disable past dates
  maxDate={new Date(2026, 11, 31)} // December 31, 2026
/>

Highlight Selected Range with Custom Styling:

The library attaches standard classes (.react-calendar__tile–rangeStart, .react-calendar__tile–rangeEnd, and .react-calendar__tile–hover) across the active selection interval. You can override these classes in your global stylesheet to display smooth gradient tracks, rounded borders, or unified branding colors across the range.

.react-calendar__tile--range {
  background: #cce5ff;
}

.react-calendar__tile--rangeStart,
.react-calendar__tile--rangeEnd {
  background: #007bff;
  color: white;
}

Add Custom Logic on Range Selection:

You can trigger operations immediately following a complete double-click sequence using the onChange event hook:

const handleRangeChange = (value) => {
  setRange(value);

  if (value[0] && value[1]) {
    console.log("Range selected:", value);

    // Call API or filter data here
  }
};

<Calendar
  selectRange
  onChange={handleRangeChange}
  value={range}
/>

Output & Use Cases

  • Output Format: [startDate, endDate] (Two standardized JavaScript Date objects).
  • Primary Use Cases:
    • Booking Systems: Selecting hotel check-in and check-out periods.
    • Reports Filtering: Scoping performance dashboards or analytics charts down to specific quarters.
    • Travel Apps: Isolating departure and return flights on flight aggregates.

3. Next and Prev Labels

Customize Navigation Button:

You can replace the default navigation typography indicators (‹ and ›) with a custom UI string by passing text directly into the wrapper component attributes:

<Calendar
  nextLabel="Next >"
  prevLabel="< Prev"
/>

Use Icons:

For cleaner layouts, you can pass structural visual components, inline SVG graphics, or FontAwesome nodes directly into the label parameter:

<Calendar
  nextLabel=">"
  prevLabel="<"
/>
Approach Setup Effort Customization Limits Best Used For 
Using react-calendar Minimal
(minutes) 
High control via props and custom target styling Fast turnarounds, general dashboards, booking systems, and standard tools
Building from scratch Significant (hours/days) Absolute control over logic, behavior, layout, and rendering grids Deep integrations, highly specialized interfaces, or tightly wrapped design suites 

Conclusion 

Creating a calendar in React.js does not require building every date and navigation feature from scratch. With `react-calendar`, developers can quickly implement a functional calendar and extend it with styling, date restrictions, range selection, event markers, and customized navigation to match application requirements.

For projects that need a standard calendar with moderate customization, using `react-calendar` can reduce development effort and provide a practical starting point. However, applications with highly specialized layouts, complex integrations, or a need for full control over calendar behavior may benefit from building a custom calendar from scratch. The right approach ultimately depends on the project’s functionality, customization needs, and development complexity. You can also hire a React JS development company to build a customized calendar in React JS from scratch.

Want expert assistance with your React project?

FAQs 

Can I use React Calendar with TypeScript?

Yes, you can use react-calendar with TypeScript. The react-calendar npm package comes with built-in TypeScript definitions. You don’t need to install the external @types/react-calendar package, as those types have been deprecated in favor of the native type definitions bundled directly within the library.

How to create a scheduler in React?

To create a scheduler in React, you can either build a custom scheduler from scratch using HTML grid/flexbox layout and React state, or use a pre-built open-source or commercial library.

Which React calendar library is best?

There is no single best React calendar library, as the choice completely depends on what you are trying to build. In the React ecosystem, packages are generally divided into three distinct categories: Date Pickers (for forms), Full-Size Event Calendars (like Google Calendar), and Enterprise Schedulers (for complex resource planning).

Can I use FullCalendar in React?

Yes, you can use FullCalendar in React. FullCalendar offers an integrated React component via the @fullcalendar/react package. Rather than acting as a simple wrapper around a vanilla JavaScript library, it hooks directly into React’s virtual DOM, ensuring excellent performance and compatibility with features like Server-Side Rendering (SSR) and StrictMode.

Is there a free calendar API available for React?

Yes, there are many free, open-source calendar APIs available for React. Your choice depends on whether you need a full scheduling engine, a visual UI calendar component, or a data-sync API; you have distinct free options.