Meta Is Transferring Jest to the OpenJS Foundation
engineering.fb.com
engineering.fb.com
Meta created Jest and a lot of the features that it's known for, but it's true that it hasn't been invested in for a few years and most of the recent features were created by the community.
With this move, Meta is showing their commitment to Open Source and Jest will be able to grow with ownership through the OpenJS Foundation led by the Jest core team and the Jest community.
And it's a shame. I wish there were more of these big companies that would just, idk, pay an organization like Apache or in this case OpenJS so that they can operate as a software development and open source stewardship company, pay people to work and manage these projects.
Sending it off to the Apache foundation in this state to me sends a signal that it's good enough, innovation is no longer required, and therefore is not worth the investment to continue to maintain.
The former is table stakes if it has any chance of displacing test frameworks which are already widely used for both server and client code. I would be shocked if it’s an issue though, there’s very little to gain from coupling a test framework to Node specifics (its own non-test APIs, V8 bindings, NAPI, etc) unless you’re heavily invested in that focus. (I say this as someone who’s worked on such a project off and on for a while, and even then the primary motivation is to make testing itself more portable without sacrificing performance or tooling.)
The latter—attractiveness as a low level API to build on—remains to be seen. This is something Node generally does well with its novel APIs. But it’s a very crowded space already. And from what I’ve seen looking at the APIs, they don’t offer a whole lot more than basic correctness that can be skipped to quickly prototype and iterate abstraction ideas.
Otherwise it’ll be a reasonable default for very Node-specific greenfield projects. Which is welcome! But it’s also a somewhat niche audience. Portability is going to matter to almost all Node users already, and abstraction will matter to a largely overlapping segment of users who are accustomed to a much richer set of built in and extensible testing semantics.
I don’t want to dismiss the effort or its prospects outright! I just think it’s become increasingly clear that Node’s influence relative to the JS ecosystem is shrinking as the diversity of runtimes increases and as compatibility between them becomes more important.
What's the status of Rome? Is that being looked at as a long term replacement?
On one hand, I would absolutely hate for someone to force me to use one tools, opinions for everything I do in a project.
On the other hand, if I just start a new job and I need to get producing, I'd rather have one big tool that just makes JavaScript work. Versus 4 different tools with a bunch of different limitations.
I've recently started experimenting with Vitest on a new webapp using Vite/React. It's API compatible with Jest, but integrates with your existing build tool-chain instead of forcing you to configure a parallel one. So far, there's a lot to like. https://vitest.dev/
The `--ui` flag showing a visualization of the dependency graph of a test is probably my favorite little feature.
It's also nice if you're running a "vite stack", you don't have to pull in babel and a bunch of other libs just to make Jest work.
Anyway as just the one developer on this project, I don't see the value in writing unit tests for every one of my components. They just work, I'll leave them alone for a few years until someone else builds a new UI.
It's not just the fact that jsdom doesn't fully support all browser APIs, but components are building blocks for a primarily visual medium, so being able to build and debug my component tests visually has been a complete game changer when it comes to productivity.
I think the very reasonable counterpoint to that is browser tests are slow to run, to the point that it's infeasible to run locally at scale. That's why for https://reflame.app, I've been building a testing strategy around using serverless compute to run browser component tests with maximum parallelization for a tight feedback loop that takes ~5s for a cold start and 1~2s thereafter, with dependency analysis to rerun only tests that could have changed to keep cost scaling under control.
See this old HN thread:
https://news.ycombinator.com/item?id=30168241
..and the comment from the "only" remaining maintainer:
https://github.com/facebook/jest/pull/11529#issuecomment-102...
I don’t mean to criticize anyone’s prior work but I know it’s better to be more specific, so my short list of problems I’ve experienced with Jest and reasons I won’t consider it for projects currently:
- Its mocking model is coupled to CJS semantics and static analysis and hoisting patterns built on Babel, and it’s hard to work around that especially in legacy code.
- Its isolation model is inherently prone to memory leaks and fragile tests, directly related to the above point. If you `import 'anything'`, in a test module or its dependency tree, you might think you’re initializing once but you’re initializing for each test. If that initialization even exposes a way to teardown it’s just sitting there waiting for you to know you need it in an afterEach, otherwise they run perpetually and never get GCed. Really surprising things like loggers and other seemingly passive libraries which you might develop internally suffer from this. This might all sound like whining, but it can make a large test suite basically useless because you can’t even observe the code that’s still running.
- I’ve watched ESM support improve and I’m impressed by the effort, but from my observation the above issues are major barriers to making its mocking and isolation strategies viable. ESM isn’t the reason they’re challenging, but cache invalidation of stateful imports is an exceedingly good way to reveal them.
The good news is that we have never been shy about making breaking changes and we are working on cleaning the house and making many legacy components optional, all while bringing the existing community with us.
As for mocking, you don’t have to rely on Jest’s inbuilt mocking libraries and you can use the ones you like better.
If you care more about raw performance and ES module support and less about isolation, check out the jest-light-runner: https://github.com/nicolo-ribaudo/jest-light-runner
We also mentioned it in our Jest 28 blog post: https://jestjs.io/blog/2022/04/25/jest-28
I’m wondering if it’s time to consider taking a big step and making this runner the default, and give people the optionality of isolation. However, in my past experience at large companies (both first-hand and second-hand experience), the lack of isolation in tests led to major reliability problems with testing infrastructure. I’m still feeling like it’s the better default today, but maybe we should have a serious discussion about Jest’s next set of defaults.
I was preparing myself to reply “thanks for the kind and receptive response, but…” I’m glad I read further before drawing a conclusion.
> The good news is that we have never been shy about making breaking changes and we are working on cleaning the house and making many legacy components optional, all while bringing the existing community with us.
> If you care more about raw performance and ES module support and less about isolation, check out the jest-light-runner
It looks likely this addresses the problem I was going to raise! I never wanted to use module mocking in the first place, and never did. But Jest at the time I used it didn’t give me an option to opt out of its isolation model and still imposed all of the problems whether I used module mocks or not. I think this (runner which doesn’t support it) is a great thing to provide, and yeah if you’re okay with breaking changes it’s a much more sensible default.
Thank you for not just the kind and receptive response, but also for showing clear direction from problems I raised! I’ll keep tinkering on my test framework as a hobby project because there are already major perf and semantic wins in it. But this definitely makes Jest a more viable day work consideration for me.
Edit to clarify: I agree isolation between tests is crucial, and isolating modules is an important part of that. It’s just… not what Jest is actually doing. It wasn’t when I was using CJS, and it’s much more challenging to mitigate with ESM. Jest very reasonably clears the require cache between tests, but that’s actually breaking isolation when modules have private state initialized on require. If I remember correctly the ESM solution is the same as my naive one: tack a query parameter on when re-importing.
Realistically, the only current viable solution to isolation is worker threads and WASM/NAPI hacks. Hopefully better isolation primitives are coming up through the standards process.
Do you know if there's a way to use that runner per-file or per-project within jest? Seems like that's the only way it'd be possible to smoothly migrate in a large codebase without rewriting all tests at once.
You can define a base config for your repo, and then inherit two sub-configs from it each with different runners and mutually exclusive selection for tests (by suffix, folder, or any convention that works for you).
Glad that this one has the ability to be configured more granually - that'll come in handy for migrating gradually.
As far as I know, further development is on hold until Node’s VM modules feature stabilises. I believe Node is waiting on V8.
This isn't meant to imply that Meta is, in this instance, offloading costs onto the community. But it's a tried-and-true tradition.
Log4j is the canonical example of this: it's such a boring piece of substrate that nobody noticed that it was effectively maintained by one person and had grown all kinds of configurable knobs and dials over the years.
Ultimately, I'm not saying that Meta is in the wrong here. But "here's a cash infusion with no long-term funding or staff commitment" is the kind of general mispattern that we're seeing w/r/t corporate open source.
No, they don't deserve pennies. Facebook has given its code to the world - if anyone wants to keep that code maintained, then they can do so, but (I'd have thought needless to say) Facebook does not owe them a penny to maintain it just because they were kind enough to donate that version of their code. They can update it if they benefit from doing so.
Seriously, is this where we've got to? You can't open source your code unless you're able to pay for its maintenance in perpetuity? How is this in the spirit of openness? And, more to the point, how in the hell does this (incomprehensibly entitled) attitude encourage open source development?
no such thing
Billionaire also donates million of dollars....
In any case, my point isn't really about whether they are being kind or not. That's a fortiori. It's that they certainly aren't under any obligation to provide it, nor to maintain it on account of having provided it.
(Although to respond to your precise point: I'm severely doubtful of your claim that Facebook gets 'huge marketing PR' from an open source library. No one is signing up to Facebook because of the [apparently-existent] 'huge marketing' of the fact that they wrote React.)
(And, even if any of the foregoing made any sense, the notion that an 'appropriate' amount is somehow measured relative to the company's revenue, rather than the factual costs of maintaining the software, is disqualifyingly silly in its own right.)
I get what you are lamenting in general, I would like to see OpenSSL or Django or perhaps even Linux better funded for example. It just seems to me that this is not a case where any lamenting is justified. If the newly-community-owned Jest doesn’t get investment, then sure, that would be lamentable. But that hasn’t happened yet. Indeed, FB divesting ownership was a necessary condition for any serious outside investment to occur, IMO.
Now reading back, I realise that I might have gotten confused and took the numbers that were referring to the Facebook project, thinking it was the Linux donations.
Sorry for the confusion.
Overall their financial contributions could be in the millions. Don't think about the small amount they've done recently.
But even if that was the case is it cynical or just the right thing to do if you've got fewer resources?
I like to use simpler tools, so I'm wondering if there's a more stripped down test tool, sort of like Preact versus React?
For node-based testing I like Ava, but is there a simple tool for browser-based testing?
(outside of a React project)
Its also, as of late, really shown some innovation around testing, I think Jest 28 is a huge step in the right direction.
The only other fully fledged alternative I can think of is Jasmine (which, iirc Jest is actually a fork of?) but Jasmine isn't as well maintained and has no transform infrastructure.
Basically, unless you're just really happy with mocha, I think Jest gives you more flexibility, especially as projects / products grow overtime.
Jest is also better in monorepos IMO.
I can't remember the specifics, but I think it was a mix of having nice reporting built in, easy to spy on or mock our ESModules, and there are a lot of other developers using it, so it was easy to find solutions.
It mostly "just worked" and didn't require adding other libraries to handle mocks and spies.
(P.S. I don't know full story but 2 years ago I used to see sponsor button on opencollective for Jest. And, the repo actively mentioned jest is owned by facebook)9
Sure, its market share is lower, but the quality of Vue 3 is on par with React. Most impressively, it comes with its own core libraries for routing [0] and state [1]. And by extension, has spawned library agnostic tooling in the form of Vite [2] and now Vitest. [3]
I understand that people who live in twitter bubble or whatever don't like to hear opinions that pop it.
I do. The ecosystem is strong and if handed over to a foundation like the OpenJS Foundation it has a better chance of evolving. From my perspective, React is what FB/Meta needs, not necessarily what the community wants. There is no oversight or governance which is concerning given that many developers make a living off of React.
For an expanded explanation see YouTube/KTQVBXb0uPM?t=328