What is the size impact of importing Moment.js

In this article, I'll look at how much our application is growing when we add Moment.js. As Moment.js is not supporting tree shaking, it makes no difference if we use many or 1 methods from it.

Library

Moment.js is a popular but deprecated library - the project has an entire page dedicated to discouraging you from using it. I include it in this series mostly for the sake of completes - according to npm trends it's still the most popular library among the ones I checked:

date-fns-vs-luxon-vs-moment-vs-dayjs.png

Code

For making the comparison, I use straightforward code:

import moment from "moment";

console.log("Yesterday was", moment().subtract(1, "day").toDate());

If you compare it with Day.js you can see that Day.js indeed has a similar API to the one in Moment.js.

Build scripts

I use simple build scripts:

$ webpack --mode=production
$ esbuild src/index.js --outfile=dist/main.js --bundle --minify

There is a guide on how to optimize Moment.js build in webpack, but I'll leave the straightforward approach:

  1. It's simpler this way 2 I didn't use dedicated, build optimization plugins in other libs, so why should Moment.js be treated differently.

Benchmark

The results:

Webpack

$ npm run webpack

> moment-js-bundle-size@1.0.0 webpack
> webpack --mode=production

asset main.js 290 KiB [emitted] [minimized] [big] (name: main) 1 related asset
runtime modules 786 bytes 4 modules
modules by path ./node_modules/moment/locale/*.js 499 KiB 135 modules
./src/index.js 98 bytes [built] [code generated]
./node_modules/moment/moment.js 170 KiB [built] [code generated]
./node_modules/moment/locale/ sync ^\.\/.*$ 3.21 KiB [optional] [built] [code generated]

WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets: 
  main.js (290 KiB)

WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can impact web performance.
Entrypoints:
  main (290 KiB)
      main.js


WARNING in webpack performance recommendations: 
You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.
For more info visit https://webpack.js.org/guides/code-splitting/

webpack 5.48.0 compiled with 3 warnings in 4067 ms

$ stat dist/main.js
  File: dist/main.js
  Size: 296747

The build feels slow, and the output is 290 KiB. Quite a big performance hit for a simple date calculation.

esbuild

$ npm run esbuild  

> moment-js-bundle-size@1.0.0 esbuild
> esbuild src/index.js --outfile=dist/main.js --bundle --minify


  dist/main.js  59.4kb

⚡ Done in 14ms
$ stat dist/main.js
  File: dist/main.js
  Size: 60855

esbuild perform noticeably better - build is instant, and the output has 59.4 KiB. This result is similar to the one of luxon.

Links

The repository.

Summary

We have seen the impact of using Moment.js in the project. I hope this article will help you sell the idea of refactoring it out of your project.