React Native Calendar Components 🗓️ 📆





GitHub Stars



Last Commit

5d ago








Type Definitions





Average Rating

Read All Reviews

Top Feedback

10Highly Customizable
7Great Documentation
5Easy to Use
4Poor Documentation
2Bleeding Edge


React Native Calendars 🗓️ 📆

Version Build Status

This module includes various customizable React-Native calendar components.

The package is both Android and iOS compatible.

Try it out

You can run example module by performing these steps:

$ git clone
$ npm install
$ react-native run-ios

You can check example screens source code in example module screens

This project is compatible with Expo/CRNA (without ejecting), and the examples have been published on Expo


$ npm install --save react-native-calendars

The solution is implemented in JavaScript so no native module linking is required.


import {Calendar, CalendarList, Agenda} from 'react-native-calendars';

All parameters for components are optional. By default the month of current local date will be displayed.

Event handler callbacks are called with calendar objects like this:

  day: 1,      // day of month (1-31)
  month: 1,    // month of year (1-12)
  year: 2017,  // year
  timestamp,   // UTC timestamp representing 00:00 AM of this date
  dateString: '2016-05-13' // date formatted as 'YYYY-MM-DD' string

Parameters that require date types accept YYYY-MM-DD formatted date-strings, JavaScript date objects, calendar objects and UTC timestamps.

Calendars can be localized by adding custom locales to LocaleConfig object:

import {LocaleConfig} from 'react-native-calendars';

