Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from moment to date-fns? #208

Open
aaronjensen opened this issue Dec 6, 2016 · 55 comments
Open

Switch from moment to date-fns? #208

aaronjensen opened this issue Dec 6, 2016 · 55 comments
Labels
feature request I want a new feature in react-dates! question

Comments

@aaronjensen
Copy link

I don't know what it would take to do, but reducing dependencies on moment would be a great thing.

https://date-fns.org/

@jpollard-cs
Copy link
Contributor

@aaronjensen I wouldn't assume folks are familiar with this library. It would probably help if you outlined the advantages of this library over moment (and in the context of react-dates).

@aaronjensen
Copy link
Author

There are some reasons on this issue: date-fns/date-fns#275

The primary reason for me is the size of moment with or without its locales (I hack them out using webpack, but moment is still pretty big). If you don't need all of the functionality from date-fns you can just use the functions you need, making the size even smaller. You could potentially get rid of the peerDependency and simply bundle the functionality you need.

@ljharb
Copy link
Member

ljharb commented Dec 7, 2016

If date-fns gains traction in the community, then it might be reasonable to support both moment and date-fn objects - although that wouldn't make the dependencies any smaller.

The author of date-fns points out some reasons in date-fns/date-fns#275 (comment) that we wouldn't want to support it just yet - and when it did have those capabilities, there's no reason not to switch over to it completely.

In general, nobody doesn't need "every locale known to humans" - because every locale you fail to account for, is a human you're excluding. That choice goes against the spirit of both the project and Airbnb.

@ljharb ljharb added feature request I want a new feature in react-dates! question labels Dec 7, 2016
@andrewmclagan
Copy link

I would be very interested in this, date-fns has gained allot of traction and looking forward seems to have allot more momentum and a better footing.

@shinzui
Copy link

shinzui commented Mar 17, 2017

@ljharb date-fns supports 32 locales now with more coming. It's also quickly gaining traction in the community.

@ljharb
Copy link
Member

ljharb commented Mar 18, 2017

When it supports every locale that moment does, and passes all of moments test cases, then it is worth having this conversation again. :-)

@andrewmclagan
Copy link

Agreed. Although, without digging too much @ljharb do you think there is allot of work to swap out implementations?

@ljharb
Copy link
Member

ljharb commented Mar 23, 2017

That would depend on the moment APIs we're using, and how date-fns' API compares - assuming it's a change we want to make.

@rubencodes
Copy link

@andrewmclagan Just browsed through the moment usage in this project (I'm also interested in this swap) and it's very minimal (IMO), should be a relatively easy swap I think... Might make a fork to try it out.

FWIW Moment.js is great but just huge, and if we're talking about "excluding humans", being data-usage-savvy is also a super important consideration.

@ljharb
Copy link
Member

ljharb commented Apr 29, 2017

Its importance is why this issue remains open :-).

@rubencodes
Copy link

rubencodes commented Apr 30, 2017

I created a branch of react-dates that uses date-fns in place of moment (without implementing the locale logic). Whereas moment is a ~130kb bundle (without locales), this version only uses 52kb of date-fns. That number might be further reducible. However, after gzipping, we're really only looking at a savings in the tens of KB's (in my case, around a 12kb difference after gzipping). Again, that's without even implementing locale support. Presumably the size difference would shrink after that.

So, in conclusion, I'm not really sure it's worth it to switch over—at least not for size savings. There's many other reasons why using a more functional approach like date-fns (and native Date objects) may be beneficial.

@selfcontained
Copy link

FWIW this module from the people @ smallwins could be a good candidate for a lighter-weight date/time manipulation lib, released pretty recently. It's 35KB total (12KB gzippd).

https://github.com/smallwins/spacetime

@jxom
Copy link

jxom commented Sep 14, 2017

This is very important IMO. A gzipped moment bundle is 64.8K which is quite clunky...

@rubencodes
Copy link

@jxom if you're interested, I do have a public fork of react-dates that uses date-fns, with the caveats I mentioned above. It's a few months out of date but I could update it if you're interested.

@glintik
Copy link

glintik commented Sep 18, 2017

Hi guys,

I've also added support of date-fns(with locales) in my fork glintik/react-dates@831870d. Minified build size with date-fns reduced by ~100K. Worth to note, that here is another way to reduce build size with the moment by cutting locales - just add plugin to webpack:

new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)

We can add support to react-dates of two dates library - moment and date-fns. It provides flexibility and great choice.

@majapw
Copy link
Collaborator

majapw commented Sep 18, 2017

Hi @glintik, thanks for the link to your fork! I'm curious as to if you had any idea for how to support both libraries (and if there is a clean/easy way to do that).

@glintik
Copy link

glintik commented Sep 18, 2017

Hi @majapw, as a possible solution: introduce a property moment to *Picker components and use it futher. I made a moment-like interface object DateObj that provides moment-methods and uses date-fns inside. So user have a choice, what supply to moment property.
Moment will be removed from dependencies in package.json.

