
How To Implement A Date Picker In React
We have third-party libraries that we can integrate into our project to extend the existing functionality of date pickers. In this article, let's explore date pickers in React.

Kaushal Joshi
May 23, 2025 • 18 min read
Forms in React! I can go on and on writing about this. Managing different states, different types of input, validating them, and displaying correct loading or error states becomes overwhelming at one point. Most of the things I mentioned have become manageable, thanks to libraries like React Hook Form and Zod. But one thing remains cumbersome and still requires special attention: handling date inputs.
Yes, HTML provides a native date picker with <input />
and it does its job. But honestly, it is very limited and can't do much beyond selecting a date, time, or month. And styling the native date picker is a different quest in itself.
In React, we have third-party libraries that we can integrate into our project to extend the existing functionality of date pickers. In this article, let's explore date pickers in React. We will also see the native date picker and its limitations. Then we will also see some NPM libraries that you can use. And finally, we'd focus on react-day-picker
, the library best suited to be used as a date picker in React.
The Native Date Picker
HTML provides a native date picker, and you must have used it at least once in your project -- before you started to look for a different approach. It's simple to implement, and the browser handles the UI for you. Let me remind you how it works:
export default function DatePicker() {
return (
<div>
<label htmlFor="bday">Birth date:</label>
<input type="date" id="bday" name="bday" />
</div>
);
}
This is how it looks:

Pretty straightforward. You get a popover that lets you select the date without writing a single line of code. It gives you a prettified human-readable string that you can easily convert to Date
object with new Date()
constructor.
Limitations with the native date picker
However, there are many limitations with the native date picker.
Limited styling: Customizing the appearance of the native date picker is notoriously difficult and inconsistent across browsers. Want to change colors, font, or the layout? All the best!
Inconsistent UI: The look and feel of the date picker can vary significantly between Chrome, Firefox, Safari, and other browsers. This can lead to a jarring user experience on your website.
Lack of Advanced Features: Need to select date ranges? Disable specific dates? Implement custom date formatting? The native date picker simply doesn't offer these functionalities out of the box.
Localization Challenges: While browsers handle basic localization, more complex scenarios like custom date formats or specific regional calendar behaviors can be tricky to implement reliably.
The native date picker is only good for basic projects. But your project is extraordinary and needs special attention to detail, right? Going beyond the basics that require a beautiful UI or complex logic is difficult with the native date picker. And hence, there exist third-party libraries that do the same for you.
Overview of Popular Date Picker Libraries in React
Before we explore react-day-picker
, I want to quickly go through some other libraries that do the same. If you find any other library that fits your needs better, feel free to use it.
react-datepicker
A well-established library with a rich feature set, including support for date ranges, inline display, and time selection as well.
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
const ReactDatepickerExample = () => {
const [startDate, setStartDate] = React.useState(new Date());
return <DatePicker selected={startDate} onChange={(date) => setStartDate(date)} />;
};
export default ReactDatepickerExample;
Pros: Mature ecosystem, excellent documentation, and wide adoption.
Cons: Heavier bundle size, requires careful styling to match your design system.
You can check out react-datepicker on NPM here.
Material UI Date Picker
This library is part of the MUI component library and integrates tightly with MUI's design system. If you're using Material UI in your project, just go with this library right away.
import { LocalizationProvider, DatePicker } from '@mui/x-date-pickers';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
const MUIDatePickerExample = () => {
const [value, setValue] = React.useState(null);
return (
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker value={value} onChange={(newValue) => setValue(newValue)} />
</LocalizationProvider>
);
};
export default MUIDatePickerExample;
Pros: Consistent design, rich feature set, strong TypeScript support.
Cons: Heavier dependency if you’re not using MUI for the rest of your UI.
You can check out Material UI Date Picker on NPM here.
react-calendar
A simpler, lightweight option ideal for straightforward date picking.
import Calendar from 'react-calendar';
import 'react-calendar/dist/Calendar.css';
const ReactCalendarExample = () => {
const [date, setDate] = React.useState(new Date());
return <Calendar onChange={setDate} value={date} />;
};
export default ReactCalendarExample;
Pros: Lightweight, easy to use, minimal setup.
Cons: Lacks some advanced features like date ranges and complex event handling.
You can check out react-calendar on NPM here.
react-day-picker
This is our topic for the day! It is lightweight, feature-rich, and highly customizable. This is perfect for all the complex use cases where you need fine-grained control over date selection and styling.
The only downside I see with react-day-picker
is that there's a learning curve, and you need to spend more time setting up things for advanced use cases. But with great power comes great responsibility. So I am fine with it.
What is React Day Picker?
react-day-picker
is a highly customizable and accessible date picker component library for React. It lets you create date pickers, calendars, and date inputs while giving you granular control over their look and feel.
What are the features of react-day-picker
?
Flexible Rendering: You have complete control over how each day, week, and month is rendered. This allows for highly customized UIs.
Multiple Selection Modes: Supports single date selection, multiple date selection, and date range selection out of the box.
Date Formatting and Parsing: Offers powerful utilities for formatting and parsing dates according to different locales and patterns.
Accessibility: Built with accessibility in mind, ensuring a good experience for all users, including those using assistive technologies.
Customizable Styling: While it doesn't come with default styling, it provides clear and well-structured CSS classes that you can easily target and customize to match your application's design.
Localization Support: Designed to handle different languages and regional date formats effectively.
Timezone Considerations: While the library itself focuses on date selection, it provides the flexibility to integrate with timezone management libraries if needed.
Custom Components: You can also create custom components for each section of the date picker. Very useful when you are building your own design system.
With over 500k weekly NPM downloads and over 7,000 GitHub stars as of writing this article, react-day-picker
is undoubtedly a great choice for your project.
How react-day-picker
stands out:
We saw some date picker libraries in the last section. I have used some of them in my projects before, but I ended up choosing react-day-picker as my go-to React day picker library. Let me explain why.
react-day-picker
differentiates itself by being less opinionated about styling compared to other libraries. It gives you raw power and flexibility to build a date picker that looks and behaves exactly as you want, without being constrained by pre-defined themes. This makes it an excellent choice for projects with custom design systems or themes.
Even projects like shadcn/ui prefer react-day-picker
for the same.
How to install react-day-picker
in your React Application?
You can install react-day-picker
simply by installing it as a dependency in your existing React project:
npm i react-day-picker
yarn add react-day-picker
pnpm add react-day-picker
Getting Started with React Day Picker
Let's start with a simple example of how to integrate react-day-picker
for single date selection.
import React, { useState } from 'react';
import { DayPicker } from 'react-day-picker';
import 'react-day-picker/dist/style.css';
export default function SingleDatePicker() {
const [selectedDate, setSelectedDate] = useState(undefined);
return (
<div>
<h2>Select a Date</h2>
<DayPicker
mode="single"
selected={selectedDate}
onSelect={setSelectedDate}
/>
{selectedDate ? (
<p>You selected: {selectedDate.toLocaleDateString()}</p>
) : (
<p>Please select a date.</p>
)}
</div>
);
}
This is how it'd render:

First, we defined a local state to store the date:
selectedDate
.Then we imported the
<DatePicker />
component and its default styles. We use thesingle
mode as we want to select a single date.The
selected
prop holds the currently selected date (i.e.,selectedDate
), and theonSelect
prop updates the state with the newly selected date. It is called whenever the user clicks on a day.
NOTE: Don't forget to import the default styles
Select multiple dates
To allow users to select multiple dates, we can use mode="multiple"
and manage the selceted
prop as an array of Date
objects.

export default function MultiDatePicker() {
const [selectedDates, setSelectedDates] = useState([]);
return (
<DayPicker
mode="multiple"
selected={selectedDates}
onSelect={setSelectedDates}
/>
);
}
Select a date range
For selecting a range of dates, we use mode="range"
and the selected
prop will be an object with from
and to
properties. Both from
and to
can be Date
objects or undefined
.

export default function RangeDatePicker() {
const [selectedRange, setSelectedRange] = useState(undefined);
return (
<DayPicker
mode="range"
selected={selectedRange}
onSelect={setSelectedRange}
/>
);
}
Disabling specific dates
You can disable specific dates using the disabled
prop. This prop accepts an array of Date
objects or a function that takes a Date
object and returns a boolean indicating whether the date should be disabled.

export default function DisabledDatePicker() {
const [selectedDate, setSelectedDate] = useState(undefined);
const disabledDates = [
new Date(2025, 4, 15), // May 15th, 2025 (month is 0-indexed)
new Date(2025, 4, 20),
];
// Disable Sundays and Saturdays
const isWeekend = (date) => date.getDay() === 0 || date.getDay() === 6;
return (
<DayPicker
mode="single"
selected={selectedDate}
onSelect={setSelectedDate}
disabled={[...disabledDates, isWeekend]}
/>
);
}
Specify minimum and maximum dates
You can restrict the selectable date range using the minDate
and maxDate
props.
export default function MinMaxDatePicker() {
const [selectedDate, setSelectedDate] = useState(undefined);
const minDate = new Date(2025, 4, 10);
const maxDate = new Date(2025, 4, 25);
return (
<DayPicker
mode="single"
selected={selectedDate}
onSelect={setSelectedDate}
minDate={minDate}
maxDate={maxDate}
/>
);
}
Customizing The Calendar
In this section, let's see how you can customize various sections of the calendar built using react-day-picker.
Show dates outside of the month
This prop lets you decide whether you want to display outside days. Days that are in the next month or the previous month. By default, it is false
.

