Migrating to Meteor 2.9

How to migrate your application to Meteor 2.9.

Meteor 2.9 introduces some changes in the accounts packages, the new method Email.sendAsync, the new method Meteor.userAsync, and more. For a complete breakdown of the changes, please refer to the changelog.

Why is this new API important?

You may know that on Meteor we use a package called Fibers. This package is what makes it possible to call an async function inside Meteor in a sync way (without having to wait for the promise to resolve).

But starting from Node 16, Fibers will stop working, so Meteor needs to move away from Fibers, otherwise, we’ll be stuck on Node 14.

If you want to know more about the plan, you can check this discussion.

Why doing this change now?

This will be a considerable change for older Meteor applications, and some parts of the code of any Meteor app will have to be adjusted eventually. So it’s important to start the migration process as soon as possible.

The migration process started in version 2.8. We recommend you check that out first in case you skipped.

Can I update to this version without changing my app?

Yes. You can update to this version without changing your app.

What's new?

Let’s start with the accounts and OAuth packages. Some methods had to be restructured to work without Fibers in the future. The current methods will continue working as of today, but if you use some of the methods we’ll mention below in custom login packages, we recommend you adapt them.

Internal methods that are now async:

  • _attemptLogin
  • _loginMethod
  • _runLoginHandlers
  • Accounts._checkPassword: still works as always, but now has a new version called Accounts._checkPasswordAsync.

We also have changes to asynchronous context in the registry of handlers for OAuth services.

Now, the OAuth.Register method accepts an async handler, and it is possible to use the await option internally, avoiding to use methods that run on Fibers, such as HTTP (deprecated Meteor package), Meteor.wrapAsync and Promise.await.

Before the changes you would have something like:

OAuth.registerService('github', 2, null, (query) => {
  const accessTokenCall = Meteor.wrapAsync(getAccessToken);
  const accessToken = accessTokenCall(query);
  const identityCall = Meteor.wrapAsync(getIdentity);

Now you have:

OAuth.registerService('github', 2, null, async (query) => {
  const accessToken = await getAccessToken(query);
  const identity = await getIdentity(accessToken);
  const emails = await getEmails(accessToken);

New async methods

We now have async version of methods that you already use. They are:

Breaking async

Accounts.createUserVerifyingEmail is now completely async:

To upgrade change from

  createUserAccount (user) {
     * This seems to be the issue.
     * Using the other method `createUser` works as expected.
      username: user.username,
      email: user.email,
      password: user.password,


  async createUserAccount (user) {
    await Accounts.createUserVerifyingEmail({
      username: user.username,
      email: user.email,
      password: user.password,

Accounts-base without service-configuration

Now accounts-base is no longer tied up with service-configuration. So, if you don’t use third-party login on your project, you don’t need to add the package service-configuration anymore.

Migrating from a version older than 2.8?

If you’re migrating from a version of Meteor older than Meteor 2.8, there may be important considerations not listed in this guide. Please review the older migration guides for details:

Edit on GitHub
// search box