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.
// 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:
// 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.await → async/await
Promise.await was a Fibers-based synchronous wait. Replace with standard await inside an async function.
// 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.
// 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.call → fetch
The old HTTP package is replaced by the fetch core Meteor package.
// 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:
// 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.send → Email.sendAsync
// 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 createIndex → createIndexAsync
// 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:
// 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 });
}
});// 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 });
});