<DayPicker mode="single" showOutsideDays />
Show week numbers
This prop lets you decide whether you want to display the week numbers column. The weeks are numbered according to the local week index.

<DayPicker mode="single" showWeekNumber />
Show multiple months
You can decide how many months you want to display when the date picker is displayed. It is useful when you want to let the user select date ranges.

DayPicker mode="range" numberOfMonths={2} />
You can pass the animate
property along with this, so that the navigation between pages is smoother. You can pass this property regardless of whether you are using numberOfMonths
.
Define caption layout
You can decide the layout of the caption of the calendar. By default, it will just be a string that displays the month and the year.
label
: Display the month and the year as a label. Change the label with theformatCaption
formatted.<DayPicker captionLayout="label" mode="single" /> // Default option, no need to mention
dropdown
: Display the dropdown for both month and year.<DayPicker captionLayout="dropdown" endMonth mode="single" startMonth />
dropdown-months
: Display only the dropdown for the months.<DayPicker captionLayout="dropdown-months" endMonth mode="single" startMonth />
dropdown-years
: Display only the dropdown for the years.<DayPicker captionLayout="dropdown-years" endMonth mode="single" startMonth />
Localization & Timezones
react-day-picker
truly shines when it comes to localization. You can easily customize the display of month and weekday names, as well as the first day of the week, by providing custom formatting functions. You can extend the functionality by using libraries like date-fns
or even built-in toLocaleDateString()
method.
Selecting timezone
You can use the timeZone
prop to define the time zone for your dates. The time zone can be specified as either an IANA time zone identifier or a UTC offset.
<DayPicker timeZone="UTC" /> // Use Coordinated Universal Time
<DayPicker timeZone="Pacific/Kiritimati" /> // Use Line Islands Time
<DayPicker timeZone="+02:00" /> // Use UTC+2
<DayPicker mode="single" timeZone="Asia/Calcutta" /> // Use Indian Time
Select calendar type
react-day-picker
also allows you to choose between calendar type: Gregorian
or Persian
. If you want to use the Persian calendar, you must import the <DatePicker />
component form react-day-picker/persian
.

import { DayPicker } from "react-day-picker/persian";
<DayPicker mode="single" timeZone="UTC" />
Select a locale for the date picker
You can also select a locale for your date picker to follow.

<DayPicker mode="single" locale="fr" />
Visit date-fns documentation to get a list of all supported locales.
Select the starting day of the week
You can specify which day you want to be the starting day of the week. In most countries, either Sunday or Monday is considered the first day of the week. react-day-picker
selects the first day of the week based on your browser locale. But you can customize it as well:

<DayPicker mode="single" weekStartsOn={3} /> // Wednesday
weekStartsOn
accepts a number between 0 and 6. Here, 0 stands for Sunday, 1 for Monday, and so on.
Select numerals language
You can also get more personal and gain even more granular control of your date picker by specifying the numeral system to be used to format dates.
<DayPicker mode="single" numerals="deva" />

