DEV Community

Cover image for Meteor 3.5: accounts-express Brings Meteor Accounts to Express
Nacho Codoñer for Meteor

Posted on

Meteor 3.5: accounts-express Brings Meteor Accounts to Express

Bring authenticated Meteor users into Express routes without building a second session system.

Meteor 3 is modernizing the framework in two complementary ways: adopting proven tools from the wider JavaScript ecosystem and completing them with the Meteor-specific capabilities that make an application coherent. Adding a library is only the start; a strong integration should preserve the Accounts, data, and developer experience that Meteor apps already rely on.

accounts-express is a clear example. Meteor already lets applications define Express endpoints through WebApp. With Meteor 3.5, those endpoints can participate in the same authenticated user context as the rest of your application. Express can now be a first-class extension of a Meteor app rather than a disconnected server layer.

A More Complete Express Integration

Express is a practical fit for REST endpoints, webhooks, third-party integrations, and server APIs. But those endpoints often need the authenticated Meteor user, existing authorization rules, and access to private application data. Before accounts-express, bridging that boundary could mean custom middleware, manual token handling, or a parallel authentication model around Express.

With Meteor 3.5, accounts-express connects Express routes to Meteor Accounts so the application's existing login state can carry through to the HTTP layer. Its middleware reads a Meteor login token, attaches the resolved user ID to req.userId, and makes Meteor.userId() available for the rest of that request's handler chain.

This extends Meteor authentication to Express when an HTTP interface is the right fit; it does not replace your existing setup. Account summaries, webhook follow-ups, and private API routes can reuse the signed-in user's identity without another set of credentials, sessions, and user lookups. The package also provides an authentication-aware fetch: importing from meteor/accounts-express enables authentication by default, while Meteor.fetch and meteor/fetch stay neutral until you pass auth: true.

Get Started with accounts-express

Create a Meteor 3.5 app:

meteor create my-app --release 3.5
Enter fullscreen mode Exit fullscreen mode

Or update an existing app:

meteor update --release 3.5
Enter fullscreen mode Exit fullscreen mode

Then install the package:

meteor add accounts-express
Enter fullscreen mode Exit fullscreen mode

Then protect an Express route with createAuthMiddleware. This example returns a compact profile for the authenticated user:

// server/routes.js
import { Meteor } from 'meteor/meteor';
import { WebApp } from 'meteor/webapp';
import { createAuthMiddleware } from 'meteor/accounts-express';

WebApp.handlers.get(
  '/api/me',
  createAuthMiddleware({ required: true }),
  async (req, res) => {
    const user = await Meteor.users.findOneAsync(req.userId, {
      fields: { username: 1 },
    });

    res.json({
      id: req.userId,
      username: user?.username,
    });
  },
);
Enter fullscreen mode Exit fullscreen mode

From client code, call that endpoint with the package's authenticated fetch:

import { fetch } from 'meteor/accounts-express';

const response = await fetch('/api/me');
const profile = await response.json();
Enter fullscreen mode Exit fullscreen mode

When a signed-in client makes this request, the package includes its Meteor login token. The middleware exposes the user ID as req.userId and through Meteor.userId(); with required: true, an anonymous request receives 401 before the route handler runs.

This also makes the security boundary clear. A browser-address-bar visit does not automatically include the Meteor login token; use one of the supported fetch entry points when a client request needs authenticated Meteor context. If you prefer explicit opt-in at each call site, use Meteor.fetch('/api/me', { auth: true }) or import from meteor/fetch and pass auth: true.

🔗 Read the accounts-express package documentation

Try the Demo

We prepared a live accounts-express demo on Galaxy so you can see request flow in practice.

Sign in as a demo user, run an example, and compare client call, server route, authentication intent, and response. The demo covers protected routes, optional authentication, request-context forwarding, explicit server tokens, and a protected JSON route. It also shows how meteor/accounts-express makes authenticated fetches default, while other entry points stay opt-in.

The accounts-express demo and its authenticated request flow

Your Feedback Shapes What Comes Next

accounts-express closes a boundary developers have discussed for a long time. The community discussion that introduced the package traces related requests back more than a decade, from early REST middleware to modern SSR, GraphQL, and API use cases. Meteor 3.5 turns that sustained feedback into a focused core capability.

That feedback is already shaping the next practical step. We are working toward configurable login and logout endpoints plus long-lived API tokens, extending the accounts-express use case without losing the connection to Meteor Accounts. It is a concrete example of how real application needs can guide what comes next.

That is part of the larger Meteor 3 approach: modernization creates room to revisit integration gaps that once required private workarounds, while focused feedback makes those gaps easier to prioritize. We will keep advancing major architectural improvements and addressing practical edges that matter in everyday application work.

Try the package in a real app, share the use cases that matter to you, and tell us where the developer experience can improve. Discussion, testing, and contributions help refine the next steps, whether you are building REST routes, server-rendered experiences, integrations, or something we have not anticipated yet.

Join the Meteor Renaissance!

Meteor 3.5 makes Express endpoints feel more connected to the Meteor applications they serve. Use accounts-express when an HTTP route needs your existing account context, then help shape what Meteor improves next.

Meteor 3.x has brought one of the most active periods of modernization since Meteor's early years, with improvements across the framework, build tooling, performance, and the developer experience. That momentum is powered by the community, direct collaboration, and the sponsors who make continued investment in Meteor possible.

If Meteor has helped you build and grow, consider supporting what comes next through the Meteor Sponsorship Program. A special thanks to our current sponsors: Galaxy, Input Logic, and CodeRabbit.

Join the renaissance! Visit the Meteor Forums, join Discord, or report an issue on GitHub. Follow Meteor on X and GitHub.


Stay tuned, and as always, happy coding! ☄️

Top comments (0)