React Native Date Picker Libraries Compared: Native Pickers, Ranges and Calendars (2026)

React Native date picker options compared for 2026: community datetimepicker v9, Expo UI, react-native-date-picker, range calendars and the off-by-one bug.

React Native Date Picker Libraries Compared: Native Pickers, Ranges and Calendars (2026)

Date pickers are the form control that looks done after a day and keeps coming back as tickets. It works on your iPhone, but on a Samsung in Berlin the week starts on the wrong day. The birthday field defaults to today, so users scroll back forty years one month at a time. The hotel booking needs a range, and the native picker cannot do ranges. Then the date the user picked arrives on the server one day earlier, because someone called toISOString() on midnight local time.

This is a practical comparison of the React Native date picker options that are worth using in late 2026, checked on npm on October 12. It covers code for the ones I would ship, the time zone bug everyone hits, and a decision table at the end.

Native picker or calendar component?

Like dropdowns, date pickers come in two kinds, and deciding which one you need first saves you from most of the bad picks:

  • A native picker uses the OS control: UIDatePicker or the SwiftUI DatePicker on iOS, a Material dialog on Android. You pick one date, one time, or both. It is accessible, localized and familiar, and you get almost no control over how it looks.
  • A calendar component is drawn in JavaScript: a month grid that you style yourself. It is the only way to get date ranges, multiple dates, marked or disabled days, and a design that looks the same on both platforms.

If the requirement says “check-in and check-out” or “show which days have bookings”, skip straight to the calendar section. A native picker cannot do it.

The options at a glance

Library Kind Version (Oct 2026) Last publish Weekly downloads
@react-native-community/datetimepicker Native 9.2.1 Sep 2026 ~2.76M
@expo/ui (community/datetime-picker) Native (SwiftUI / Compose) 57.0.22 Oct 2026 ~5.2M (whole package)
react-native-date-picker Native-style wheel 5.0.13 Jun 2025 ~298K
react-native-modal-datetime-picker Modal wrapper over community 18.0.0 Aug 2024 ~852K
react-native-ui-datepicker JS calendar 3.3.0 May 2026 ~91K
react-native-paper-dates JS calendar (Material) 0.24.1 Oct 2026 ~49K
react-native-calendars JS calendar views 1.1314.0 Jan 2026 ~500K

@react-native-community/datetimepicker: the default

This is the package that used to be core’s DatePickerIOS and TimePickerAndroid. It is the one Expo bundles, and it is the one most other libraries wrap. Version 9 changed two things you should know about if you are coming from old tutorials. 9.0.0 (March 2026) removed the deprecated Android positiveButtonLabel, negativeButtonLabel and neutralButtonLabel props in favour of positiveButton and friends. 9.1.0 introduced separate listeners, so onChange is now deprecated in favour of onValueChange, onDismiss and onNeutralButtonPress. The old single onChange that fired with event.type === 'dismissed' still works. It just isn’t how you should write new code.

npx expo install @react-native-community/datetimepicker
# bare React Native
npm install @react-native-community/datetimepicker

Android: use the imperative API

The library’s own README recommends the imperative API on Android, because the Android picker is a dialog and not a view:

import { useState } from 'react';
import { Button, Text, View } from 'react-native';
import { DateTimePickerAndroid } from '@react-native-community/datetimepicker';

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

  const open = () =>
    DateTimePickerAndroid.open({
      value: date,
      mode: 'date',
      design: 'material',
      minimumDate: new Date(),
      onValueChange: (_event, selected) => setDate(selected),
    });

  return (
    <View>
      <Button title="Pick a due date" onPress={open} />
      <Text>{date.toLocaleDateString()}</Text>
    </View>
  );
}

design: 'material' gives you the Material 3 picker instead of the older default dialog, and unlocks title, fullscreen and initialInputMode. It needs your Android app theme to inherit from Theme.Material3.DayNight.NoActionBar in styles.xml, otherwise it crashes on open. That is the first thing to check when it “works in the example app”.

iOS and cross-platform: the component

import DateTimePicker from '@react-native-community/datetimepicker';

{show && (
  <DateTimePicker
    value={date}
    mode="date"
    display="inline"
    minimumDate={new Date(1920, 0, 1)}
    maximumDate={new Date()}
    onValueChange={(_event, selected) => setDate(selected)}
    onDismiss={() => setShow(false)}
  />
)}

