Why we switched from Moment.js to Day.js

Moment.js is an awesome library when it comes to performing complex date-time manipulations. It provides a rich and clean API that covers many use cases. That aside, Moment.js shouldn’t always be the go-to library when it comes to date-time problematics. Alternatives should be considered as well.

What are the alternatives?

Actually, there are plenty of alternatives out there:

Why we picked Day.js?

This decision bases on two reasons:

  1. Lightweight – only 2.6KB gzip
  2. Similar API to Moment.js – which means easier migration

How the migration went?

All date-time functions used in our apps are located in the service date.service.ts. So the migration of this service made the switch possible for us.
In general, having the date-time manipulation centralised in one place is a good practice. It makes changes like this one possible without much effort.

The migration process

  1. Make sure that the service is 100% covered with unit tests
  2. Check if all Moment.js API usages are available in Day.js
  3. Replace Moment.js with Day.js in the package.json
  4. Adjust the service to use Day.js

Step 1. was an easy one. We just wrote the missing unit tests for our service.
In general, test coverage of utility functions should always be high.

In Step 2. we found out that the following changes were necessary:

  • Object instantiation
// Moment.js
const now = moment();
const day = moment('2019-07-12');
// Day.js
const now = dayjs();
const day = dayjs('2019-07-12');
  • Second parameter in diff is plural in Moment.js, but singular in Day.js
// Moment.js
var date1 = moment('2019-07-11');
var date2 = moment('2019-07-10');
date1.diff(date2, 'years'); // 0
date1.diff(date2, 'days'); // 1
// Day.js
const date1 = dayjs('2019-07-11');
const date2 = dayjs('2019-07-10');
date1.diff(date2, 'year'); // 0
date1.diff(date2, 'day'); // 1
  • UTC support doesn’t come out of the box with Day.js
// Moment.js
moment('2019-07-12T15:37:01+02:00').utc().format(); //2019-07-12T13:37:01Z
// Day.js
import dayjsPluginUTC from 'dayjs-plugin-utc';

dayjs.extend(dayjsPluginUTC);
dayjs('2019-07-12T15:37:01+02:00').utc().format(); //2019-07-12T13:37:01Z
  • months() doesn’t exists in Day.js
// Moment.js
moment.months(); // ['January', 'February', ... , 'December' ]
// Day.js
dayjs.months(); // dayjs.months is not a function

The APIs are mostly compatible. Finding these key differences between the libraries helped us to tackle all the issues in Step 3 and 4.

All other changes were specifically related to our business logic.

How our bundle changed?

The migration confirmed our intentions. Our bundle is 60KB (~10%) lighter.
Gzipped size of Moment.js was 72.47KB and now of Day.js is 3.14KB (including locale and UTC plugin)

TL;DR

So far, switching to Day.js seems like a great decision. We haven’t run into any issues since our migration, one month ago.

The goal of this blog post is not to convince you that Day.js is awesome and Moment.js is terrible. But to remind you that choosing a date-time library is not an easy task.
There are many options available, so take your time and find out which one might be the best for your apps and needs.