# [You don't (may not) need Moment.js](https://you-dont-need.github.io/You-Dont-Need-Momentjs/#/)
[Moment.js](https://momentjs.com/) is a fantastic time & date library with lots of great features and utilities. However, if you are working on a performance sensitive web application, it might cause a huge performance overhead because of its complex APIs and large bundle size.
Problems with Moment.js:
- It is highly based on OOP APIs, which makes it fail to work with tree-shaking, thus leading to a huge bundle size and performance issues.
- It is mutable and it causes bugs:
- [clone](https://momentjs.com/docs/#/parsing/moment-clone/)
- [How do I work around mutability in moment.js?](https://stackoverflow.com/questions/30979178/how-do-i-work-around-mutability-in-moment-js)
- Complex OOP API (which doubles mutability problem). Here is an example:
https://github.com/moment/moment/blob/develop/src/test/moment/add_subtract.js#L244-L286
Moment.js allows to use `a.subtract('ms', 50)`, `a.subtract(50, 'ms')` and even `a.subtract('s', '50')`.
If you are not using timezone but only a few simple functions from moment.js, this might bloat your app, and therefore is considered overkill. [dayjs](https://github.com/iamkun/dayjs) has a smaller core and has very similar APIs so it makes it very easy to migrate. [date-fns](https://github.com/date-fns/date-fns) enables [tree-shaking and other benefits](https://github.com/date-fns/date-fns/issues/275#issuecomment-264934189) so that it works great with React, Sinon.js, and webpack, etc. See https://github.com/moment/moment/issues/2373 for more ideas on why and how people switch from moment.js to other solutions.
## Brief Comparison
| Name | Tree-shaking | Methods richness | Pattern | Locale | Timezone Support | Popularity (stars) | Sizes |
| --------- | ------------ | ---------------- | ---------- | ------ | ---------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Moment.js | No | High | OO | 123 | Good (moment-timezone) | | |
| Luxon | No | High | OO | - | Good (Intl) | | |
| date-fns | Yes | High | Functional | 64 | Good (date-fns-tz) | | |
| dayjs | No | High | OO | 138 | Good (Intl) | | |
## Voice of Developers
> [Removed moment.js to replace with date-fns - build output reduced by 40%](https://github.com/oysterprotocol/webnode/pull/116)
> —Jared Farago from [webnode](https://github.com/oysterprotocol/webnode/pull/116) project.
> [Good library if you’re looking to replace Moment.js for one reason or another. Immutable too.](https://twitter.com/dan_abramov/status/805030922785525760)
> —Dan Abramov, Author of [Redux](https://github.com/reduxjs/redux) and co-author of [Create React App](https://github.com/facebook/create-react-app). Building tools for humans.
> [I strongly recommend using date-fns over Moment.js, it's has a nicer API and you can include only parts you need!](https://twitter.com/silvenon/status/804946772690923520)
> —Matija Marohnić, a design-savvy frontend developer from Croatia.
## ESLint Plugin
If you're using [ESLint](http://eslint.org/), you can install a
[plugin](http://eslint.org/docs/user-guide/configuring#using-the-configuration-from-a-plugin) that
will help you identify places in your codebase where you don't (may not) need Moment.js.
Install the plugin...
```sh
npm install --save-dev eslint-plugin-you-dont-need-momentjs
```
...then update your config
```js
"extends" : ["plugin:you-dont-need-momentjs/recommended"],
```
## Quick Links
**[Parse](#parse)**
1. [String + Date Format](#string--date-format)
1. [String + Time Format](#string--time-format)
1. [String + Format + locale](#string--format--locale)
**[Get + Set](#get--set)**
1. [Millisecond/Second/Minute/Hour](#millisecond--second--minute--hour)
1. [Date of Month](#date-of-month)
1. [Day of Week](#day-of-week)
1. [Day of Year](#day-of-year)
1. [Week of Year](#week-of-year)
1. [Days in Month](#days-in-month)
1. [Weeks in Year](#weeks-in-year)
1. [Maximum of the given dates](#maximum-of-the-given-dates)
1. [Minimum of the given dates](#minimum-of-the-given-dates)
**[Manipulate](#manipulate)**
1. [Add](#add)
1. [Subtract](#subtract)
1. [Start of Time](#start-of-time)
1. [End of Time](#end-of-time)
**[Display](#display)**
1. [Format](#format)
1. [Time from now](#time-from-now)
1. [Time from X](#time-from-x)
1. [Difference](#difference)
**[Query](#query)**
1. [Is Before](#is-before)
1. [Is Same](#is-same)
1. [Is After](#is-after)
1. [Is Between](#is-between)
1. [Is Leap Year](#is-leap-year)
1. [Is a Date](#is-a-date)
# Feature Parity
⚠️ Indicates other packages or work are needed. See individual functions [above](#quick-links).
| | Native | Luxon | date-fns | dayjs | Temporal |
| ------------------------------ | ------ | ----- | -------- | ----- | -------- |
| **Parse** | | | | | |
| String + Date Format | ✅ | ✅ | ✅ | ✅ | ✅ |
| String + Time Format | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| String + Format + locale | ❌ | ⚠️ | ✅ | ⚠️ | ❌ |
| | | | | | |
| **Get + Set** | | | | | |
| Millisecond/Second/Minute/Hour | ✅ | ✅ | ✅ | ✅ | ✅ |
| Date of Month | ✅ | ✅ | ✅ | ✅ | ✅ |
| Day of Week | ✅ | ✅ | ✅ | ✅ | ✅ |
| Day of Year | ✅ | ✅ | ✅ | ✅ | ✅ |
| Week of Year | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| Days in Month | ✅ | ✅ | ✅ | ✅ | ✅ |
| Weeks in Year | ❌ | ❌ | ✅ | ⚠️ | ✅ |
| Maximum of the given dates | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| Minimum of the given dates | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| | | | | | |
| **Manipulate** | | | | | |
| Add | ✅ | ✅ | ✅ | ✅ | ✅ |
| Subtract | ✅ | ✅ | ✅ | ✅ | ✅ |
| Start of Time | ❌ | ✅ | ✅ | ✅ | ✅ |
| End of Time | ✅ | ✅ | ✅ | ✅ | ✅ |
| | | | | | |
| **Display** | | | | | |
| Format | ✅ | ✅ | ✅ | ✅ | ✅ |
| Time from now | ✅ | ❌ | ✅ | ⚠️ | ✅ |
| Time from X | ❌ | ❌ | ✅ | ⚠️ | ✅ |
| Difference | ✅ | ✅ | ✅ | ✅ | ✅ |
| | | | | | |
| **Query** | | | | | |
| Is Before | ✅ | ✅ | ✅ | ✅ | ✅ |
| Is Same | ✅ | ✅ | ✅ | ✅ | ✅ |
| Is After | ✅ | ✅ | ✅ | ✅ | ✅ |
| Is Between | ❌ | ✅ | ✅ | ⚠️ | ❌ |
| Is Leap Year | ✅ | ✅ | ✅ | ⚠️ | ✅ |
| Is a Date | ✅ | ✅ | ✅ | ✅ | ✅ |
## Parse
### String + Date Format
Return the date parsed from date string using the given format string.
```
…
```
**[⬆ back to top](#quick-links)**
### String + Time Format
Return the date parsed from time string using the given format string.
```
…
```
**[⬆ back to top](#quick-links)**
### String + Format + locale
Return the date parsed from string using the given format string and locale.
```
…
```
**[⬆ back to top](#quick-links)**
## Get + Set
### Millisecond / Second / Minute / Hour
Get the `Millisecond/Second/Minute/Hour` of the given date.
```js
// Moment.js
moment().seconds();
// => 49
moment().hours();
// => 19
// Native
new Date().getSeconds();
// => 49
new Date().getHours();
// => 19
// date-fns
import getSeconds from 'date-fns/getSeconds';
import getHours from 'date-fns/getHours';
getSeconds(new Date());
// => 49
getHours(new Date());
// => 19
// dayjs
dayjs().second();
// => 49
dayjs().hour();
// => 19
// Luxon
DateTime.local().second;
// => 49
DateTime.local().hour;
// => 19
// Temporal
Temporal.Now.zonedDateTimeISO().second;
// => 49
Temporal.Now.zonedDateTimeISO().hour;
// => 19
```
### Performance tests
| Library | Time |
| -------- | ---------- |
| Moment | 1500.703ms |
| Native | 348.411ms |
| DateFns | 520.670ms |
| DayJs | 494.234ms |
| Luxon | 1208.368ms |
| Temporal | - |
Set the `Millisecond/Second/Minute/Hour` of the given date.
```
…
```
### Performance tests
| Library | Time |
| -------- | ---------- |
| Moment | 1689.744ms |
| Native | 636.741ms |
| DateFns | 714.148ms |
| DayJs | 2037.603ms |
| Luxon | 2897.571ms |
| Temporal | - |
**[⬆ back to top](#quick-links)**
### Date of Month
Gets or sets the day of the month.
```
…
```
### Performance tests
| Library | Time |
| -------- | ---------- |
| Moment | 1381.669ms |
| Native | 397.415ms |
| DateFns | 588.004ms |
| DayJs | 1218.025ms |
| Luxon | 2705.606ms |
| Temporal | - |
**[⬆ back to top](#quick-links)**
### Day of Week
Gets or sets the day of the week.
```
…
```
| Library | Time |
| -------- | ---------- |
| Moment | 1919.404ms |
| Native | 543.466ms |
| DateFns | 841.436ms |
| DayJs | 1229.475ms |
| Luxon | 3936.282ms |
| Temporal | - |
**[⬆ back to top](#quick-links)**
### Day of Year
Gets or sets the day of the year.
```
…
```
| Library | Time |
| -------- | ---------- |
| Moment | 5511.172ms |
| Native | 530.592ms |
| DateFns | 2079.043ms |
| DayJs | - |
| Luxon | 3540.810ms |
| Temporal | - |
**[⬆ back to top](#quick-links)**
### Week of Year
Gets or sets the week of the year.
```
…
```
| Library | Time |
| -------- | ---------- |
| Moment | 7147.201ms |
| Native | 1371.631ms |
| DateFns | 5834.815ms |
| DayJs | - |
| Luxon | 4514.771ms |
| Temporal | - |
**[⬆ back to top](#quick-links)**
### Days in Month
Get the number of days in the current month.
```js
// Moment.js
moment('2012-02', 'YYYY-MM').daysInMonth();
// => 29
// Native
new Date(2012, 02, 0).getDate();
// => 29
// date-fns
import getDaysInMonth from 'date-fns/getDaysInMonth';
getDaysInMonth(new Date(2012, 1));
// => 29
// dayjs
dayjs('2012-02').daysInMonth();
// => 29
// Luxon
DateTime.local(2012, 2).daysInMonth;
// => 29
// Temporal
(new Temporal