Hacker News new | past | comments | ask | show | jobs | submit login
We now consider Moment.js to be a legacy project in maintenance mode (momentjs.com)
1129 points by maple3142 on Sept 15, 2020 | hide | past | favorite | 257 comments

Good for them. Open Source seems to have an irrational fear of done.

Done is good. Done should be the goal.

But it’s not. Because if you’re not adding new features and pushing code changes every day, your project is abandoned, dead. To quote another thread from two minutes ago: “I’m quite sad to see the end of Moment.js”

I wish the was a way to fix this attitude. So that project maintainers didn’t need to write two page apologies for finishing their thing.

> I wish the was a way to fix this attitude. So that project maintainers didn’t need to write two page apologies for finishing their thing.

One of the problems is that GitHub is full of OSS libraries where the last commit was three years or more ago and you have no idea (without forensically analysing commits, issues, etc.) whether it's because the project is done or because the maintainer(s) lost interest, had other priorities, etc.

And you have no idea because they haven't said. They haven't told anyone: it's just drifted into an unclear state of unmaintained-ness.

I would suggest rather that what the Moment.js team have done here should be the norm: i.e., clear communication of the situation. That situation, as here, might be "done", or it might be "the thing's only half finished but we don't care enough to carry on any more", or something completely different. These are all good reasons to stop working on something even if they're potentially frustrating for users. E.g., in the "don't care" scenario, people have the option to step in and pick up maintenance, fork the project, or simply not use it.

Doesn't matter: understanding the state of a potential dependency in terms of maintenance and development is the key factor that will enable people to make an informed decision about whether to use it or not.

> One of the problems is that GitHub is full of OSS libraries where the last commit was three years or more ago and you have no idea (without forensically analysing commits, issues, etc.) whether it's because the project is done or because the maintainer(s) lost interest, had other priorities, etc.

I don't think there's any at least medium sized project that is considered to be done but not abandoned/legacy and does not receive any commits.

Any non-trivial project that has no commit since the last three years is abandoned. Even in the case a project is considered to be done/finished, in order to not abandon it you have to maintain it: fix security issues, update outdated dependencies, update tooling so that you can still run/compile with non outdated tools and so on.

You might benefit from flipping this around and asking yourself why you're not able to ship software that remains shipped without intervention. And why you can't even imagine a world where that would be possible.

If you spend some time and effort removing whatever obstacles you have in place that are keeping you from being able to do that, you'll have a lot more free time to spend building new things.

For what it's worth, this world does in fact exist. And there are lots of us living in it. Here's hoping you find a way to join us!

> If you spend some time and effort removing whatever obstacles you have in place that are keeping you from being able to do that

This is literally impossible for many JS libraries. Chromium / NodeJS / other JS environments are themselves constantly changing. Irrespective of the evolving timezone info, the core MomentJS can only be "done" for a particular set of browser versions. Each bug pertaining to dates, like https://bugs.chromium.org/p/v8/issues/detail?id=7863 , is a potential browser/engine version for which Moment needs a fix.

> this world does in fact exist

It only exists for certain proprietary software and SaaS developers because of the hard work of open source developers to keep up with the changing landscape. If everyone adopted your attitude, you would be forced to contend with the true nature of the ecosystem directly.

This is true, but also it would be good if the JS environments stopped doing that.

If the Web, browsers, the JS lang, sandboxing, Internet protocols, TLS, etc. were all perfect and done, then JS envs would be too.

So your projects have no dependencies? You just write everything from scratch? Your code is perfect the first time you write it? I'm utterly confused by this comment.

There are plenty of projects which do not need to change once written as long as you leave web-based things. Some examples:

I recently found my old GPS logger, and wanted to pull data from it. I installed "mtkbabel" package and it worked wonderfully. This code was last updated in 2013 [0].

I was recently copying some files from one of my embedded boxes. It had rsync 3.1.2, released in 2015. Still works and no need to upgrade (the page lists some security vulnerabilities for this version, but this is only for "untrusted server" scenarios, which I never have)

The embedded systems not connected to internet will generally work forever without any updates. I do have a 20 year old MP3 player and it still works fine.

[0] https://metadata.ftp-master.debian.org/changelogs//main/m/mt...

This is security (and thus stability) by obscurity basically. By being an obscure userbase, a niche.

Browsers, compilers, SSL/TLS libraries, operating systems and so on doesn't have this luxury, and thus this has a knock-on effect.

I would not say that non-web software is "obscure". You probably interact with it as much as you interact with desktop/phone software -- think vehicles and home appliances. And factories that produce all the stuff you use are famous for having very old software -- I would not be surprised if a factory which makes springs for your chair still has some MS-DOS machines around.

Remember, the post I am replying to says "no commit since the last three years" -> "abandoned". The software life of 3 years is really not that long for many contexts.

I agree with that anything browser-related needs to be constantly updated, especially if you need fancy functionality. But if you do not need this functionality, then HTML 4 based stuff still works and does not need to be updated.

Compilers (and programming languages by extensions) do not need to be updated very often. 5 years ago we had gcc 5 and python 3.5. There is no reason to upgrade them at all if your build system does not require it (for example, if you use buildroot or customized emerge or docker). And you do want to use latest versions, then there is a very high chance your software will work with the latest versions without any changes.

SSL/TLS libraries are important to keep patched. Luckily, the critical faults do not happen that often. For example, last critical vulnerability in OpenSSL was in 2016 -- so you really did not need to update your SSL libraries in the last 3 years.

Operating systems upgrades are probably the biggest drivers for the changes. But again, Ubuntu LTS have full security support for 5 years -- so if you can require a specific OS (embedded device or container) then you can update the software only twice a decade.

The software world is very big. The web / GUI world is most visible of them all, but it does not mean everything else is "obscure".

Hm, right, obscure is not the right terms to use, a mix of "done" plus "very much not in active development" are closest.

I meant obscure as in: except from a very specific persistent and advanced adversary (APTs) no one will even try to hack something like that directly. Sure, it's possible, so it's put behind a lot of firewalls, middlewares, wrappers and message queues. At least that's how one insurance company I work with uses COBOL. And if they can avoid touching it, they won't, because it's so hard/risky/expensive, and the risk of external security intrusion has been deemed low. It's abandoned as a product, as a goal, it's basically an aging power tool at this point, that will eventually give up. (Like embedded stuff.)

I know 3 years is not that long. I'm just saying that the various forces (business and security aspects) that be usually dictate fast turnaround, or at least a certain minimal level of upkeep.

Java, C++, Rust, PHP, JS, etc. all have quite a big velocity nowadays.

Python 3.5 just got EOLed.

Sure, you don't have to upgrade every last piece of python script. After all RHEL and other distros still provide some py2 support too. And if your business is not growing fast, your build system is "done", then you don't have to touch it much. But eventually it'll need some maintenance, maybe just a few touches to keep it future proof, but that again also implies that it's a niche, a custom software that does what you need it to do, that's likely not a high-profile target directly.

If you want stable, long lifespan software, this is exactly how you do it. You are also careful to only build on layers of abstraction that are also designed with this mindset. Yes, it limits what you can do and which features you can rely on, but it is an achievable goal for many critical lower level libraries.

> it limits what you can do

Yep. For example you have to basically air-gap your software, no input/output, especially nothing that touches crypto/TLS/networks/protocols, usually no support for fancy file formats either.

Or you can just go ahead and implement all those by hand. Perfectly.

I mean it's possible, but bumping BoringSSL/Libre/OpenSSL version every few months seems easier.


A project can't be more stable than its dependencies and tooling, but that doesn't mean that the only way to be stable is to have no dependencies.

Some programming languages make guarantees that old code will build in new versions (eg, ISO C even refuses to introduce new warnings for code that would previously build without warnings), while others will introduce backwards incompatible changes in minor releases. How much maintenance a project needs after it is "done" really depends on the tooling environment.

Library and framework maintainers will eventually stop updating previous major versions. So you manage to tread water just fine till your major version reaches EOL, then you've found yourself in the position of having to change over to a completely new API on a schedule set by the maintainer of the dependency.

> Library and framework maintainers will eventually stop updating previous major versions.

