Skip to content

Breaking changes

MongoDB Methods in the server

As mentioned in the Frequently Asked Questions, insert, update, remove, find, findOne, upsert methods no longer work in the server.

You should migrate to use their Async counterparts.

js
const docs = MyCollection.find({ _id: '123' }).fetch(); This will not work in the server
const doc = MyCollection.findOne({ _id: '123' }); This will not work in the server


// in Meteor 3.x you should use the Async methods

const docs = await MyCollection.find({ _id: '123' }).fetchAsync(); This will work in the server
const doc = await MyCollection.findOneAsync({ _id: '123' }); This will work in the server

CLI

The --vue2 flag is no longer available. We droped support for vue2. You can see more information in this PR.

Why?

This was decided because vue2 reached its end of life on 2023-12-31, the team decided to drop support for it.

Node v20

Meteor 3.0 is now using Node v20. This means that if you have any dependencies or usages of Node v14, you will need to update them to be compatible with Node v20.

NPM Installer

The npm installer has been updated. Use the following command to install Meteor:

bash
npx meteor

or

bash
npx meteor@<version>

You should be using a node version >= 20.0.0, if you use in your CI/CD you should update it to use the latest version of Node.

Call x CallAsync

TIP

You can check call x callAsync page for a full overview.

Due to how meteor now works with async/await, you should use callAsync instead of call in your methods.

In Meteor 2.x this was a common pattern:

js
import { Meteor } from 'meteor/meteor'

Meteor.methods({
  async getAllData() {
    return await MyCollection.find().fetch(); 
  },
  async otherMethod() {
    return await MyCollection.find().fetch(); 
  }
});


Meteor.call('getAllData') 
Meteor.call('otherMethod') 

Now in Meteor 3.x it should become:

js
import { Meteor } from 'meteor/meteor'

Meteor.methods({
  async getAllData() {
    return await MyCollection.find().fetchAsync(); 
  },
  async otherMethod() {
    return await MyCollection.find().fetchAsync(); 
  }
});

await Meteor.callAsync('getAllData') 
await Meteor.callAsync('otherMethod') 

Changes in Webapp

TIP

Webapp now uses Express under the hood. This means that you can use all the express features in your Meteor app.

But if you did any customizations in the WebApp package, you should check if they are compatible with Express.

The webapp package now exports this new properties:

ts
type ExpressModule = {
  (): express.Application;
  json: typeof express.json;
  raw: typeof express.raw;
  Router: typeof express.Router;
  static: typeof express.static;
  text: typeof express.text;
  urlencoded: typeof express.urlencoded;
};

export declare module WebApp {
  // ...
  /**
   * @deprecated use handlers instead
   */
  var connectHandlers: express.Application;
  var handlers: express.Application; 
  /**
   * @deprecated use rawHandlers instead
   */
  var rawConnectHandlers: express.Application;
  var rawHandlers: express.Application;
  var httpServer: http.Server;
  var expressApp: express.Application;
  var express: ExpressModule; 
  // ...
}

// import { WebApp } from 'meteor/webapp';

If you want to use express in your app, you can do it like this:

js
import { WebApp } from 'meteor/webapp';

const app = WebApp.express(); you can use as a normal express app

app.get('/hello', (req, res) => {
  res.send('Hello World');
});

WebApp.handlers.use(express);

The code below is an example of how you can use the handlers property to create a route in your app:

js
import { WebApp } from 'meteor/webapp';

WebApp.handlers.get('/hello', (req, res) => {
  res.send('Hello World');
});

Changed engine from connect to express and changed api naming to match express. See below:

  • WebApp.connectHandlers.use(middleware) is now WebApp.handlers.use(middleware)
  • WebApp.rawConnectHandlers.use(middleware) is now WebApp.rawHandlers.use(middleware)
  • WebApp.connectApp is now WebApp.expressApp

A few methods from WebApp internals are now async:

  • WebAppInternals.reloadClientPrograms()
  • WebAppInternals.pauseClient()
  • WebAppInternals.generateClientProgram()
  • WebAppInternals.generateBoilerplate()
  • WebAppInternals.setInlineScriptsAllowed()
  • WebAppInternals.enableSubresourceIntegrity()
  • WebAppInternals.setBundledJsCssUrlRewriteHook()
  • WebAppInternals.setBundledJsCssPrefix()
  • WebAppInternals.getBoilerplate

Meteor.userAsync

You should use Meteor.userAsync instead of Meteor.user in your code, especially if you want isomorphism or want to get your user in the server.

js
// Before
const user = Meteor.user(); 
// After
const user = await Meteor.userAsync();