On iOS, display controls the look: 'compact' (a small button that expands), 'inline' (the full calendar), or 'spinner' (the classic wheel). For a birthday field the spinner is still the kindest option, because scrolling a year wheel beats paging back through 480 months. mode="datetime" and mode="countdown" exist on iOS only. On Android, pick a date and then a time in two dialogs.

Expo UI’s drop-in DateTimePicker

On Expo SDK 57, @expo/ui ships a DateTimePicker whose API matches the community package. It uses SwiftUI’s DatePicker on iOS and Jetpack Compose on Android, which means Material 3 by default without the theme change. Per the Expo docs, migrating means changing one import:

import DateTimePicker from '@expo/ui/community/datetime-picker';

{show && (
  <DateTimePicker
    value={date}
    mode="date"
    presentation="dialog"
    onValueChange={(_event, selected) => {
      setShow(false);
      setDate(selected);
    }}
    onDismiss={() => setShow(false)}
  />
)}

The differences are listed plainly in the docs. There is no DateTimePickerAndroid.open(); you render the component with presentation="dialog" on Android (iOS ignores the prop and renders inline). countdown mode, minuteInterval, textColor, firstDayOfWeek, the neutral button, fullscreen, title and startOnYearSelection are not supported. Time zones take an IANA timeZoneName rather than timeZoneOffsetInMinutes. If you don’t rely on any of those, on Expo this is the version I would start with. Our dropdown comparison reached the same conclusion about Expo UI’s Picker: the SDK is gradually turning community shims into native components.

react-native-date-picker: the wheel, everywhere

Henning Hall’s react-native-date-picker draws an iOS-style wheel on both platforms, inline or in its own modal, with date, time and datetime modes. That makes it the usual answer when a designer wants the same picker on Android and iOS:

import { useState } from 'react';
import { Button } from 'react-native';
import DatePicker from 'react-native-date-picker';

export function ReminderField() {
  const [date, setDate] = useState(new Date());
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button title="Set reminder" onPress={() => setOpen(true)} />
      <DatePicker
        modal
        open={open}
        date={date}
        mode="datetime"
        minuteInterval={15}
        theme="auto"
        onConfirm={(value) => {
          setOpen(false);
          setDate(value);
        }}
        onCancel={() => setOpen(false)}
      />
    </>
  );
}

Two caveats. It has custom native code, so it works in Expo development builds but not in Expo Go (no config plugin needed). And the last npm release, 5.0.13, came out in June 2025. It still works in plenty of apps, but sixteen months without a publish is a risk for a native module, given how often React Native changes the native side. Pin the version and test it on each RN upgrade.

react-native-modal-datetime-picker: check whether you still need it

This wrapper puts the community picker inside a modal with confirm and cancel buttons, giving you an isVisible, onConfirm, onCancel API on both platforms. It still has 850K weekly downloads, mostly from apps that adopted it years ago. Its last release was 18.0.0 in August 2024. Today the community picker’s own display="inline" on iOS, the Android dialog, or the Expo UI component cover the same ground with one less dependency. I would not add it to a new project. If you already use it, there is no hurry to remove it, but don’t build anything new on it.

Calendars: ranges, multiple dates and full styling

react-native-ui-datepicker

A pure JavaScript calendar with single, range and multiple modes, an optional time picker, Gregorian and Jalali calendars, and styling through either a styles object or Tailwind-style classNames (handy with NativeWind). No native code, so it runs in Expo Go and on web:

import { useState } from 'react';
import DateTimePicker, { DateType, useDefaultStyles } from 'react-native-ui-datepicker';

export function StayDates() {
  const defaultStyles = useDefaultStyles();
  const [range, setRange] = useState<{ startDate: DateType; endDate: DateType }>({
    startDate: undefined,
    endDate: undefined,
  });

  return (
    <DateTimePicker
      mode="range"
      startDate={range.startDate}
      endDate={range.endDate}
      minDate={new Date()}
      onChange={({ startDate, endDate }) => setRange({ startDate, endDate })}
      styles={defaultStyles}
    />
  );
}

It renders inline, so for a pop-up put it inside a sheet. Our bottom sheet guide covers the options, and a plain modal works too.

react-native-paper-dates

If your app already uses React Native Paper, this is the Material Design match: single, range, multiple and input date pickers, plus a time picker with clock face or keyboard input, all in modals styled by your Paper theme. Formatting uses the native Intl APIs, and translations are built in. It is actively maintained (0.24.1 shipped October 10):