And, if it's open source and it's easier than switching to a new dependency, you can just adopt maintenance of the dependency—not necessarily generally, just enough to address any bugs induced in or evolution in needs for the project(s) you have that depend on it.

It depends on the language. Fortran last broke backwards compatibility with F90. F77 code is still 100% supported. C is similar.

As far as I know Java too. That doesn't mean it's still best practice to write code that uses unsafe/deprecated constructs.

> A project can't be more stable than its dependencies

Sure it can; there's no reason a project has to take every upstream update, if, for instance, it vendors dependencies, or otherwise doesn't directly depend on the remotely maintained source.

Someone has to mull over whether to apply the update or not. Usually this is a by default "not" for most projects. (And that's not necessarily a bad stance.)

Stability is great as long as you have the luxury of no pressure for new features or better security. (Eg. operating systems, browsers, compilers, critical libraries don't.)

Imagine a CSV parser written in Java. I can imagine quite well that it would rarely need updates, as CSV does not evolve and I find it reasonable to write such code with no external dependencies except the Java standard library, which almost never breaks backward compatibility.

CSV is a very bad example. Yes, it is easy to throw together a simple regex to parse simple RFC4180 CSV strings, but Excel is its own black box with a huge number of hacks.

For example, en-US excel will automagically parse TRUE and "TRUE" to be the logical value TRUE. The way to get Excel to see a literal string TRUE is to make a formula ="TRUE". Many CSV writers implement this hack specifically assuming files will be read back in Excel. So now your parser, if you're trying to process data like Excel, has to do the same.

So then you discover that this is actually localized! If you set your UI language to French (France), Excel will treat VRAI and FAUX as booleans while TRUE and FALSE are treated as literal strings.

What you thought was a simple CSV parser now has to handle localization as well. So that CSV parser library can roll its own dodgy localization support, use a tried and true solution, or just choose not to support the feature. Each choice has its own drawbacks

> Imagine a CSV parser written in Java. I can imagine quite well that it would rarely need updates, as CSV does not evolve

CSV, which isn't even a standard and the closest thing to a standard is a description of the breadth of different behaviors seen under the name at a particular point in time with some notes about their relative frequencies and respective practical issues, does, in fact, evolve.

Depending on your needs RFC 4180 might be your CSV standard.

What if you're working in a domain which does evolve? For example, every domain.

Alright, fair, but then again what if you're building something more complex, where CSV-parsing is just 1% of what it does? Do you implement every single non-standard library functionality you need?

Don’t you have to update the project source code at least a few times a year to add new versions of Java to the CI?

Usually when bringing in a library dependency, you don't use all features from the library. If the updates to some library relate to things you don't use, and the rest remains compatible, then why update?

Because not every language / environment allows concurrent versions of a single library. PHP definitely does not, and for Java stuff IIRC you can only have one version of a library in one context of Tomcat/whatever application server you use.

Therefore you want to keep your code at least somewhat up to date so that people don't run into weird bugs.

Security teams generally have policies that require dependencies be up-to-date within a certain time frame. This is especially true if the dependency has a CVE somewhere within it - even if that CVE affects functionality that isn't utilised by the project.

As someone who used to work on fairly old embedded systems in a safety critical environment, I am extremely puzzled by your comment.

Why you would need to modify your code because you have dependencies ? Libraries'API are supposed to be stable. You can update them when they need a security patch without having to change anything in your own project.

Why do your dependencies break your project all the time that it needs updates itself?

Changing the pinning of dependencies is still a change to a project, if only a minor change.

Fair. Guess shows that I spent a lot of time recently in C and C++ lands, where that's not yet as common to even have.

Thats because web as we know it has been evolving pretty fast, while the architechtures that generally use C or C++ have remained stable for a long time.

Wow! What software is this that is complete and doesn’t need maintenance? Based on my experience, it must be either very simple or very uninteresting.

Embedded systems, particularly small ones, often don't even have a means of being updated.

You mean like TeX?

How do people use TeX nowadays? Is that part of the whole LaTeX ecosystem? How big is the userbase?

>I don't think there's any at least medium sized project that is considered to be done but not abandoned/legacy and does not receive any commits.

As another commenter mentioned, this can be pretty common in math libs.

Here's an example: https://github.com/fommil/netlib-java

This project BLAS/LAPACK/ARPACK bindings for JVM languages. The repository is marked as archived and the owner explicitly states that the project is done. The last commit was 21 Jun 2017.

This project is still heavily used, there are still multiple libraries that use those bindings.

The README.md contains install instructions for Debian and Ubuntu, these tend to outdate (not work) quite fast with newer versions of the distributions. Also if any of the low-level libraries BLAS, LAPACK or ARPACK updates, then the wrapper might not continue to work with newer versions or is stuck on a legacy version including bugs and security issues 4 ever.

> This project is still heavily used, there are still multiple libraries that use those bindings.

Heavily used does not imply that a dependency is not abandoned.

That really depends on what the project is I think (and I guess what you consider non-trivial). I can easily see e.g. a numerical library not really needing maintenance of that sort.

>in order to not abandon it you have to maintain it: fix security issues, update outdated dependencies, update tooling so that you can still run/compile with non outdated tools and so on.

If you step back a little, you can see a "positive" feedback loop. The entire issue is that maintainers have to catch crazy rabbits who have no rest, change things and abandon "old" versions that worked but were not perfect. Perfect is the enemy of good.

I was hoping to use Tex as the counter example here, because it’s a large system that’s remarkably stable. However, it’s not actually a counter example as there are small commits periodically.

So I’ll post here admitting to be wrong in my instinct.


That's TeX Live, a distribution of TeX.

TeX: The Program has had its most recent release in January 2014.

Thanks. I was noodling around on my phone trying to find it and landed there incorrectly.

There are a couple of projects I track where more than half of the commits are just updating dependencies or compatibility information.

It's both a responsible thing to do and a form of virtue signalling. Yes, we are still here.

I ended up resurrecting someone's github project by introducing a PR to fix a configuration bug. It sat for a while before the maintainer saw it, but he merged it. Then half a dozen other PRs showed up in the next six months.

You can't tell if a project is dead by the commit dates, but you might be able to tell via open PRs that go unacknowledged.

They explicitly said it will be maintained but they will not be any new features. It's not the same as a project with no commit for three years... I think this post is a bit over the top and shouldn't be required but, I agree, clear communication in OSS librairies is important.

Github having an objective "This isn't being worked on anymore" flag with a few options as to why, and pointers for where to reach a community for support/discussion would be most useful, especially overlaid on the crazy huge dependency graph frontend projects tend to acquire.

I think that is the point of the "archive" functionality: https://docs.github.com/en/github/creating-cloning-and-archi...

That's part of it, but doesn't give any useful data beyond 'archived' to make use of when considering your dependencies.

What’s the value in that vs a small note in README.md or similar?

Well, it would be more obvious. Right now, one of the first things the eyes are drawn to on a repository is the date of the last commit. I know I'm I have an internal bias against projects as soon as I see "Feb 23, 2016" as the last commit, it can make me stop scrolling without thinking about it. It would be nice to have a badge that is more obvious than the last commit date to supercede that.

There have been some attempts to improve communication on OSS projects, such as http://unmaintained.tech/

If an OSS library does what you need, is it not done in any meaningful sense anyway? It makes little difference if the author had hoped to add the kitchen sink, but gave up on it, if you don't need the kitchen sink.

If it does what I need but has a dozen security flaws because the maintainer just doesn't care anymore it makes a difference. You have to dig around to figure this out. On github it's relatively easy to check the issue tracker but still.

One case in point is (was) atftp. Since it's packaged with most distros you might be tempted to assume it's safe to use. But then I encountered a crash on Debian. Tracked down the official project page to sourceforge, found the bug was reported years ago including fix, nothing happened. Found it had several other issues like not checking return values of calls like setuid(). Debian at the time had their own patches for this in sid, since coincidentally someone must have hit the same issue around the time. Checked suse out of curiosity and they also had their own patches which were around for quite some time. Same with gentoo (I think). Obviously all three had different patches for different bugs, because unresponsive upstream. I wish there was a joint effort of distros for such cases instead of duplicating work. Or just drop dead projects with known security issues instead of this half arsed approach.

Sorry, second part is only semi related with the original issue but it's just one more way in which picking the right open source solution for a problem can be difficult because of lacking communication.

> If it does what I need but has a dozen security flaws because the maintainer just doesn't care anymore it makes a difference

Does it? The alternative might be to write your own code, which will carry your own flavour of security issues. No matter what code you adopt, be it your own or someone else's, will require some level of commitment in maintaining it.

Is not ci for this ?

Does clearly-stated and overt semantic versioning not solve this?

How so? Semantic versioning shows no indication of project status. It's just a set of numbers that defines the impact of changes since the last set of numbers.

I'm pretty sure SemVer allows for alpha and beta releases. Why not extend that versioning convention to include an omega release as well? (Is "omega release" even a thing? I'm imagining it as the last stable release - it will be maintained but no new features will be added. Which I think I would consider different from EOL.)

But even a release titled “Final-1.2.8” releases a year ago doesn’t tell you if the last release was because it was abandoned and shouldn’t be used anymore because it’s out of date or if it still works and just hasn’t been updated because there was nothing else to fix right now.

I also appreciate that they clearly covered: (i) why you shouldn't use this going forward; (ii) why you might continue to anyway; and (ii) what the alternatives are. All in all, a very well handled response.

Is this really what a "done" software is? "Should not be used for new projects" is not "done" imo, it's more like "unfixable" and "obsolete". No prejudice at all against Moment.js or its devs, but this is essentially what they're saying.

And the purpose and tone of the article does not seem to be an apology at all, but rather simply setting the expectations for future work so that the maintainers don't have to answer the same questions over and over.

Overall, good to see honest documentation of project status.

...but there's nothing to "fix", it works as intended. You might want to do things differently nowadays, is all - that's not on Moment.

Re: "obsolete"... jQuery is somewhere laughing, having gone through this already.

> ...but there's nothing to "fix", it works as intended

If there were nothing to fix, they wouldn't be telling people not to start new projects with Moment. They actually do mention a few significant issues that they can't / won't fix in Moment such as bundle size and mutability.

I will concede that perhaps Moment was "done" at some point before, some years back. When it was quite complete, yet was still the best way to do reliably work with timezoned dates in JS. But as Intl support improved, and better designed alternatives grew, it got rather obsolete, and will get more obsolete over time.

jQuery for comparison, while largely obsolete for rich web app development, is still very relevant to ecommerce, website-development-for-hire and other niches, and it will probably stay that way for a long time because it's the right design for those problems. Moment isn't the right design for any problem anymore, unless, as the article says, you need to support old browsers.

I think it's worth making the distinction between "nothing to fix" and "nothing to fix in moment.js". Clearly the problem they're trying to solve is still a real one, and there ARE problems with moment, but the cost of breaking backwards compatibility in moment to fix those problems isn't worth it because the new API would be so dissimilar to the current API it would only confuse users.

I'm not sure "done" and "obsolete" are mutually exclusive. Something can be completed but also not relevant any more. Moment is doing its date thing excellently, it's just not the best solution nowadays.

Mutability isn't an "issue", it's just not the fad of the day. Personally I like mutable objects. The size isn't that bad either.

I'm not going to stop using moment in new or existing projects for petty reasons like the ones presented. I'm tired of having the rug pulled out from under me every time I'm comfortable with something.

Ditto. While the rest of the world messes with all the problems the alternatives have, I'm just gonna drop in moment, solve the problem at hand with a few lines of code and be done with it. Date/time handling in JS is a solved problem and the solution is called moment.js.

> Is this really what a "done" software is?

I think it is. It basically solved all the problems that were there at its inception and the world moved on. It continues to offer a solution for the original problems (which legacy software most likely still has) and can still be used with minimal engineering effort.

I would call that done.

Unfixable is very different from obsolete.

MomentJS may be an exception but any JavaScript project with a large number of node_modules or testing/distribution pipelines pinned to build systems like gulp or webpack are highly likely to break from year to year as they become incompatible with a version of node or one of the dependencies is taken over by a potentially malicious actor. For this reason any JavaScript ecosystem based project must receive increased scrutiny for this type of stuff.

Now give me a golang library that hasn’t been touched in four years and it would be a completely different situation (knock on wood go2 doesn’t ruin this).

A significant issue though is that timezones change. For example the EU is ditching daylight savings time in 2021[1].

So actually there are many libraries and tools that could be done and just work forever, timezone stuff is much more dynamic than I'd ever realised.

FWIW I loved moment and made the move this year to date-fns[2] as I trusted browser availablity of the prerequisites enough to finally switch, and I do like working with it, but its focus on lightweight makes it less "magic" than Moment.

- [1] https://www.insider.com/europe-to-get-rid-of-daylight-saving...

- [2] https://date-fns.org/

(edit formatting)

EU ditching daylight savings time is unlikely to happen next year, as the legislation is only at draft stage and hasn't been finalised yet. The original proposal in 2018 called for it to end in 2019, but various industries pushed back saying that a transition would need more time. Because of Brexit (Ireland wants to use the same timezone as Northern Ireland, i.e. keep daylight savings time) and COVID-19 it's been delayed.

The article specifically states that they're going to keep Moment-Timezone up to date. Which is important, because the timezone database has changed approximately 4 times a year for the last 5 years (https://mm.icann.org/pipermail/tz-announce/).

Let's just hope no random country decides to use 100 minutes an hour or something one day.

> So actually there are many libraries and tools that could be done and just work forever, timezone stuff is much more dynamic than I'd ever realised.

I think the parent’s point was that things like security updates still need to happen. So there may be scrutiny if you come across a package and there hasn’t been a change for a couple of years, in the JS ecosystem it would raise red flags for many. Maybe not so much in the Go ecosystem.

Yeah, active development is always a good sign. These days at least NPM shows popularity, quality and maintenance data in search, and flags up known vulnerabilities so you can at least see if a project is rotten, or just no longer maintained (which may be ok in some circumstances).

Well, they do say: "We will release data updates for Moment-Timezone following IANA time zone database releases."

Precisely! Working with Erlang, I come across libraries that haven't been touched in years. Sometimes that means they're experimental projects that have been abandoned, but more often than not it means the're done. Complete. All bug fixed, all functionality implemented, stable, safe to use and unlikely to change. I'll take that any day over the twitchy, look-away-for-a-second-and-your-build-chain-is-broken JS way of things.

I think the only reason for a Go 2 would be to introduce breaking changes.

I disagree. Software can go into 'maintenance mode', that's fine, but there is otherwise no difference between done, abandoned and dead.

For a real example, look at lodash. You could easily argue it's 'done' and that it has better alternatives now, but look what happened: a security bug was discovered, the original author pretty much abandoned it, and it took about a week to figure out how to get a working build while meanwhile many thousands of other projects were failing due to npm audit checks.

The fact is even if nothing really needs to change in your project, the ecosystem around it can change requiring updates to your code.

It's fine to say "This project needs no new features and is in maintenance mode", but otherwise, if you're not willing to deploy new releases, "done", "dead" and "abandoned" all mean exactly the same thing.

> Open Source seems to have an irrational fear of done.

Older open source was more okay with this, but it's a huge issue with the modern JS/github model, where quality is measured by recent updates, "stars" within the last month etc.

I was about to write the same thing. I like "done". The best libraries are the ones in maintenance mode, with long-term stability goals. The worst libraries are ones where the author(s) do a Major Rewrite every year or two.

There is a widespread meme/trope about something being "dead". Whenever I hear someone saying that a language/library is "dead", I make a point of checking that person's credentials. It almost always turns out that these are not people who write big applications or well-known libraries, but rather ambulance chasers — constantly looking for the next shiny thing.

That would be fine if they didn't recommend not to use it for new projects.

> I wish the[re] was a way to fix this attitude.

This isn't a universal attitude. Numerous language ecosystems exist where it's completely normal to use dependencies that haven't been updated in a while _because_ they warrant no change.

This is a problem with the general attitude of the community of JavaScript developers.

And they're too stuck in their JS ecosystem bubble to realize this isn't necessarily "normal" or "the way things should/have to be."

I agree and unfortunately that attitude is spreading beyond the JS community.

A great example is the issue newcomers to Common Lisp face. I don't want to get in specifics regarding the Lisp community here but one common complaint is that only "old libraries" are available and no recent releases.

Side note: Although I'm not sure it initially started in the JS community, it is by far the most affected community. Besides that issue it also suffers from Not Invented Here syndrome.

"Done" as a goal would maybe mean "mature", "polished", "complete".

But in this case they also say they don't actually recommend Moment.js for new new projects, generally. "we would like to discourage Moment from being used in new projects going forward." In this case "done" also basically means "obsolete", "newer better alternatives exist".

That doesn't seem to be the kind of "finished" that you are talking about, or that would be a goal of developers. Or is it?

Examples of open source projects which are very popular, mature, not obsolete, still recommended by their maintainers for new projects -- but also "done" -- might be closer to what you are trying to compliment. They are definitely few and far between.

They seem to not recommend it solely because it doesn't support immutability or tree shaking.

Another important reason mentioned is that it includes heavy-weight internationalization locale files that are not needed in recent browsers -- "for the size alone." I don't know at what point the adjective "solely" stops being appropriate.

Those who have been developing it for years and are most familiar with it, and the alternatives, discourage it's use in new projects, although also outline the exceptions that in their opinion make it reasonable to keep using it. You are going to take a stand to disagree with them, based on superior understanding?

"You are going to take a stand to disagree with them, based on superior understanding?"

Uh, no. I read their list and the two things I cited (from their stated reasons) seemed to be the key drivers.

The issue is that this model of opensource is different than the Linux distribution model of opensource.

In the Linux distribution model, Debian, Red Hat, etc maintain older libraries in maintenance mode. Patching them for security or other less glamorous fixes and adjustments.

In the Github, NPM model of opensource, the original author also controls the default means of distribution. There is not 3rd party like Debian in the middle to maintain it when the original authors leave. So many thousands of projects will still point to an abandoned distribution channel as opposed to simply an abandoned project.

There are likely solutions, and this is not to say that the second model is better or worse. It is only to describe that it is not as simple as a project being considered "done".

Not adding new features might mean the project is "done" but not fixing bugs is an indication it is abandoned, and I have yet to find useful software that doesn't have bugs. And note that moment.js will continue to get bugfixes, just not new features.

You don't have to rewrite all software every 3 years. After 5 years without any major changes the software is stable, it has been battle tested, all issues and quirks are well known, features and designs has been discussed. It's now time for the software to pay off the development cost. And for a project like this - it's probably saves millions of man-hours every year, time that can be used for other things.

I completely agree.

It takes a lot of guts to make this kind of announcement. When faced with younger, faster competitors, it's natural to try and fight your corner. This is rarely good for a software project.

The devs have put their hands up and called it off. They can move on to more exciting projects. The rest of us can make better decisions now that the thinking behind this decision is out in the open.

Congrats, moment.js, on a great project!

Not only programmers, many of us tend to look at progress as an end in itself. Progress is the process of measuring if we achieve the objectives, it can not be the objective. Many times we do not achieve 100% of the objectives and that is fine, we need to consider the law of diminishing returns.

To some extent I don't think this means moment is dead although I don't assume a lot of new developers will be choosing it for their projects. Even starting a few years back I replaced it with Luxon and haven't looked back.

Is software ever really done, as long as it's not perfect (and perfection does not exist)? In fact, even Moment.js is not done. They say they will keep releasing security fixes and time zone updates. What if at some point they decide they won't even do that?

I am wary to use software that is not maintained, because bugs won't get fixed, and new requirements that will eventually arise won't get taken up. And usually at that point a competitor rises up and releases a better product.

It would seem to be quite easy to do something like:



https://img.shields.io/badge/Maintenance Level-Done-success

and have that as a convention.

Additionally to being easy to implement, it is literally a 3 second task for maintainers to add something like this into their Readme.

https://www.repostatus.org is a similar idea

That's a weird way to think about software. Every released version of every product is already "done". Once you take a dependency there is no obligation to keep updating it, no matter what features the maintainers may add to future versions.

In this case, considering the creators are discouraging people from using the package and explicitly saying there won't be future bug fixes, TZ/locale updates etc., it is pretty clear that done really means deprecated.

>I wish the was a way to fix this attitude.

I think the best way to fix this attitude is to have more examples of "done but not dead" projects in the wild. You can't blame people for assuming they're the same thing when in most cases they are.

> So that project maintainers didn’t need to write two page apologies

They don't need to write me an apology, but just a notice like this one is very nice so I can be sure what is up.

As Ajahn Brahm says: "What's done is finished!"

Done is fine. But Done is the first step to Dead.

Times change, and when open source software doesn't change with the times it becomes vulnerable for some newer, shinier, more intuitive thing to pop up and take over. Software simply isn't going to reach some "Done" state and then have people using it for 100 years with no changes. Pretty soon, no one uses the project that is "Done" anymore, because it's old and does things the old ways, and not long after that, it's "Dead".

Time to die.

I have no problem with a project being considered "complete", but the post also says "we would like to discourage Moment from being used in new projects going forward", which sounds more like "dead & done". :)