Visit react-day-picker documentation to get a list of all available numerals.
Date Picker Helper Functions
The react-day-picker
library provides plenty of helper functions to attach on various triggers in the date picker. We saw onSelect
in one of our previous examples. Let's quickly go through some other functions as well.
onDayBlur
: Triggered when a day is blurred.onDayClick
: Triggered when the user clicks on a day.onDayFocus
: Triggers when a day is focused.onDayKeyDown
: Triggers whenever a key is pressed on a day.onDayMouseEnter
: Triggers whenever the mouse enters a day.onDayMouseLeave
: Opposite toonDayMouseEnter
, this triggers whenever the cursor leaves the dayonMonthChange
: Triggers whenever the user navigates between monthsonNextClick
: Triggers when the next month button is clicked.onPrevClick
: Triggers when the previous month button is clicked.
Integrating with React Hook Form and Zod
Integrating react-day-picker
with form libraries like React Hook Form and validation libraries like Zod allows you to manage your date inputs within a robust form management system.
Here's an example of integrating with React Hook Form & Zod. If you are following along, make sure you install both libraries.
import React from 'react';
import { useForm, Controller } from 'react-hook-form';
import { DayPicker } from 'react-day-picker';
import 'react-day-picker/dist/style.css';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
const schema = z.object({
eventDate: z.date({ required_error: 'Event date is required.' }),
});
export default function FormWithDatePicker() {
const { handleSubmit, control, formState: { errors } } = useForm({
resolver: zodResolver(schema),
});
const onSubmit = (data) => {
console.log('Form Data:', data);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="eventDate">Event Date:</label>
<Controller
name="eventDate"
control={control}
render={({ field }) => (
<DayPicker
mode="single"
selected={field.value}
onSelect={field.onChange}
/>
)}
/>
{errors.eventDate && <p style={{ color: 'red' }}>{errors.eventDate.message}</p>}
</div>
<button type="submit">Submit</button>
</form>
);
}
Let's understand what we wrote:
We use the
useForm
hook from React Hook Form.We define a Zod schema to validate the
eventDate
field, ensuring it's a date and is required. ThezodResolver
is used to integrate this schema with React Hook Form.The
Controller
component connects theDayPicker
with the form state.The
render
prop ofController
receives thefield
object, which containsvalue
andonChange
that we pass to theselected
andonSelect
props ofDayPicker
, respectively.We can then access form state and validation errors through the
formState
object.
Styling React Day Picker Component
The react-day-picker
library provides several ways to style your component.
Use classname
to directly apply classes to the root
The most straightforward way to style react-day-picker
is by using the className
prop. This works just like the standard className
prop on any HTML element in React. You can apply one or more CSS classes defined in your stylesheets to the DayPicker
component.

Here's the CSS and the component for the same
.calendar-root {
background-color: #00ffff;
color: #141414;
padding: 1rem;
border-radius: 0.5rem;
}
import "./styles.css";
import React, { useState } from "react";
import { DayPicker } from "react-day-picker";
import "react-day-picker/dist/style.css";
export default function DatePickerWithModifiedClassName() {
const [selectedDate, setSelectedDate] = useState(new Date());
return (
<div>
<DayPicker
mode="single"
classname="calendar-root"
selected={selectedDate}
onSelect={setSelectedDate}
/>
</div>
);
}
Use classnames
to override the default class names of date picker elements
Use this prop when you need to change the default class names — for example, when importing the style via CSS modules or when using a CSS framework.

Here's the CSS and the component for the same:
.calendar-root {
background-color: #00ffff;
color: #141414;
padding: 1rem;
border-radius: 0.5rem;
}
.day {
padding: 1rem;
border: 1px solid pink;
background-color: #cecece;
}
import "./styles.css";
import React, { useState } from "react";
import { DayPicker } from "react-day-picker";
import "react-day-picker/dist/style.css";
export default function DatePickerWithModifiedClassNames() {
const [selectedDate, setSelectedDate] = useState(new Date());
return (
<div>
<DayPicker
mode="single"
classNames={{ root: "calendar-root", day: "day" }}
selected={selectedDate}
onSelect={setSelectedDate}
/>
</div>
);
}
You can find a list of all classnames used to override styles of UI, selection states, and day flags on their respective documentation pages.
Use style
to add inline styles to the root
The style
prop allows you to apply inline styles directly to the DayPicker
component. This works like the standard style
prop in React, where you pass a JavaScript object containing CSS properties and values.
A few things to remember while using the style
prop:
Inline styles have the highest specificity and will override styles from CSS files. While convenient for quick, component-specific styling, overuse of inline styles can make your code harder to maintain and can lead to a lack of consistency across your application.
Generally, it's recommended to use CSS classes for most styling needs and reserve inline styles for dynamic styles based on component state or props, or for very specific, isolated styling.

