Skip to content

Removing Fibers Patterns

Meteor 3 removes the Fibers dependency entirely. This page shows before/after examples for the most common Fibers-dependent patterns you'll encounter during migration.

For background on why Fibers was removed, see the FAQ.

Meteor.wrapAsync → Promises

Meteor.wrapAsync no longer exists. Replace it with util.promisify or manual Promise wrapping.

js
// Before
import { Meteor } from 'meteor/meteor';

const syncFunction = Meteor.wrapAsync(someCallbackFunction); 
const result = syncFunction(arg1, arg2); 

// After — using util.promisify
import { promisify } from 'util';

const asyncFunction = promisify(someCallbackFunction);
const result = await asyncFunction(arg1, arg2); 

If the callback doesn't follow the standard (error, result) pattern, wrap it manually:

js
// After — manual Promise wrapping
function asyncFunction(arg1, arg2) {
  return new Promise((resolve, reject) => {
    someCallbackFunction(arg1, arg2, (error, result) => {
      if (error) reject(error);
      else resolve(result);
    });
  });
}

const result = await asyncFunction(arg1, arg2); 

Promise.awaitasync/await

Promise.await was a Fibers-based synchronous wait. Replace with standard await inside an async function.

js
// Before
const result = Promise.await(someAsyncOperation()); 

// After
const result = await someAsyncOperation(); 

WARNING

The function containing await must be declared as async. This often means you need to make the calling function async too, which can cascade up the call chain.

Npm.require('fibers') → Remove

Any direct usage of the fibers npm module must be removed entirely.

js
// Before
const Fiber = Npm.require('fibers'); 
const Future = Npm.require('fibers/future'); 

const future = new Future(); 
someCallback((err, result) => { 
  if (err) future.throw(err); 
  else future.return(result); 
}); 
const result = future.wait(); 

// After
const result = await new Promise((resolve, reject) => { 
  someCallback((err, result) => { 
    if (err) reject(err); 
    else resolve(result); 
  }); 
}); 

HTTP.callfetch

The old HTTP package is replaced by the fetch core Meteor package.

js
// Before
import { HTTP } from 'meteor/http'; 

const response = HTTP.call('GET', 'https://api.example.com/data', { 
  headers: { Authorization: `Bearer ${token}` } 
}); 
const data = response.data; 

// After
import { fetch } from 'meteor/fetch'; 

const response = await fetch('https://api.example.com/data', { 
  headers: { Authorization: `Bearer ${token}` } 
}); 
const data = await response.json(); 

For POST requests:

js
// Before
HTTP.call('POST', url, { 
  data: { key: 'value' } 
}); 

// After
await fetch(url, { 
  method: 'POST', 
  headers: { 'Content-Type': 'application/json' }, 
  body: JSON.stringify({ key: 'value' }) 
}); 

Email.sendEmail.sendAsync

js
// Before
import { Email } from 'meteor/email';

Email.send({ 
  to: 'user@example.com',
  from: 'noreply@example.com',
  subject: 'Hello',
  text: 'World'
}); 

// After
await Email.sendAsync({ 
  to: 'user@example.com',
  from: 'noreply@example.com',
  subject: 'Hello',
  text: 'World'
}); 

Synchronous createIndexcreateIndexAsync

js
// Before
MyCollection._ensureIndex({ email: 1 }); 

// After
await MyCollection.createIndexAsync({ email: 1 }); 

Callback-Based Patterns → async/await

Many older Meteor patterns used callbacks or synchronous Fiber-based code. Convert these to async/await:

js
// Before — callback in Meteor.startup
Meteor.startup(() => {
  const settings = Settings.findOne({ key: 'app' }); 
  if (!settings) {
    Settings.insert({ key: 'app', value: defaults }); 
  }
});

// After
Meteor.startup(async () => { 
  const settings = await Settings.findOneAsync({ key: 'app' }); 
  if (!settings) {
    await Settings.insertAsync({ key: 'app', value: defaults }); 
  }
});
js
// Before — synchronous publish
Meteor.publish('userPosts', function () {
  const user = Meteor.users.findOne(this.userId); 
  return Posts.find({ authorId: user._id }); 
});

// After
Meteor.publish('userPosts', async function () { 
  const user = await Meteor.users.findOneAsync(this.userId); 
  return Posts.find({ authorId: user._id });
});