LocaleConfig.locales['fr'] = {
  monthNames: ['Janvier','Février','Mars','Avril','Mai','Juin','Juillet','Août','Septembre','Octobre','Novembre','Décembre'],
  monthNamesShort: ['Janv.','Févr.','Mars','Avril','Mai','Juin','Juil.','Août','Sept.','Oct.','Nov.','Déc.'],
  dayNames: ['Dimanche','Lundi','Mardi','Mercredi','Jeudi','Vendredi','Samedi'],
  dayNamesShort: ['Dim.','Lun.','Mar.','Mer.','Jeu.','Ven.','Sam.'],
  today: 'Aujourd\'hui'
LocaleConfig.defaultLocale = 'fr';


Basic parameters

  // Initially visible month. Default = Date()
  // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
  // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
  // Handler which gets executed on day press. Default = undefined
  onDayPress={(day) => {console.log('selected day', day)}}
  // Handler which gets executed on day long press. Default = undefined
  onDayLongPress={(day) => {console.log('selected day', day)}}
  // Month format in calendar title. Formatting values:
  monthFormat={'yyyy MM'}
  // Handler which gets executed when visible month changes in calendar. Default = undefined
  onMonthChange={(month) => {console.log('month changed', month)}}
  // Hide month navigation arrows. Default = false
  // Replace default arrows with custom ones (direction can be 'left' or 'right')
  renderArrow={(direction) => (<Arrow/>)}
  // Do not show days of other months in month page. Default = false
  // If hideArrows = false and hideExtraDays = false do not switch month when tapping on greyed out
  // day from another month that is visible in calendar page. Default = false
  // If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday
  // Hide day names. Default = false
  // Show week numbers to the left. Default = false
  // Handler which gets executed when press arrow icon left. It receive a callback can go back month
  onPressArrowLeft={subtractMonth => subtractMonth()}
  // Handler which gets executed when press arrow icon right. It receive a callback can go next month
  onPressArrowRight={addMonth => addMonth()}
  // Disable left arrow. Default = false
  // Disable right arrow. Default = false
  // Disable all touch events for disabled days. can be override with disableTouchEvent in markedDates
  // Replace default month and year title with custom one. the function receive a date as parameter
  renderHeader={(date) => {/*Return JSX*/}}
  // Enable the option to swipe between months. Default = false

Date marking

Disclaimer: Make sure that markedDates param is immutable. If you change markedDates object content but the reference to it does not change calendar update will not be triggered.

Dot marking

  // Collection of dates that have to be marked. Default = {}
    '2012-05-16': {selected: true, marked: true, selectedColor: 'blue'},
    '2012-05-17': {marked: true},
    '2012-05-18': {marked: true, dotColor: 'red', activeOpacity: 0},
    '2012-05-19': {disabled: true, disableTouchEvent: true}

You can customize a dot color for each day independently.

Multi-Dot marking

Use markingType={'multi-dot'} if you want to display more than one dot. Both the <Calendar/> and <CalendarList/> support multiple dots by using dots array in markedDates prop. The property color is mandatory while key and selectedColor are optional. If key is omitted then the array index is used as key. If selectedColor is omitted then color will be used for selected dates.

const vacation = {key: 'vacation', color: 'red', selectedDotColor: 'blue'};
const massage = {key: 'massage', color: 'blue', selectedDotColor: 'blue'};
const workout = {key: 'workout', color: 'green'};

    '2017-10-25': {dots: [vacation, massage, workout], selected: true, selectedColor: 'red'},
    '2017-10-26': {dots: [massage, workout], disabled: true}

Period marking

    '2012-05-20': {textColor: 'green'},
    '2012-05-22': {startingDay: true, color: 'green'},
    '2012-05-23': {selected: true, endingDay: true, color: 'green', textColor: 'gray'},
    '2012-05-04': {disabled: true, startingDay: true, color: 'green', endingDay: true}

Multi-period marking

CAUTION: This marking is only fully supported by the <Calendar/> component because it expands its height. Usage with <CalendarList/> might lead to overflow issues.

    '2017-12-14': {
      periods: [
        {startingDay: false, endingDay: true, color: '#5f9ea0'},
        {startingDay: false, endingDay: true, color: '#ffa500'},
        {startingDay: true, endingDay: false, color: '#f0e68c'}
    '2017-12-15': {
      periods: [
        {startingDay: true, endingDay: false, color: '#ffa500'},
        {color: 'transparent'},
        {startingDay: false, endingDay: false, color: '#f0e68c'}

Custom marking allows you to customize each marker with custom styles.

    '2018-03-28': {
      customStyles: {
        container: {
          backgroundColor: 'green'
        text: {
          color: 'black',
          fontWeight: 'bold'
    '2018-03-29': {
      customStyles: {
        container: {
          backgroundColor: 'white',
          elevation: 2
        text: {
          color: 'blue'

NEW! While we still don't support multi marking type, we add the possibility to combine between period and simple.

    '2012-05-15': {marked: true, dotColor: '#50cebb'},
    '2012-05-16': {marked: true, dotColor: '#50cebb'},
    '2012-05-21': {startingDay: true, color: '#50cebb', textColor: 'white'},
    '2012-05-22': {color: '#70d7c7', textColor: 'white'},
    '2012-05-23': {color: '#70d7c7', textColor: 'white', marked: true, dotColor: 'white'},
    '2012-05-24': {color: '#70d7c7', textColor: 'white'},
    '2012-05-25': {endingDay: true, color: '#50cebb', textColor: 'white'}

Keep in mind that different marking types are not compatible. You can use just one marking style for a calendar.

Displaying data loading indicator

The loading indicator next to the month name will be displayed if <Calendar/> has displayLoadingIndicator prop and the markedDates collection does not have a value for every day of the month in question. When you load data for days, just set [] or special marking value to all days in markedDates collection.

Customizing look & feel

  // Specify style for calendar container element. Default = {}
    borderWidth: 1,
    borderColor: 'gray',
    height: 350
  // Specify theme properties to override specific styles for calendar parts. Default = {}
    backgroundColor: '#ffffff',
    calendarBackground: '#ffffff',
    textSectionTitleColor: '#b6c1cd',
    textSectionTitleDisabledColor: '#d9e1e8',
    selectedDayBackgroundColor: '#00adf5',
    selectedDayTextColor: '#ffffff',
    todayTextColor: '#00adf5',
    dayTextColor: '#2d4150',
    textDisabledColor: '#d9e1e8',
    dotColor: '#00adf5',
    selectedDotColor: '#ffffff',
    arrowColor: 'orange',
    disabledArrowColor: '#d9e1e8',
    monthTextColor: 'blue',
    indicatorColor: 'blue',
    textDayFontFamily: 'monospace',
    textMonthFontFamily: 'monospace',
    textDayHeaderFontFamily: 'monospace',
    textDayFontWeight: '300',
    textMonthFontWeight: 'bold',
    textDayHeaderFontWeight: '300',
    textDayFontSize: 16,
    textMonthFontSize: 16,
    textDayHeaderFontSize: 16

Customize days titles with disabled styling

    textSectionTitleDisabledColor: '#d9e1e8'
    ...this.getDisabledDates('2012-05-01', '2012-05-30', [0, 6])
  disabledDaysIndexes={[0, 6]}

Advanced styling

If you want to have complete control over the calendar styles you can do it by overriding default style.ts files. For example, if you want to override <CalendarHeader/> style first you have to find stylesheet id for this file:

In this case it is stylesheet.calendar.header. Next you can add overriding stylesheet to your theme with this id.

  arrowColor: 'white',
  'stylesheet.calendar.header': {
    week: {
      marginTop: 5,
      flexDirection: 'row',
      justifyContent: 'space-between'

Individual day header styling

Using the above advanced styling, it is possible to set styles independently for each day's header. If we wanted to make the header for Sunday red, and Saturday blue, we could write something like the following:

  'stylesheet.calendar.header': {
    dayTextAtIndex0: {
      color: 'red'
    dayTextAtIndex6: {
      color: 'blue'

Disclaimer: Issues that arise because something breaks after using stylesheet override will not be supported. Use this option at your own risk.

Overriding day component

If you need custom functionality not supported by current day component implementations you can pass your own custom day component to the calendar.

  style={[styles.calendar, {height: 300}]}
  dayComponent={({date, state}) => {
    return (
        <Text style={{textAlign: 'center', color: state === 'disabled' ? 'gray' : 'black'}}>

The dayComponent prop has to receive a RN component or a function that receive props. The dayComponent will receive such props:

  • state - disabled if the day should be disabled (this is decided by base calendar component).
  • marking - markedDates value for this day.
  • date - the date object representing this day.

Tip: Don't forget to implement shouldComponentUpdate() for your custom day component to make the calendar perform better

If you implement an awesome day component please make a PR so that other people could use it :)


<CalendarList/> is scrollable semi-infinite calendar composed of <Calendar/> components. Currently it is possible to scroll 4 years back and 4 years to the future. All parameters that are available for <Calendar/> are also available for this component. There are also some additional params that can be used:

  // Callback which gets executed when visible months change in scroll view. Default = undefined
  onVisibleMonthsChange={(months) => {console.log('now these months are visible', months);}}
  // Max amount of months allowed to scroll to the past. Default = 50
  // Max amount of months allowed to scroll to the future. Default = 50
  // Enable or disable scrolling of calendar list
  // Enable or disable vertical scroll indicator. Default = false

Horizontal CalendarList

You can also make the CalendarList scroll horizontally. To do that you need to pass specific props to the CalendarList:

  // Enable horizontal scrolling, default = false
  // Enable paging on horizontal, default = false
  // Set custom calendarWidth.


An advanced Agenda component that can display interactive listings for calendar day items.

  // The list of items that have to be displayed in agenda. If you want to render item as empty date
  // the value of date key has to be an empty array []. If there exists no value for date key it is
  // considered that the date in question is not yet loaded
    '2012-05-22': [{name: 'item 1 - any js object'}],
    '2012-05-23': [{name: 'item 2 - any js object', height: 80}],
    '2012-05-24': [],
    '2012-05-25': [{name: 'item 3 - any js object'}, {name: 'any js object'}]
  // Callback that gets called when items for a certain month should be loaded (month became visible)
  loadItemsForMonth={(month) => {console.log('trigger items loading')}}
  // Callback that fires when the calendar is opened or closed
  onCalendarToggled={(calendarOpened) => {console.log(calendarOpened)}}
  // Callback that gets called on day press
  onDayPress={(day) => {console.log('day pressed')}}
  // Callback that gets called when day changes while scrolling agenda list
  onDayChange={(day) => {console.log('day changed')}}
  // Initially selected day
  // Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
  // Maximum date that can be selected, dates after maxDate will be grayed out. Default = undefined
  // Max amount of months allowed to scroll to the past. Default = 50
  // Max amount of months allowed to scroll to the future. Default = 50
  // Specify how each item should be rendered in agenda
  renderItem={(item, firstItemInDay) => {return (<View />);}}
  // Specify how each date should be rendered. day can be undefined if the item is not first in that day
  renderDay={(day, item) => {return (<View />);}}
  // Specify how empty date content with no items should be rendered
  renderEmptyDate={() => {return (<View />);}}
  // Specify how agenda knob should look like
  renderKnob={() => {return (<View />);}}
  // Specify what should be rendered instead of ActivityIndicator
  renderEmptyData = {() => {return (<View />);}}
  // Specify your item comparison function for increased performance
  rowHasChanged={(r1, r2) => {return r1.text !== r2.text}}
  // Hide knob button. Default = false
  // When `true` and `hideKnob` prop is `false`, the knob will always be visible and the user will be able to drag the knob up and close the calendar. Default = false
  // By default, agenda dates are marked if they have at least one item, but you can override this if needed
    '2012-05-16': {selected: true, marked: true},
    '2012-05-17': {marked: true},
    '2012-05-18': {disabled: true}
  // If disabledByDefault={true} dates flagged as not disabled will be enabled. Default = false
  // If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly
  onRefresh={() => console.log('refreshing...')}
  // Set this true while waiting for new data from a refresh
  // Add a custom RefreshControl component, used to provide pull-to-refresh functionality for the ScrollView
  // Agenda theme
    agendaDayTextColor: 'yellow',
    agendaDayNumColor: 'green',
    agendaTodayColor: 'red',
    agendaKnobColor: 'blue'
  // Agenda container style


See also the list of contributors who participated in this project.


Pull requests are most welcome! Please npm run test and npm run lint before push. Don't forget to add a title and a description that explain the issue you're trying to solve and your suggested solution. Screenshots and gifs are VERY helpful. Please do NOT format the files as we are trying to keep a unified syntax and the reviewing process fast and simple.

Rate & Review

Great Documentation7
Easy to Use5
Highly Customizable10
Bleeding Edge2
Responsive Maintainers1
Poor Documentation4
Hard to Use0
Unwelcoming Community0
Ranseth4 Ratings1 Review
Raising skills
9 months ago
Highly Customizable
Poor Documentation
Bleeding Edge

I tried this library because we needed a very flexible calendar for our client. I was able to create pretty much any style of calendar after spending days playing with it, so although I'm not happy with it (for reasons I'm about to explain) I'm very amazed by their work. For us, the last 300 versions don't work because the module targeting is broken and the app can't load because of this. I tried to revert back to the last version in which this bug doesn't occur and my Agenda tag isn't working anymore (whether it's the one I used or a fresh one). There is an impressing number of issues with RNCalendars, which I get, because this is open source. But we barely got any changelogs for something that's supposedly been updated hundreds and hundreds of time, without resolving any issues that people still have, are still talking about because they're still in trouble. No one seems to take care of anything (except like once a year), which is frustrating, because the issues are closely related to the library, no forums on any website on the Internet can help with this. I don't get why I am the only one giving such a low rating, which I don't like to do. But we're at a point where we're going to need to change libraries and choose another calendar altogether.

v-5030 Ratings44 Reviews
5 months ago
Easy to Use
Great Documentation
Highly Customizable

Scheduling and maintaing routine is very important part of an application and this package helps in the same by providing the calender features like scheduling a task or using dates and months for something. One of the most important package for this purpose. Really Loved it.

Deepak KhiwaniChandigarh47 Ratings57 Reviews
9 months ago
Great Documentation
Highly Customizable
Easy to Use

A beautifully written and highly customised calendar package, I used the same in one of my professional booking applications with tons of dependency on calendar. Wix-calendar has everything we needed - Awesome documentation - Rich Features - Highly Customisation on UI

Prashant Singh ThakurRanchi15 Ratings15 Reviews
5 months ago

This is a very good package if we want to implement date and calender realted like week, day, month in our react native application. Its a very usefull and important package . A huge shout out to the developers and the community.

Luís MestrePortugal43 Ratings31 Reviews
10 months ago
Great Documentation
Highly Customizable
Responsive Maintainers

In the beginning it's a bit overwhelming but the component gives out all the basic and complex functionalities that you would need in a Calendar componente. It's very well documented and it can be very customizable