I think parent poster’s point was that dead should be considered done in this case instead of adding on more and more features and insisting on backwards compatibility until it ends up looking like modern C++. Dead isn’t necessarily bad.

> But it’s not. Because if you’re not adding new features and pushing code changes every day, your project is abandoned, dead. To quote another thread from two minutes ago: “I’m quite sad to see the end of Moment.js”

In this case, the reason why Moment.js is "dead" and not "done" is because it has fundamental flaws in its design: Mutable objects + huge bundle size which doesn't work well with tree-shaking.

Just because you disagree with a design decision doesn't change the done/dead debate. It's done, because its maintainers have agreed the project has gone as far as it needs to go, and its current iteration is stable. You (as always) can choose not to use a project you do not agree with; that has no bearing on the project's status.

This isn’t me disagreeing with the design decision, this was their own explanation for why you shouldn’t use Moment.js in the future.

My point was that the reason we’re transitioning away from it is because of technical reason, not because it’s not being updated.

I'd been complaining about these issues for years.

I kinda hate being vindicated years later, the time in between as an outsider kinda frustrates me.

I wish we had a more thoughtful, less packrat culture in programming. Fighting off the pushback is exhausting. It's not even worth bringing things up most of the time.

And as a disclaimer to those feeling tempted, I've got zero interest in debating this reality, water is wet.

