Create a Custom Date Picker With React and TypeScript Using Day.js
Why not? — As it turns out, it’s pretty easy.

In this article, we are going to create a simple react date picker from scratch. As our dates manipulation helper, we will use a library called “Day.js”. Please, don’t pay too much attention to styling. Our goal is to create a basic component, which you can modify however you want to.
So what is Day.js?
Day.js is a minimalist JavaScript library that parses, validates, manipulates, and displays dates. It’s really lightweight (only 2 kB!) and exposes quite simple API.
Why we can’t just use some library such as “react-datepicker”?
First of all, this article won’t be interesting at all, If I just show you how to install a library). In addition, I think there are some cases, which can be easily implemented without any 3rd party packages (which are usually hard to customize).
What is our final result?
What functionality do we have here?
- Calendar displaying dates of a current month, with names of the weekdays. Also, it can be flipped forward or backward.
- Functionality for selecting a specific date. By default, present-day will be selected.
Let’s get started!
Dependencies.
First of all, we need to install our dependencies. As I mentioned before, we will use Day.js
and the library called “clsx”, which allows us to easily combine class names (It’s totally optional, I just prefer to use it)

App component.
Everything is quite simple. We will create a frame for our app and add a state for our calendar. Notice, that we invoke dayjs
as our initial value here. It returns us the instance of the dayjs
containing current date info. Also, we format the selected date and place it in the heading. Don’t worry about the import of DatePicker
, we’ll implement it a little bit below.
Datepicker component
Next, we should create our datepicker
root component. I’ll divide it into two separate parts.
The first part is DatePickerSelector
, this is the place that contains our flip logic.
The second part DatePickerCalendar
is responsible for displaying the calendar and selecting a specific date.
Our component receives two props:
selectedDate
is thedayjs
instance, representing the chosen date.onChange
is the handler that is called on clicking the date cell and gets the new date as its first argument.
Also, notice that we have another local state called shownDate
. It will be responsible for displaying the proper months and years in our calendar.
DatePickerSelector component
As I mentioned before, this component will contain our flip logic. Nothing special here, we just handle our click events and increase/decrease our shownDate
by month.
changeDateMonth
is a function that decides whether we need to add or subtract a year as well.
DatePickerCalendar component
In order to implement this part, we need to create some helpers ahead. Firstly, let’s create an interface representing our single cell in the calendar, it will be called ICalendarCell
. Additionally, we will write two more functions:
getCalendarCells
will get the current shown date and return an array of cells. Also, it will add days from the previous and next month to fill our calendar rows fully.getCalendarRows
will return an array of rows for our calendar.
After this, we can move to our UI.
Everything is pretty straightforward here:
handleSelectDate
is a select date handler that takes advantage of closure and invokesonChange
the needed date.rows
is a memoized return value of ourgetCalendarRows
. So it recalculates only when the shown date changes.- In the 29–35 lines we render weekdays.
- In the 37–56 lines we render calendar days rows. Also, we attach proper class names depending on the selected date.
That’s it for this article. Now our Datepicker
component is ready to be used.
Thanks for reading!
I hope, you found this article useful. If you have any questions or suggestions, please leave comments. Your feedback helps me to become better.
Don’t forget to subscribe⭐️