mrkeyoor.com_
Sat 08 Aug 20:58 UTC
npmWeb Frontendupdated 08 Aug 2026

react-datepicker

react-datepicker is a controlled React date and time picker built around native JavaScript Date objects and date-fns. It supplies the text input, floating calendar, keyboard navigation, date ranges, multiple selection, month and year pickers, time lists, localization, portals, inline calendars, blocked or highlighted dates, and custom headers or inputs. Version 9 supports React 16.9 through 19 and includes TypeScript declarations and CSS. It is a styled component rather than a headless calendar primitive, and form serialization remains your responsibility.

Verdict

A capable default when a React application wants a styled, controlled Date-based picker with many modes and can accept date-fns plus supplied CSS. Avoid it when date-only serialization, headless styling, or an existing UI-system integration matters more than its long feature list.

API stability4/5The central `selected` and `onChange` controlled contract has survived years of releases, and current declarations distinguish single, range, and multiple-selection callback types. React support spans 16.9 through 19 and both ESM and CommonJS exports are present. Major upgrades still carry real risk because the component has a very large prop surface, version 2 replaced Moment with date-fns, version 9 uses date-fns 4, and deprecated props such as `calendarIconClassname` remain visible.
Docs4/5The README covers installation, mandatory CSS, basic control, selection versus change events, time selection, locale registration, React compatibility, browser expectations, and full keyboard commands. The demo site and prop table cover a wide feature surface, while separate import and timezone guides address common failures. Some text conflicts with newer features: one section says timezone conversion is not built in even though version 9 documents a `timeZone` prop, so types and current examples must sometimes arbitrate.
Maintenance4/5Version 9.1.0 was published in December 2025, the repository was pushed in April 2026, and it is not archived. The project supports current React 19, date-fns 4, exports types, and maintains extensive tests and documentation. GitHub reports 91 open issues and pull requests, which shows both continuing use and a meaningful support queue; with a decade-old component and a broad prop matrix, regressions and slow issue resolution remain plausible.
Ecosystem5/5The npm last-week endpoint recorded 4,934,297 downloads and the repository has 8,382 stars. It works across five React major lines, uses native Date values, integrates date-fns locales, offers date-fns-tz-backed IANA timezone display, and has years of examples for common forms. Ecosystem fit is strongest in standalone React applications; teams centered on Material UI, a headless design system, or string-based date models may spend more effort adapting it than choosing a closer component.

Use it if

  • You want a mature drop-in React calendar with single-date, range, multiple-date, and date-time modes
  • Your application already represents values as JavaScript Date objects and uses date-fns conventions
  • You need keyboard navigation, locale registration, constrained dates, custom inputs, portals, or inline calendars from one component
  • You prefer adapting supplied CSS and props over assembling a calendar from headless primitives
Skip it if

Setup reality

Install with `npm install react-datepicker`, make sure compatible `react` and `react-dom` peers are already present, and import `react-datepicker/dist/react-datepicker.css` once in the client bundle unless you are replacing every style yourself. Version 9.1.0 supports React 16.9 through 19, depends on date-fns 4.1, declares date-fns-tz 3 as a peer, and ships CommonJS, ESM, and TypeScript declarations. The component is controlled: keep a `Date | null` in state, pass it as `selected`, and update it from `onChange`. Range and multiple selection deliberately change the callback type, so TypeScript code must model `[Date | null, Date | null]` or `Date[] | null` rather than reuse a single-date handler. The biggest first-run mistake is forgetting the CSS, which leaves a functional but effectively unstyled calendar. The second is forgetting that a JavaScript Date is a timestamp interpreted in a timezone, not a date-only value. A birthday selected as local midnight can become the previous UTC date after `toISOString()`. Format date-only values from local year, month, and day, or use date-fns `format(date, 'yyyy-MM-dd')`; reserve ISO timestamps for actual moments. Version 9 adds a `timeZone` prop for IANA zones, but the repository guide says it needs date-fns-tz and falls back to local-time behavior with a development warning when that package is absent. Keep `minDate`, `maxDate`, excluded dates, and selected values consistent with the same timezone model. Non-English display is not automatic: import a locale object from date-fns, call `registerLocale`, then pass its registered name or set a global default. Popovers can be clipped by overflow containers; `withPortal`, `portalId`, and `portalHost` exist, but moving DOM also affects stacking, focus, and test selectors. Custom inputs must forward the ref and received input props or opening and keyboard focus break. Time selection defaults to 30-minute intervals. Date disabling functions run across rendered days, so expensive business rules should be memoized or converted into interval and date props. The README documents arrow, Page Up, Home, End, Enter, Escape, and Tab behavior, but built-in keyboard support does not replace application-level accessibility testing, clear labels, validation messages, and touch testing.