@ljharb
Copy link
Member

ljharb commented Sep 19, 2017

@glintik that seems like it would be a burden on users; they'd have to make react-dates stateful (which it currently isn't) and inject moment, where currently they don't have to do that at all - only moment is stateful (which it already is).

@ConAntonakos
Copy link

With the release of Luxon, perhaps that can be a viable candidate? Or consider a date formatting interface like @majapw's suggests (#839 (comment))?

@erin-doyle
Copy link
Collaborator

erin-doyle commented Nov 30, 2017

Luxon does look more viable to me than date-fns at this time.

Localizations and time zones are implemented by the native Intl API (or a polyfill of it), instead of by the library itself.

This seems like much better solution for covering the localization compared to date-fns.

Here are their docs on output formatting: https://moment.github.io/luxon/docs/manual/formatting.html and here on differences between Luxon and Moment: https://moment.github.io/luxon/docs/manual/why.html

@SamMatthewsIsACommonName

Another thing to consider is that a LOT of people (look at the stars on luxon repo) are moving to luxon from monent for reasons such as immutability and reduced bundle size. However we are then stuck having to use both because of the dependency of this library.
Just a thought to consider. I agree it would be the most viable alternative candidate though, and the immutability may help remove some small bugs too, who knows (unless this uses moment clone which it probably does)? I know I had bugs in my code caused by moment's mutability.

@bes
Copy link

bes commented Feb 21, 2018

Any movement on this? I recently switched to Luxon from Moment in my projects and it is working very well.

@KingScooty
Copy link

I'm curious about this too. We use react-dates in a project, and the moment payload is massive. It makes no sense to bundle all locales for the client, when the client only needs 1 locale at a time.

@ljharb
Copy link
Member

ljharb commented Mar 19, 2018

There’s no reason you have to bundle all locales; that’s just webpack’s default behavior.

@Magellol
Copy link

@KingScooty Funny enough, webpack has documentation to exclude the locales from the bundle.

https://webpack.js.org/plugins/ignore-plugin/#ignore-moment-locales

@farnoy
Copy link

farnoy commented Nov 27, 2018

Fair enough, I assumed Intl was in a state where it could handle these things, but it is not.

@bjankord
Copy link

bjankord commented Dec 7, 2018

This is one of the most well-developed date pickers I've seen, I'm impressed with the accessibility features of it, though the size moment adds is concerning. We are currently using https://github.com/Hacker0x01/react-datepicker which just recently moved away from using moment and towards using the native JavaScript Date object paired with date-fns.

Based on this comment from @ljharb

When it supports every locale that moment does, and passes all of moments test cases, then it is worth having this conversation again. :-)

It looks like moment has support for 123 locales while date-fns has support for 27 locales.

Based on this metric, I don't see date-fns become a viable solution, though I think it's still worth consideration.

Reading through the last meeting notes on Temporal proposal, it sounds like BigInt may also be needed with using Temporal which would need to be polyfilled.

Edit: Maybe only the Temporal polyfill is needed, haven't looked into it too much.

Looks like the temporal pollyfill isn't too big. https://bundlephobia.com/result?p=@wealthbar/tc39-temporal@1.0.0

I understand the concern of not wanting to make a 2 breaking changes, one to move away from moment to (date-fns, luxon, etc) and one to move to the Temporal proposal.

@Vages
Copy link

Vages commented Jul 16, 2020

Slight update: date-fns now support 70 locales: https://github.com/date-fns/date-fns/blob/master/src/locale/index.js

@rektide
Copy link

rektide commented Sep 15, 2020

Recent posting from Moment, describing the state of the proejct:

Recently, Chrome Dev Tools started showing recommendations for replacing Moment for the size alone. We generally support this move.
[snip: list of alternatives]
We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.

https://momentjs.com/docs/#/-project-status/

I think a lot of people would really love & enjoy a switch to date-fns or #1947 or proposal-temporal. Moment.js indicating that they are a done project & talking about their large size, agreeing with the recommendation to not use Moment for projects, is something I thought worth mentioning in this ticket.

@ljharb
Copy link
Member

ljharb commented Sep 15, 2020

Temporal is not yet stage 3, and thus is much too premature to use.

However, the champions’ current plan is to aim for stage 3 in November, and it’s simply not worth migrating to another date library twice.

@tonyhb
Copy link

tonyhb commented Sep 15, 2020

Just want to note that adding "driver" support explicitly means that we dont have to migrate date libraries twice.

You migrate once and add driver support. Extensibility and interfaces, similar to other well designed systems.

@ljharb
Copy link
Member

ljharb commented Sep 15, 2020

@tonyhb that is only true if every relevant date library ends up having the same props patterns/design. moment only has one "kind" of object - Temporal has like 6 or more, and it's highly likely that components will need breaking changes to be able to accept only the relevant Temporal types.