It's the same in all human culture and politics. Every era's mainstream ridicules and dismisses those who criticize it as "extremists". But some of those extremists will one day be vindicated as being on the right side of history long before everyone else came around, and we will look back at that prior mainstream attitude and ask, "How could they be so blind?"

The important thing to keep in mind that we don't know which of today's counter-culture takes will end up winning (I don't say "being right" because cultural evolution is, like biological evolution, not teleological).

In other words, you had a belief, and in hindsight you were "vindicated". But there were many others who had equally strong beliefs that were not.

Their point of view seems kind of right to me in that they may be suboptimal design decisions in hindsight, but changing them now will break all existing integrators. If you're going to break everyone anyways, might as well switch to a whole different library, or alternatively give the redone version a new name so nobody assumes you can just upgrade it and it'll be fine.

The basis of my complaint is that some things are well designed, others are just nicely documented.

moment has a, to me, counterintuitive "hidden" type system that is a different-kind-of-menacing. In code I've had to review and maintain, the moment parts or more than often a soupy mess of the previous coders in combat with the nuanced hairy complexities of the library as opposed to straightforward execution of the api (compare to say, jquery, where setting all architectural disagreements aside, there's no substantial evidence of frequent "programmer struggle" in the codebases using it)

This leads to poor long-term maintainability as the code passes through many hands over the years.

If, after a year or two of average "blue collared" programmers touching a codebase it gets so convoluted that you generally need to abandon it, then fundamentally you are using poorly designed tools.

