Discussion on Update ECMAScript 2015 to 2023


does anyone see any blocks for moving Meteor to ES14(2023) or at least ES11(2020)?
I see Meteor 2.14 will still rely on ECMAScript 2015. (ECMAScript Versions in JavaScript | Web Reference)

babel-preset-meteor is filled with proposal plugins which have been all turned to standard since ES11.
In the same package, @babel/core is fixed to 7.14.0 released 2.5 years ago.

I’d be ready to test a version of Meteor with these latest tools and push some updates if someone could help me understand the areas that need to be touched to move it to ES14. For the moment I have a local version of https://github.com/meteor/babel-preset-meteor/blob/master/package.json cleaned up of all outdated proposals and filled with the relevant transform plugins (that replace the proposals).

For example in ECMAScript 2022 a top-level await is introduced: “The ability to use top-level await, making it possible to use the keyword outside of an async function”

// fetch request
const colors = fetch("../data/colors.json").then((response) => response.json());

export default await colors;


I’m all for upgrading stuff. PRs welcome.

It would be great for the babel packages to be updated. These are the main things that need to be done. They don’t all have to be done at the same time or by the same person.

  1. In meteor-babel, add a function to get defaults for the node version used in Meteor 3. We have one for node 8, but haven’t added any for newer node versions: https://github.com/meteor/meteor/blob/829d0eabb6357714f42699a88d9d751d0b6eb0bb/npm-packages/meteor-babel/options.js#L165. This includes both removing babel plugins that aren’t needed anymore, and adding babel plugins for ecmascript features that Node is missing. A useful resource is https://node.green
  2. Do the same thing for Node 14 to use in Meteor 2
  3. Update the config for Node 8 so it supports that latest ecmascript features
  4. Update minimum version for modern browsers: https://github.com/meteor/meteor/blob/devel/npm-packages/babel-preset-meteor/babel-presets-meteor/modern.js. Move the babel plugins for ecmascript features that are widely supported to index.js (used for the legacy client) and update the minimum modern browser versions so any browsers that don’t support those features use the legacy client.
  5. Ensure the legacy client has babel plugins for all newer ecmascript features
  6. Ensure the modern client has babel plugins for all ecmascript features that are not fully supported by the minimum modern browser versions.
  7. Drop support for browsers that don’t fully support es5. I don’t think Meteor has supported these browsers for years, but there is still code in every Meteor app to support them
  8. We’ve discussed possibly dropping support for old browsers that don’t support es6 classes. This would allow the legacy client to use native es6 classes, fixing a common cause for the legacy client to break. Since the browser versions that supports classes also support many other es6 features, this would allow us to remove many babel plugins and polyfills from the legacy client.

There’s also the ecmascript-runtime-client and ecmascript-runtime-server packages that need to be updated along with the babel packages.

We don’t really have any guidelines on where to put the line between legacy and modern clients. One thing to keep in mind is that many developers don’t test the legacy client so it frequently is broken.

The data for caniuse and mdn support tables has become easily accessible the past few years. We could create some simple tools to help with maintaining this.


The general understanding had been that top level await has to be implemented by the bundler. There have been some exceptions in the last few years, but they all have some requirements or only work with specific bundlers.

For Meteor we’ve implemented top level await in Meteor 3. The main implementation is part of reify, and these are the PR’s that integrate it with Meteor. As far as I know, reify is the only implementation of top level await that works outside of any bundler - you can even use it in old versions of Nodejs that don’t support top level await, or most other commonjs environments. Meteor is also the second most spec compliant bundler that I’ve tested (webpack does better with circular deps, better than even SpiderMonkey or JavaScriptCore), and there is a large gap between between Meteor and the other bundlers.

The next step is to finish the linker rewrite, and then do something similar with the import scanner to make it faster and more easily extendable. That would allow more of the TLA compilation to be moved from babel to the import scanner where it would only need to be run for the async modules to avoid unnecessarily increasing the bundle size. This is also dependent on dropping support for some very old browsers, so we can either use a simpler way to compile async/await to generators for legacy browsers, or use native async/await.

Unfortunately, I wasn’t able to figure out how to get TLA to work with fibers in Meteor 2 - either we would have a breaking change to make top level fibers code follow the top level await spec, or we would have to make top level await work differently than the spec.


Meteor 3 is a good reason to drop support for browsers without native async/await

With all the effort to move to Meteor 3, and Meteor 2 becoming obsolete due to Node 14, seems the sacrifice to make TLA work differently than the spec due to Meteor 2 will not be worth it


caniuse says async/await is supported by 97.3% of users. That’s much higher than the last time we had discussed this. Compared to requiring es6 classes (supported by 97.78%), requiring native async/await would drop support for these browsers:

  • chrome 42 - 54
  • edge 13 and 14
  • safari 9 and 10
  • opera 29-41
  • Samsung Internet 5

@filipenevola Meteor had supported old versions of Safari. Do you remember why, and if it is still needed?