export default function StyledDatePickerWithInlineStyle() {
const [selectedDate, setSelectedDate] = useState(undefined);
const customStyle = {
border: '2px solid #00c853',
borderRadius: '8px',
padding: '15px',
fontFamily: 'monospace',
};
return (
<DayPicker
mode="single"
selected={selectedDate}
onSelect={setSelectedDate}
style={customStyle}
/>
);
}
Add inline styles to specific parts with styles
The styles
prop that allows you to apply inline styles directly to specific parts (sub-components) of the date picker. This gives you fine-grained control over the appearance of individual elements.
The styles
prop accepts an object where the keys correspond to the names of the sub-components you want to style (e.g., caption
, head
, body
, day
, navButton
, etc.), and the values are style objects.

export default function DatePickerWithModifiedStyles() {
const [selectedDate, setSelectedDate] = useState(new Date());
const monthCaptionStyle = {
borderBottom: "1px solid currentColor",
paddingBottom: "0.5em",
};
return (
<div>
<DayPicker
mode="single"
selected={selectedDate}
onSelect={setSelectedDate}
styles={{
month_caption: monthCaptionStyle
}}
/>
</div>
);
}
You can find a list of all classnames used to override styles of UI, selection states, and day flags on their respective documentation pages.
Choosing the Right Styling Approach
The best styling approach depends on your project's needs and your preferences:
className
: Ideal for applying consistent styles defined in your CSS files, especially when working with CSS modules or styled components.classnames
: Excellent for managing conditional and dynamic CSS class names, making your styling logic cleaner and more maintainable.style
: Use sparingly for highly specific, often dynamic, inline styles on the mainDayPicker
container. Avoid overusing it for general styling.styles
: The most powerful option for applying targeted inline styles to the internal parts of theDayPicker
. Use this when you need fine-grained control over the appearance of specific elements without writing complex CSS selectors or relying on!important
.
In practice, you might even combine these approaches. For example, you could use className
for general layout and theming, and the styles
prop for tweaking the appearance of specific elements like the navigation buttons or selected day.
Creating Custom Date Picker Components With React Day Picker
This is the final boss. This shows how powerful and robust the react-day-picker
library is. You can provide custom components to render the calendar with react-day-picker
.
You can pass the set of components as objects, where every key is a part of the calendar anatomy (like day, day button, footer, month, etc.), and the value is the custom component that you built.
import React from "react";
import { DayButtonProps, DayPicker } from "react-day-picker";
const SelectedDateContext = React.createContext<{
selected?: Date;
setSelected?: React.Dispatch<React.SetStateAction<Date | undefined>>;
}>({});
function DayButton(props: DayButtonProps) {
const { day, modifiers, ...buttonProps } = props;
const { setSelected } = React.useContext(SelectedDateContext);
return (
<button
{...buttonProps}
onClick={() => setSelected?.(undefined)}
onDoubleClick={() => setSelected?.(day.date)}
/>
);
}
export function CustomDayButton() {
const [selected, setSelected] = React.useState<Date>();
return (
<SelectedDateContext.Provider value={{ selected, setSelected }}>
<DayPicker
mode="single"
selected={selected}
onSelect={setSelected}
components={{
DayButton
}}
footer={selected?.toDateString() || "Double click to select a date"}
/>
</SelectedDateContext.Provider>
);
}
This is how it'd render on the screen:

There are a lot of components you can override by providing a custom component. You can find a list of all components on the react-cay-picker official documentation. By leveraging these custom components, you can achieve highly specific and unique date picker UIs.
Wrapping Up
There are so many things react-day-picker has to offer. We covered everything that you need to build your own Date Picker component on top of it. You can mix and match the options, styles, and customize them as you want.
I hope you found this article helpful. If you did, feel free to share this within your friends and peers so that they can also learn from this. If you want to connect with me, I am active on Peerlist and Twitter.
If you are looking for a new job or want to share a cool project you built, consider Peerlist! It is a professional network for builders to show & tell!
Until then, happy validating!