Again, we all only have our own personal lived experiences to make such assessments on, and I way too often end up "debating" what mostly amounts to my work history of parachuting in and rescuing code (it's a psychiatric problem I have) so the pessimistic aspects become quite sharp to me.

If you fundamentally and incompatibly change it's design then it's an entirely new product. Calling that "Moment Version 3" doesn't mean anything.

Brand value is huge. I would trust moment 3 lot more than project I never heard of . I would trust a new projects by core authors of moment almost as much too.[1]

Trust is major factor when depending on third party libraries especially in the JS ecosystem.

[1] reason libre office or deno gains traction

Ha-ha, oh dear. From your lips to gulp's (and other "bump major at tuesday" projects) ears.

Huge bundle sizes and mutability are JS design flaws.

Until very recently it was impossible to make objects immutable in JS. Even now its really only done using third party libraries.

Huge bundle size is only a problem because tree shaking is done on a "module" level. Most languages are static enough that it's called dead code elimination and doesn't need to use tree pruning. You can tell statically that the code is not used.

Moment isn't compatible with modern workarounds which I don't blame it for. The way JS is, immutability and true dead code elimination will probably show up as built in features in a few years and make all this obsolete again

> Until very recently it was impossible to make objects immutable in JS. Even now its really only done using third party libraries.

There's a big difference between "literally impossible to mutate" (only important in the most security-critical contexts) and "designed around immutability as the default" (which is what is desired in most of the real world.)

The former not being possible is not a reason to exclude the latter.

With JS, until recently, it was nearly impossible to design immutable API's. Everything takes JSON based objects which have no field accessors. All the objects underneath are just hashmaps with string keys.

When all your objects are hashmaps you can't really make fields immutable. Even if you wrote getters, someone can just reassign the function reference.

Even if you check your fields in incoming object parameters, somebody can randomly add more fields that you don't know about. Until recently you couldn't stop people from randomly adding fields to your objects

Nowadays JS supports stuff like freeze thaw which makes it easier

You didn't have language enforced immutability. But you still could have convention enforced immutability. If you don't provide apis that mutate your objects and document that mutating is not supported, you get almost all of the benefits of immutability.

Object.freeze() has been available since IE 9, Firefox 4, Chrome 6 etc. Not really "recently" in web terms.

You can mess with private fields with reflection in other languages too. If someone's bent on bypassing your API you're not going to stop them.

I don't think mutability is JS design flaw. It was designed for manipulating UI - computer screen, which is mutable. If it was designed for printing (an immutable interface) i'd agree with you. Bigger problem is that people started using javascript for server side, for which is (was) totally unfit for.

> I don't think mutability is JS design flaw. It was designed for manipulating UI - computer screen, which is mutable.

You don't need, or particularly benefit from, language-level mutability to specify the next state of UI as a function of previous state plus new inputs, which is really the best way to model interactivity.

JS just has a very simple, flawed design. It's still a rather bad language from a design perspective.

One of the shortcuts is that all objects are hashmaps. Fully mutable hashmaps with string keys. You can do this:

obj.prop = "hi"; obj["prop"] = "bye";

And you set the same field. And you can do that to any object, reassigning any field type.

Most languages have static number of fields in an object, or at least static types for fields already created.

Another huge shortcoming is prototype chain based inheritance. Someone can rewrite a random link in your chain and suddenly you have another object type entirely. It's also very bad for performance. Essentially, the inheritance tree of an object can change at runtime.

These are more like footguns for beginners than intractable obstacles. For example, you can avoid the issues in your comment with static analysis (Typescript). And the Javascript professional just avoids things like arbitrary obj[prop] and prototype chain hacking.

And since they aren't intractable, and smart people regularly decide that it's worth the downsides, you're making the uninteresting observation that $lang has warts.

javascript gets a lot of heat from folks wishing it was a different language. It's just different, works differently, does things atypical of most languages. You can fight it or learn it.

A big "Thank you!" to the developers of Moment.js. For the last 8 years or so it has always been the first library I included in any new JS-project.

I didn't even bother looking for alternatives, so I didn't know about Intl, Luxon & day.js until today.

The size of the library has always been one of these things where I thought that the benefits outweigh the costs, and I knew that it wouldn't be like this forever. To me, this time in the future has come now, and I will switch to day.js (or Luxon, day.js has its size on its side, but I still need to compare).

No other library has filled a huge gap in JavaScript like Moment.js did for so many years.

On a note aside: I wish HTML had a <time>-tag, so we could also settle the timezone problem in publications like rocket launches or starting times of keynotes once and for all, where the publisher would use something like <time tz="Europe/Berlin">2020-09-15 10:26:48</time> and the browser would show it to the reader in the reader's local timezone.

> On a note aside: I wish HTML had a <time>-tag, so we could also settle the timezone problem in publications like rocket launches or starting times of keynotes once and for all, where the publisher would use something like <time tz="Europe/Berlin">2020-09-15 10:26:48</time> and the browser would show it to the reader in the reader's local timezone.

While the browser won't convert it automatically, this is what the HTML <time>⁰ tag is for. The publisher can use <time datetime="2020-09-15T10:26:48+2">2020-09-15 10:26:48</time> and include a script which will read the datetime attribute and convert it to the browser's local time zone.


     No other library has filled a huge gap in JavaScript like Moment.js did for so many years.
I might say jQuery... which is mighty fine company to be included with!

HTML5 does have a <time>-tag, but browsers don't render times in local time, you need JavaScript for that.

TIL: Intl.DateTimeFormat [1] has good browser support [2] and allows for nifty tricks like

  > new Intl.DateTimeFormat('zh', { hour: 'numeric' }).format(new Date)
  < "下午11时"
[1]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... "MDN: Intl.DateTimeFormat"

[2]: https://caniuse.com/mdn-javascript_builtins_intl_datetimefor... "Can I Use: Intl.DateTimeFormat"

The whole Intl namespace is a godsend.

Until you start seeing times like 24:45 in your app. The spec has some really strange behaviour in it that defaults to "1-24"-hour time instead of the common "0-23" if you specify hour12: false.

Only Chrome seems to have actually implemented the spec this strictly, they don't want to change it: https://bugs.chromium.org/p/chromium/issues/detail?id=104579...

It isn't the pure javascript feeling without a few cross-browser quirks.

Not sure if this is a stupid suggestion, but could there be a drop-in replacement for moment which uses Intl and other modern browser APIs, otherwise fetches the full moment.js? Or does MomentJS already do that?

Pretty reasonable stance, all in all. Modern practices have changed, and favoring not breaking huge chunks of the existing web chasing new usages (that may already be accomplished well by other libraries) is a reasonable and professional stance.

I don't know if the Moment.js folks are reading this, but THANK YOU for your commitment to stability and security fixes.

Not all of us are in a situation where we're iterating through the JavaScript new hotness every couple years and still have significant legacy systems to maintain and support.

Yes, and you're welcome.

Thank you.

I pulled in moment.js 5 years ago for a suite of state death and birth certificate registration apps we are working on.

Due to the amount of “business logic” and small staff size on these, they take years to roll out. I appreciate that this library will “hold still” for a few years.

Not all of us are churning out a new e-commerce app every 3 months. E.g. we replaced the birth certificate app from the 80s, and I expect some version of our app to be around for at least a decade, albeit with patches for new browsers on the front end and new Java app servers on the back end.

Please pardon this drive-by assessment of JS calendar libraries by a casual user.

moment.js: Mutable. Thank you, next.

Luxon: Takes the effort to implement `Interval`, which would be `Range<DateTime>` in any proper language, but somehow avoids providing separate `Date` and `Time` objects.

Day.js: When you kinda like moment.js, but your bundler says it's too fat.

date-fns: The finest of pure, curry-able functions over the minefield that is Javascript's `Date` object.

js-joda: If Javascript didn't have classes already, this project would probably port the entire Java runtime to JS just to replicate them. Likely the most correct handling of date/time stuff available for the browser, but damn, at what cost?


Edit: this turned out way too negative, my bad. All I wanted was a library that offered:

0) Type definitions.

1) Immutable classes of `Date` (year, month, day), `Time` (hour, minute, etc), `DateTime` (the prior two combined), `Instant` (for a certain moment on the global timeline), and `Duration`.

1b) `DateTime` should probably be split into two separate things, one of which is aware of time zones.

2) All the obvious date arithmetic functions - duration between dates, adding/subtracting durations, etc etc.

Hi. You seem to be asking for Temporal. It's coming, we hope! https://tc39.es/proposal-temporal/docs/index.html

Yes, thank you! I've seen this before and forgot. Looks like it's at Stage 2 right now, so still a ways to go until shipping, but should resolve all my gripes when it does.