import { DatePickerModal } from 'react-native-paper-dates';

<DatePickerModal
  locale="en"
  mode="range"
  visible={open}
  onDismiss={() => setOpen(false)}
  startDate={range.startDate}
  endDate={range.endDate}
  onConfirm={({ startDate, endDate }) => {
    setOpen(false);
    setRange({ startDate, endDate });
  }}
/>

react-native-calendars

Wix’s react-native-calendars is less a picker than a calendar display kit: Calendar, CalendarList, Agenda, ExpandableCalendar and markedDates for dots, periods and disabled days. Use it when the calendar is the screen (bookings, schedules, habit trackers) rather than a form field. For a simple range input it is more than you need.

The bug everyone ships: dates off by one

Every picker above gives you a JavaScript Date, which is a point in time, not a calendar day. Pick “March 3” at local midnight in Berlin, call toISOString(), and you send 2027-03-02T23:00:00.000Z. The server stores March 2, and a user files a bug report. The fix is to decide what you are storing:

  • A calendar day (birthday, due date, check-in): send YYYY-MM-DD built from the local parts, and never convert to UTC.
  • A moment (appointment, reminder): send the full ISO timestamp and the user’s IANA time zone, so you can render it correctly for someone in another zone.
// a calendar day, no UTC conversion
const toDay = (d: Date) =>
  `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;

// a moment, plus the zone it was chosen in
const payload = {
  at: date.toISOString(),
  timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,
};

Hermes ships full Intl support now, so toLocaleDateString and Intl.DateTimeFormat work on both platforms without polyfills. For display, use them. For arithmetic across time zones, a library like date-fns with its tz helpers or Temporal (once it lands in your runtime) beats hand-rolled maths.

Four smaller things worth getting right

  1. Start where the user is likely to be. A birth date picker should open around 30 years ago with maximumDate set to today. A booking picker should have minimumDate set to today.
  2. Locale on iOS comes from the project. The community picker follows the languages declared in your Xcode project. Its locale prop is iOS only and the README itself discourages it outside the spinner display.
  3. Dark mode. On iOS, themeVariant forces light or dark if your app does not follow the system. react-native-date-picker has theme. Calendars follow whatever styles you pass.
  4. Test the dismissal path. On Android, a user tapping outside the dialog fires onDismiss, not onValueChange. Code that only closes the picker in the value handler leaves your “show” state stuck at true.

Which one should you use?

You need Use
One date or time, native look, any setup @react-native-community/datetimepicker
One date or time on Expo, Material 3 and SwiftUI by default @expo/ui/community/datetime-picker
The same wheel on iOS and Android react-native-date-picker (pin it)
Date range or multiple dates, custom styling react-native-ui-datepicker
Already on React Native Paper react-native-paper-dates
A calendar screen with marked days and agenda react-native-calendars

My default for a new app: the native picker (Expo UI’s drop-in on Expo, the community package otherwise) for every single-date field, and react-native-ui-datepicker inside a sheet the moment someone says “range”. If you only remember one thing from this post, make it the YYYY-MM-DD helper. It prevents more bug reports than the choice of library does. If you are still deciding on Expo itself, our Expo explainer covers what you gain and what you give up.

FAQ

Does React Native have a built-in date picker?

No. The old core DatePickerIOS and DatePickerAndroid were removed. The maintained replacement is @react-native-community/datetimepicker, and Expo also offers a native one in @expo/ui.

What is the best date picker for React Native?

For a single date or time, @react-native-community/datetimepicker, or Expo UI’s DateTimePicker on Expo. For date ranges, use a calendar component like react-native-ui-datepicker or react-native-paper-dates.

How do I pick a date range in React Native?

Native pickers only select one value. Use react-native-ui-datepicker with mode="range", or DatePickerModal from react-native-paper-dates with mode="range".

Why is my selected date one day off?

You converted a local midnight Date to UTC with toISOString(). For calendar days, send a YYYY-MM-DD string built from the local year, month and day instead.

Is onChange deprecated in @react-native-community/datetimepicker?

Yes, since 9.1.0. Use onValueChange for a selected value, onDismiss for a cancelled picker, and onNeutralButtonPress for the Android neutral button. onChange still works for now.

Does react-native-date-picker work with Expo?

Yes, in development builds. It does not work in Expo Go because it contains custom native code.

Leave a Reply 0

Your email address will not be published. Required fields are marked *