Patterns

Build a controlled single-date pickerselect-single-date

import { useState } from 'react';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';

export function DueDate() {
  const [date, setDate] = useState<Date | null>(null);
  return <DatePicker selected={date} onChange={setDate} placeholderText="Choose a date" />;
}

Import the stylesheet once in the application and keep null in the state type so clearing is valid.

Select a start and end dateselect-date-range

const [range, setRange] = useState<[Date | null, Date | null]>([null, null]);
const [startDate, endDate] = range;

<DatePicker
  selectsRange
  startDate={startDate}
  endDate={endDate}
  onChange={(next) => setRange(next)}
  isClearable
/>

With `selectsRange`, onChange receives a tuple rather than the single Date used by the default mode.

Select several independent datesselect-multiple-dates

const [dates, setDates] = useState<Date[] | null>([]);

<DatePicker
  selectsMultiple
  selectedDates={dates ?? []}
  onChange={(next) => setDates(next)}
/>

Multiple selection has its own Date-array callback type; do not combine it with `selectsRange`.

Select a date and timeadd-time-picker

<DatePicker
  selected={appointment}
  onChange={setAppointment}
  showTimeSelect
  timeIntervals={15}
  dateFormat="Pp"
/>

The default time interval is 30 minutes. The resulting Date represents a moment, so ISO serialization is appropriate only after confirming timezone intent.

Register and use a date-fns localeregister-locale

import DatePicker, { registerLocale } from 'react-datepicker';
import { es } from 'date-fns/locale/es';

registerLocale('es', es);

<DatePicker selected={date} onChange={setDate} locale="es" />

Registration is explicit; passing an unregistered name does not load locale data automatically.

Display and select in an IANA timezoneset-timezone

<DatePicker
  selected={instant}
  onChange={setInstant}
  showTimeSelect
  timeZone="America/New_York"
  dateFormat="MMMM d, yyyy h:mm aa"
/>

Install a compatible date-fns-tz 3.x peer. Without it, development logs a warning and the picker falls back to local timezone behavior.

Serialize a date without a timezone shiftserialize-date-only

import { format } from 'date-fns';

function handleBirthday(date: Date | null) {
  const value = date ? format(date, 'yyyy-MM-dd') : null;
  saveBirthday(value);
}

<DatePicker selected={birthday} onChange={handleBirthday} />

Do not use `toISOString().slice(0, 10)` for a local calendar date; UTC conversion can move it to the previous or next day.

Restrict selectable dateslimit-date-range

import { addMonths, startOfToday } from 'date-fns';

const today = startOfToday();
<DatePicker
  selected={date}
  onChange={setDate}
  minDate={today}
  maxDate={addMonths(today, 6)}
/>

Provide selected, minimum, and maximum values under the same timezone assumptions, particularly when also using `timeZone`.

Disable weekends and known blackout datesdisable-business-days

import { isWeekend, isSameDay } from 'date-fns';

const blackout = [new Date(2026, 11, 25)];
<DatePicker
  selected={date}
  onChange={setDate}
  filterDate={(day) => !isWeekend(day) && !blackout.some((x) => isSameDay(x, day))}
/>

filterDate runs for rendered calendar days; memoize large rule sets or use excludeDates and interval props to avoid repeated expensive work.

Render the calendar without an input popoverrender-inline-calendar

<DatePicker
  inline
  selected={date}
  onChange={setDate}
  onClickOutside={() => setPanelOpen(false)}
/>

The README specifically points to `onClickOutside` for closing an inline picker because there is no input popover to manage it.

Supply a custom input that forwards its refuse-custom-input

const DateButton = forwardRef<HTMLButtonElement, React.ComponentProps<'button'>>(
  ({ value, onClick, ...props }: any, ref) => (
    <button type="button" ref={ref} onClick={onClick} {...props}>{value || 'Choose date'}</button>
  )
);

<DatePicker selected={date} onChange={setDate} customInput={<DateButton />} />

Forward the ref, value, click handler, and accessibility props injected by DatePicker or focus and keyboard behavior can fail.

Move the calendar out of a clipped containerrender-in-portal

<DatePicker
  selected={date}
  onChange={setDate}
  withPortal
  portalId="date-picker-portal"
/>

A portal helps with overflow clipping, but verify focus order, stacking context, modal interaction, and test selectors after moving the DOM.

Alternatives

PackageRegistryPick it when
react-day-pickernpmChoose it when a design system needs a more headless calendar surface and can supply its own input and popover behavior
@mui/x-date-pickersnpmChoose it when the application already uses Material UI and date fields must share its theme, adapters, and form conventions
flatpickrnpmChoose it for framework-neutral pages or mixed stacks where a React-specific controlled component is unnecessary