Can you explain why you find mutability to be a showstopper? Is this a front end developer thing?

I like my consts and all where relevant, but I don't see why mutability is such a problem. Javascript is an imperative language where almost everything more complicated than a number is mutable. I see the lack of creating copies of objects with every operation as a benefit because of the RAM and CPU cycles it saves.

Is it because the API returns a reference to an object as well as updating said object? That's the API I'd expect, personally; if I want to do an addition of 1 to i, I'd write i += 1 and expect i to have incremented. I don't see why moment.add() should behave differently?

Basically, unexpected behavior. One of the "footguns" is that it's easy to write to a Moment object when you mean to be reading from it. And by the way, you can mutate objects declared with `const` in JS - you just can't reassign them.

I don't view the mutability of moment as a complete show stopper, though. If you limit the surface area of the mutability by hiding the underlying moment object within an abstraction, then you can at the very least keep the chances of misusing moment to a minimum.

I also think it's not a showstopper for Node.js apps. For bundling in a front-end app it's waaaay too big.

The moment locales webpack plugin goes a very long way toward dealing with the size downside of the library.

That said, we wouldn't be in this position if more companies used a shared CDN for libraries instead of always bundling them.

> shared CDN

That helps with transfer but clients still have to parse and execute the javascript which can be significant, especially on mobile devices.

It's very unpractical and error prone.

You call a function that requires a date (moment) object, and after the call you want to do something else with that date. Was it modified? Who knows. You will have to clone it before calling the aforementioned function. Otherwise, bugs.

You write a function that expects a date (moment) object. You want a different date (say "the day after"). If you call a method on the object, will the parent be smart enough not to touch anymore the date? You can't know that, so you will have to (remember to) start by cloning the date. Otherwise, bugs

Treating it as a dealbreaker seems a bit strong, but immutability has become very popular among JS devs recently. JS has pretty respectable functional-programming features, libraries like Immutable.js have cropped up to add memory-saving immutable data structures, and major frameworks like React and Redux play much more naturally with immutable data than mutable. The overall goal is scalability through reduction of side-effects. Whether the trade off is worth it or not, it's absolutely the fashion right now.

Others have already covered it, but it's mostly about limiting things that can go wrong. The single-threaded nature of JavaScript means data races are not an issue, but you can still get situations where a local variable (whether `const` or not) is mutated without it being obvious.

I see your concerns about performance, but 1) temporal objects are so small that there are plenty of optimization opportunities for the JS engines to eliminate or greatly reduce allocations.

2) The larger and older your project, and the more people are working on it (including authors of third-party dependencies), the murkier data ownership becomes. With that you are more likely to slip into defensive programming practices. "I have a `Date` object that is someone's birthday, but I need to pass it to multiple functions and then serialize it to storage. But I can't tell for sure what those functions are doing with that value. Should I serialize the date right away and persist that value later? Should I just create copies of the object to pass to the functions?"

But birthdays don't mutate, so now you're worrying about a thing that shouldn't be an issue! In the unlikely case that someone's birthday date is corrected, May 9th doesn't suddenly turn into July 15th. In the real world you don't drag the red circle drawn in marker on a paper calendar with your finger from one cell to another, or white out the day number and write in another one. You cross the old circle off and draw a new one in the right place.

My background is in backend services, hundreds of threads running on dozens of cores. The peace of mind that comes with being able to pass values to async functions and thread pool executors, and knowing that they won't turn into a pumpkin at midnight is a very real thing. There's a performance price to pay, sure, but it's so tiny compared to the wins in development and debugging times. And in the particular case of date/time objects, most things are around 8-16 bytes anyway so it ends up not mattering much.

Tangent: this is the fear that Rust talks about in its value proposition btw. Technically, everything is mutable in Rust. You can flip a bit in an integer that is passed to a function from inside that function if you want. But the difference is that you have control over who gets to do that, and you have visual cues in the code (the `mut` keyword), and you have assurances from the compiler that the rules are followed. One owner at a time. Many can look, but not while a value is modified. Best of both worlds. The end result is that it never bothered me that `Date` is mutable in Rust. Either I'm the owner, or I borrowed the value to look at it, or I borrowed it for mutation and have the guarantees that 1) nobody else is doing the same; and 2) nobody will see in-progress modifications until I'm done.

"moment.js: Mutable. Thank you, next."

Mutable is not bad, buddy. You live in mutable world.

False comparison. We're not creating a copy of the mutable world, we're writing software. Pretty different. Good luck programming in DNA or whatever and knowing that your code does what you want it to do.

Mutability, in this case, can be pretty unexpected.

Just like you don't expect the expression a + 5 to change the value of a but to return a new number, most people don't expect myDate.add(5, 'days') to change the value of myDate.

I know that moment values are mutable, yet I often forget it while writing code and make dangerous mistakes because of how unnatural it is to see an arithmetic expression that is not immutable.

That's totally expected behavior to me.

I would expect to use something like Moment.addDate(date1, 5, 'days') if I wanted a new instance of a date to be returned.

Even in javascript-land, methods like that will have side-effects, yet still return this often just for the sake of method chaining. E.g. date.add(5, 'days).format("%Y-%m-%d") would mutate date, but return the same instance as a convenience.

No I don't. I live in an immutable, four-dimensional world /s

These are all just models of the real world, not the reality. The real world can be modeled equally accurately as mutable or immutable, it just depends which properties of the real world you care about modeling.

Mutable is not bad when necessary, but otherwise I'd say that immutable is generally quite good.

> 1b) `DateTime` should probably be split into two separate things, one of which is aware of time zones.

due to daylight saving timezones depend on the date, which makes it hard to separate date and time

You're right! I should have phrased that better. I didn't mean splitting `DateTime` into timezone-aware `Date` and `Time`. I meant two different `DateTime`s.

Sometimes you need "Wake me up on December 24th at 10:00, regardless of where I am that day", and sometimes you want "The match will start on May 1st at 21:00 British Standard Time, and I want to be alerted about this even if I'm in New Zealand at that moment."

What I meant is a distinction between a `LocalDateTime` (first example, timezone is not relevant) and a `ZonedDateTime` (second example). The latter is very close to `Instant`, which is a point on the UTC timescale, but the subtle difference is that if timezone definitions were to change - as they often do - the `ZonedDateTime` would correctly remap to the actual `Instant` when the event was happening.

> `DateTime` should probably be split...


Anyone has an idea for a solid module that supports representations of sub-millisecond precision (preferrably ns but at least us)?

> moment.js: Mutable. Thank you, next.

A petty, thoughtless dismissal that reflects more on the one saying it than the library.

I wish more software/libraries would mark themselves as "Done" instead of sending one update every week and a ui refresh every 6 months. Software engineering is the only field where we keep building a single thing forever until it becomes a hot mess.

It really isn't "done" if you tell people they probably should look at alternatives instead. Sounds more like a soft deprecation to me.

But regardless of semantics, they're being transparent on the project's status.

It "done" really, and I can use it today knowing its pros and cons. It would be "dead" if it had a glaring flaw which couldn't be fixed (which I don't think mutability is)

Every project has cons and they should embrace it and call it out like this project did instead of forever targeting a perfect library but nothing is perfect. It serves its purpose.

I am not sure if they are telling people not use it just because chrome now says to exclude it or they came up with it independently.

> I am not sure if they are telling people not use it just because chrome now says to exclude it or they came up with it independently.

Independent. The maintainers have been recommending other alternatives (like Luxon) long before Chrome started to advise users on it. Moment has been in maintenance mode for a while now, this is just an updated confirmation of the fact, I'm guessing because users kept asking.

We (the Moment maintainers) have been saying it anecdotally for quite some time. In our respective podcasts, talks, Stack Overflow comments, etc. The Chrome thing simply encouraged us to make it an official position.

I am very emotionally confused, as I feel this is a huge step forward for open source.

More code should be done. More developers just need to know how to quit the project when the time is right.

This is weird to say, but this is strong leadership.

This is exactly that: Strong, humble, responsible, positive and encouraging leadership and guidance.

I remember request.js being "done" as of late.

There can be a surprisingly looooooooooong tail for retired open source stuff.