@tonyhb
Copy link

tonyhb commented Sep 15, 2020

No no. We design the interface that this date picker uses (actually done), and we build an adapter over the specific implementations so they conform to our interface (also done for moment and luxon).

Edit: To expand, that's kind of the point of a driver. Build an adapter over your dependencies so that they conform to what you need, and normalize the API that you use so that you can swap out dependencies at will. You then don't care about how the implementation works - they can have the craziest APIs they want! The driver normalizes it.

@ljharb
Copy link
Member

ljharb commented Sep 16, 2020

@tonyhb that is certainly a good goal to strive for, and certainly i understand the point of an adapter :-) what i'm saying is, unless you're designing the interface for Temporal (which is unknown until stage 3), we can't know in advance what the adapter would need to provide to be able to abstract things away sufficiently to make swapping nonbreaking.

@tonyhb
Copy link

tonyhb commented Sep 16, 2020

I'll drop this discussion after one more comment:

we can't know in advance what the adapter would need to provide to be able to abstract things away sufficiently

Yes, we totally can. I don't understand how you say that. The datepicker already exists! We know what APIs we need to provide to make the date picker work. There are only several functions that we need in a driver for this library - already defined https://github.com/airbnb/react-dates/pull/1947/files#diff-5843b3fcb06308c995f15755473ca448R75-R106. Lets walk through it:

  1. This is the driver functionality that is used in the datepicker. We design it, because it's only used in the datepicker.
  2. There are individual wrappers over each implementation
  3. These wrappers use whatever API the implementation provides under the hood
  4. These wrappers - adapters in common design language - are swappable at any time and anyone can write new adapters at any point in time when future technology changes. Such as temporal, in the future.

We are not designing the interface for temporal! I can't emphasise this any clearer. We are designing the interface for the datepicker. However temporal ends up, we build a wrapper over it. And of course the adapter can't be built until temporal exists. I'm not saying we need a temporal adapter now... we need it after it's ready.

So, no, we can do this now, in advance. Frankly, it's already done. It needs some testing and some actual constructive feedback rather than stonewalling.

Also, pretending the above didn't matter for just a second, it has been said in this thread - for 2 years - "temporal is close". If it's so far away that we don't know the API, please stop saying it's close!

@thibaudcolas
Copy link

thibaudcolas commented Sep 16, 2020

With the statement from Moment.js in mind, could we get a similar statement somewhere on the react-dates README, documenting the intention to keep using moment as-is for now, and eventually replace it with Temporal / the (polyfilled) standard library / whichever other approach?

Personally I’m a happy Moment user, and also very happy they’ve officially clarified the situation that project is in – would be good for react-dates to have a clear position too, considering it’s likely lots of react-dates users are only using Moment because of it.

@bsides
Copy link

bsides commented Jan 22, 2021

The lack of decisions here after 2 years makes me afraid of using this library. I'm moving on to a driver based one like react-datepicker too.

@ljharb
Copy link
Member

ljharb commented Jan 22, 2021

@bsides there is no lack of decisions. The decision remains the same as it has always been: moment.js, only, until Temporal is stage 3, at which point we will move to Temporal, only (as should everything else in the ecosystem). There's no value in migrating to date-fns now only to migrate again to Temporal.

@jsphkhan
Copy link

This is what moment team is saying - "The Moment team has discussed these issues at length. We recognize that many existing projects may continue to use Moment, but we would like to discourage Moment from being used in new projects going forward. Instead, we would like to recommend alternatives that are excellent choices for use in modern applications today. "

Furthermore it is important now to have date-fns support or general JS Date support.

@ljharb
Copy link
Member

ljharb commented Feb 16, 2021

This isn’t a new project.

i don’t agree it’s important - until Temporal, moment is the de facto standard, no matter what the moment team says; once Temporal arrives, everything else, including moment, date-fns, and Date itself, will be obsolete and should be aggressively migrated away from.

@ConAntonakos
Copy link

Temporal is finally Stage 3! https://github.com/tc39/proposal-temporal/pull/1440/files

@ljharb
Copy link
Member

ljharb commented Mar 11, 2021

Indeed it is, as of today.

However, a) there’s still some format questions to work out, so browsers are going to ship it behind a flag, and b) a production-ready polyfill doesn’t yet exist.

I’ll be publishing one in the next month or so, at which point we’ll begin migrating.

@mijamo
Copy link

mijamo commented Sep 8, 2021

The production polyfill is now getting some steam here: https://github.com/js-temporal/temporal-polyfill

@ljharb
Copy link
Member

ljharb commented Sep 8, 2021

@mijamo the proposal itself continues to have normative changes, so no polyfill is viable yet; that particular one doesn’t support enough browsers/node versions to be viable last i checked.

@javierfuentesm

This comment was marked as spam.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request I want a new feature in react-dates! question
Projects
None yet
Development

No branches or pull requests