I retired https://pypi.org/project/setuptools-pep8/ in 2013 but I still periodically check in on it since even today it gets 1.5k downloads per month https://pypistats.org/packages/setuptools-pep8

This might be an even better reason to use it. It's purely in bug fixing and maintenance mode at this point. Which means for projects it will probably be super stable and won't change too much. This by itself is really valuable.

I don't see this tiny upside outweighing the many deal-breaking downsides of moment.js. Especially since Luxon is already incredibly stable.

Besides, this announcement probably makes moment.js less stable than it was previously, since the web will continue to change but it won't change with it.

> We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.

Honestly, I wish more js libraries would be that way. I’ve used date-fns in a small part of an app, so of course when I return to it in several months, date-fns released a fully incompatible new major version.

sure, annoying but they did bump to v2, nothing is stopping you from continuing to use the older version if it works for you.

Makes sense. Similar thing with 'request' awhile back.

I mean, you can see that even in the high-tech realm, it takes years for obsolescence to be acknowledged. But at least it does eventually happen.

I actually think that a lot of the problems that our society has in general is because we take too many decades to move on from obsolete ways of doing things.

What we need is for other core assumptions or technologies in our society to be able to upgraded. For examples: roads, cars, cities, government, money. I truly believe that all of those fundamental structures are often stuck in outdated forms that are holding us back.

This should be a reason to use moment.js more, not less. It’s done, so it will not change under you, and you won’t have to rewrite your app.

Could you not just say the same about using LTS versions?

LTS in js-world is usually something like "we support it for about three months, maybe six".

And if within that period they release an incompatible version, your upgrade path is worse, beacause your version is too old.

I worked extensively with Luxon (a sibling project leveraging modern js constructs) and found it to be really great! I’m really happy with their approach of creating an entirely new project to embody the API and new features you might expect in newer release of moment. It allowed Luxon to mature for several years without the weight of supporting the legacy api and avoided confusion within the community. The direction for moment seems completely reasonable.


> Ideas in Luxon

> Luxon is built around a few core ideas:

> * Keep the basic chainable date wrapper idea from Moment. Make all the types immutable. Make the API explicit; different methods do different things and have well-defined options.

> * Use the Intl API to provide internationalization, including token parsing. Fall back to English if the browser doesn't support those APIs.

> * Abuse the Intl API horribly to provide time zone support. Only possible for modern browsers.

> * Provide more comprehensive duration support.

> * Directly provide interval support.

> * Write inline docs for everything.


Dropped using Luxon when I couldn't easily chain like moment.js.

moment.js's API is intuitive and I have been using Dayjs and it has been doing great.

When you say chain, do you mean mutate the object as you call methods?


For me that was one of the really desirable features.

Been a happy user for years, will continue to be. It works, it's battle tested, and powers many of my apps just fine.

Our favorite bug for newbies using moment.js:

  const somedate = moment(...somedate...);
  const oneMonthLater = somedate.add(1, 'M');
  const dateToCheck = ...; // between somedate and somedate + 1 month

  if (dateToCheck.isBetween(somedate, oneMonthLater)) {
    // do something
The puzzled looks when the tests fail. I'll miss that. Seriously.

Just to confirm that I remember Moment correctly, the code in the if statement never runs because .add mutates somedate, so somedate and oneMonthLater are the same, correct?

Yes, `somedate` is mutable.

Gotta love immutables after that...

Yes, it bit me once

Request came to my mind after reading this. They also became de-facto standard and then technology improvements made them less relevant.

Main technological advancements that are breaking old monolithic libraries are, 1. async/await along with promises 2. Need for smaller footprint. Compile to what is needed not this is what I all got. I think, lodash done that to underscore.js at one time. 3. Typing support with libraries for runtime type safety. It's not breaking existing but new typescript, flow, etc projects opt for newer libraries with typing support.

Shouldn't software strive to perfection when done (like, say, LaTeX) rather than being obsolete when not anymore maintained?

Some software exists to "bridge the gap" for deficiencies in other areas of the software ecosystem. Javascript date api really sucked from 2002-at least 2016 (arguably still does? haven't really followed) and so these libraries come in to close the gap. Similar to JQuery.

Moment can be thought of as an instance (or build) of the iterative development of a strong usable, robust and bug free javascript api for dates. It's just that moment is the major release version that is still extremely popular but is a dead end in terms of design. Eventually the end goal is a solid, community agreed upon standard lib and in between versions (moment in this case) should be obsoleted while also not breaking existing code bases.

But read the attached article, it does a much better job of explaining than I do.

As the author says, the library caters to a language that is no longer in use - aka. javascript 2010 - and keeping up with the evolution of javascript would be making breaking changes, which have been accomplished by other projects by now. What would be the point?

I've been a happy date-fns user for a long time. Recently I started a project that heavily uses time zone conversions and date-fns-tz falls short. It does work 99% of the time. It's not maintained by the core devs. The APIs aren't very intuitive. If I'm starting a new project I'd like to give Luxon a try.

I guess this post motivated me to finally try Luxon (I didn't evaluate the other alternatives) and I migrated the frontend of a side-project from Moment.js.

https://moment.github.io/luxon/docs/manual/moment.html helps getting up to speed.

I was doing mostly basic things and it has been straightforward (note that I don't have tests): https://github.com/conradfr/ProgRadio/commit/d52d9aed219281f...

edit: halved my app.js' size (before gzip).

edit2: Needed a new polyfill for timezones on IE11

I wish more projects chose stability over features. Every single week, I see 10s of updates (which I don't care about) when installing node packages.

Pretty sad- I've used moment in 50+ projects. That said, it's a very respectable and thoughtful resolution. Thanks to the moment team.

I'm a big fan of Luxon and have been using it lately.

I thought there would be more discussion here surrounding the recent update to Lighthouse, whereby it warns you if you're using Moment.js and suggests alternatives.

There was some back-and-forth about this on Twitter the other day:


Got a "This is not available to you", which confused me since I don't even have a twitter account. Turns out this just the new form of Twitter's "Links with referrers stop working the first time"

Moment's API makes it a source for subtle bugs. In particular, the conflation of dates, times, and datetimes as a single structure. This damage goes beyond the lib, into ones it's influenced, like Arrow in Python.

I'd love to see something like Rust's Chrono ported to JS via WASM. In a TS project I did a few years ago, I had to roll my own DT lib.

It is not easy to replace moment.js since many libraries like react-dates rely on momentjs. Hope they have plan to replace it.

These kind of dependencies is one of the reasons I prefer to avoid react-* libraries.

It would be nice to see more flexible dependencies in such libs for example like material-ui pickers [0] which let’s you bring your own date/time lib.

[0] https://material-ui-pickers.dev/getting-started/installation

All the date libraries have different APIs. The only one that is currently standard (the Date object) is full of footguns and hard to use.

You either ship without any date support at all or you pick a library and go. Very little comes close to Moment for i18n and timezone support, so lots of libraries go with that.

The Temporal proposal to replace Date can't happen fast enough.

Hell yes. I wish more projects would open to the idea of “moving over” when they’re done. Most developers have this idea that if they add an “alternatives” section to their Readme they’re losing something.

Moment’s developers realized that their job is done and that there are potentially better solutions now.

How refreshing is that?

The longer I code the more I value stability. That is not to say that stuff like immutability doesn't impress me -- I certainly do prefer an immutable data type for things like dates, strings, vectors, etc.

But as long as the API doesn't completely suck, that stuff is worth less to me than stability. Updating libraries, especially in the world of JS, is always a fingers crossed moment hoping nothing will break. As long as there are no security flaws I am happier with no updates than with continual nice-to-have additions and changes to the API -- especially if those nice-to-haves come with opinionated deprecations to the "old and busted" way of doing things.

I've got the opposite complaint: Don't force your immutability on me. Immutability is not a virtue, it is a tradeoff. I can deal with mutability far better than the tons of allocations you're doing behind my back.

Someone recently added moment to our project to parse some dates. More recently, I decided to use it to parse and format some dates somewhere else, and I immediately got flak for it.

This is, all I need moment for, is simple date.formatAs('DD-MM-YYYY') and date.parse(date, 'YYYY-MM-DD') stuff. moment is overkill for that, but js Date somehow doesn't do it. It would probably be quicker to write one myself than to find a library that does just that.

That's what Intl.DateTimeFormat is for.

    var options = { year: 'numeric', month: '2-digit', day: '2-digit'};
    console.log(new Intl.DateTimeFormat('te-IN', options).format(new Date()));
    // outputs 16-09-2020

Not as far as I can tell. It just formats it according to a locale, not according to a format string. SimpleDateFormat for javascript[0] looks more like what I need. Locales are exactly the thing I don't need.

[0] https://github.com/noahcooper/SimpleDateFormatJS

Why use a whole freaking library instead of just writing a one-line function?

Because I'd have to write a lot of variations of that one-line function to handle different date format variations from various systems.

I'll consider this my yearly reminder to check my user share on iOS Safari; once I have no version 10 users, off to Luxon it is.

So long, moment, and thanks for all the fish!

Protocol dictates they now delete it from NPM without warning.

I know NPM and/or Yarn now shows warnings on install, some libraries flag up as being obsolete or unmaintained (in the form of a message from the developer); I hope Moment sets that up as well, and makes sure they add big warnings on the website as well.

I too stuck with Moment for longer than I should have because of inertia and familiarity.

I see that immutability is major concern for backward incompatibility, however over years I've become so much used to moment js that I wish I can still use their API's. Can someone explain why is it so hard to release a completely new version that isn't backward compatible? We could as well use different naming so that it doesn't conflict with last versions. moment3().now()

That’s effective what day.js is. Its effectively an identical api and is incredibly lightweight in comparison with opt-in extensions.

I think the suggestion is just use Luxon - the apis are a bit different but there isn't really need for another library

Time and Dates are incredibly hard, so thank you Moment.js team for the painkillers you have provided to JS community.

I found myself always starting with native Date library, then eventually adding Moment.js when we needed to robustly support timezones and timezone conversions.

Nothing like receiving a text at 5am pacific, because the system is calibrated to Eastern Timezone work hours.

I've used moment in many of my projects. Though they're able to be migrated into new libraries, I haven't found alternative that use moment.js's date format notation. Are there any alternative that use it?

Many UI libraries use that format so using different libraries with different notation will be harder to manage for me.

Moment made up its tokens as it went along. Some match other languages, several do not.

The only real "standard" in this area is LDML tokens, which are part of CLDR. Luxon follows those.

It's been common knowledge in the front end development community for quite a while now to avoid Moment.js due to it's file size. Glad to see the maintainers agree. I'm thankful for the work they did in progressing date/time management libraries as a whole, but just like jQuery there's now better alternatives.

End of an era for JS developers. It's been an incredibly useful library. The amount of projects I've used Moment.JS on... And I'll be somewhat glad to never use it again. Javascript really needs a better native Date/Time API.

Another JS dependency I didn't quite get around to using before its status changed in a way that greatly alters the calculus of choosing whether to use it.

... and folks kept telling me I was wasting time writing my own time and date stuff in JS.

Been using date-fns. It's good. I am happy moment recognized that their time is better spent on other frameworks.

It did the job well and now time to move on. Why save something when another thing already does it and so well.

Although I understand the reasoning in their post, I'm quite sad to see the end of Moment.js.

In my experience, it works reliably and easily. I've never had issues with it, and it does a fantastic job for a pretty big range of requirements.

Maybe react-dates from Airbnb will move away finally


could someone take the time and explain to a moron like me why the mutability of moment is bad? i just don't get it. moment has always been my goto library for dealing with dates in javascript.

OK, let me try.

Most software has "reference types", like a customer. A customer is mutable; for example their name can change for a variety of reasons, their shipping address can change etc.

And then there are "value types", like integers or strings. The integer 42 can never change to be any other value.

If your customer lives in Rando Street no 42, and moves to Rando Street 41, you don't change the integer (value type) 42 to 41, you set `custtomer.address.house_number` to the new integer 41. If any other code referenced the number 42, it still has number 42 stored.

Now, many people argue that a moment in time (like timestamp/datetime) is usually better modeled as a value type. If you have two references to one moment, you can rely on the fact that nobody else can modify that moment after the fact.

This is usually safer, since it makes the case of accidentally over-shared objects a non-problem, though possibly a little bit less performant (since all "modifications" must create new copies).

Disclaimer: I too use moment in my daily project

Example snippet (CMIIW, it's as I remembered):

    let date1 = moment("2020-01-01");
    let date2 = date1.add(2, "days");
    console.log(date1.format("YYYY-MM-DD")); // 2020-01-03
    date2.add(2, "days");
    console.log(date1.format("YYYY-MM-DD")); // 2020-01-05
Usually the date1.add operation won't change the date1 value, and any operation to date2 won't change date1, but it isn't. It's made worse because people like to return moment object outside function scope, so operation outside can modify the object inside and weird bugs happen.

It's actually a manageable problem IF you know the behavior, and only using moment object reference inside scope, and using immutable objects as parameter / return, such as milliseconds timestamp and js date.

I've used Moment a million times ago.

Love the work your team has done, best of wishes!

Ah, the nostalgia. Thank you for saving me so many times from dealing with DateTime APIs and making my projects that much the faster, Moment.js! It's great to see it in done state!

It is done, but not dead? to me that sounds like a contradiction given that there is always a need for security patches and also given the limitations mentioned such as improving bundle size.

As per the post:

"We will address critical security concerns as they arise."

Perhaps a better term than "done" is "feature complete".

Super excited about this. It's going to be a slow transition moving off but our bundle sizes are going to drop dramatically. Definitely love the idea of making our I18N work easier.

Thank you to the Moment.js project and all the developers who worked on it. I’ve used it in many projects and it’s always been great to use. Thanks for all the work you all put in :)

It is the fate of a truly great library is that its benefits are so undeniable that they will eventually be absorbed into the standard thus making the library itself obsolete.

Thank you momentjs developers, as well as the time others have taken over the years answering my boring questions about time. All the best.

I plan for “done.” I remember taking a project management course, where the instructor kept using the phrase “What does ‘done’ look like?” I also worked with a manager that declared "The #1 feature of a project is 'Ship.'”

Every project that I do; even experimental and “unending” projects are done as “ship-quality.” This is because I often revisit previous work, looking for snippets. If they are already at “ship” quality, then that’s one less problem.

I’m also a grizzled veteran of “the prototype becomes the product.” That’s something that many of us have experienced. It sucks, but it’s real. If the prototype is already “ship-quality,” then that’s one less problem.

I tend to tag ongoing projects, so the head may be dynamic, but cloning a tag will generate a stable release, or branch point. That’s a fairly typical Git workflow. I’m not a fan of too many branches. I used the Mainline Model (a Perforce pattern) for years, but I like no more than two branches, these days (dev and master, and sometimes, dev can be in a private repo, squashing to master). Often, I only have one branch. If I create a branch (like a retrospective fix to a release tag), I merge that branch back into master, or apply the same fix to master (not my preferred pattern). I will, occasionally, create experimental or exploratory branches, which are short-lived, and designed to be reintegrated with master. Again, not a unique workflow. This will be familiar to many folks.

So, lots of “done,” as mileposts on a continuum. In some cases (like when I am preparing course materials), I may do a lot of work in a dev branch, and squash over to master, in order to reduce the “noise” in master, but the “done bits” are always tags in master. I always reintegrate back to dev, so the branches remain in sync, and the tags propagate to dev.

One exception to the “continuum model,” is that fix tags may be in small, short-lived branches. If possible, I try to add the tag to master, at the reintegration point, but that isn’t always practical or safe, especially if I can’t actually reintegrate, but have to introduce the fix as new code, down the road.

Since I have started using the Swift Package Manager, this has been a good fit. I believe that many package managers rely on that pattern, so I don’t think the way that I work is especially creative or standout. Pretty much garden-variety configuration management.

Speaking of package managers, I often extract subprojects from my work in the master branch, as I progress, spinning them off as standalone package projects, with their own project lifecycle, and reintroduce them as dependencies. This gives me little pockets of “done,” that have encapsulated state and identity (and their own repo), along with focused testing. Each project I spin off, is one less thing to worry about, and another tool on the pegboard, for future projects.

So, in my case, “done” is really just a signpost along the road, but there can be many signposts.

Just want to plug Luxon, it's pretty great.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact