Moving from Meteor to Express, MongoDB, React, Node.js

Have you ever tried moving from meteor to Express, MongoDB, React, Node.js? What problems were the most difficult?
I want to start form authorization and authentication. Can I get unhashed token wich is stored in DB. I want to compare both this token from Db and token on client.
I am gonna do it step by step, first page and then second.

I tried, but kept coming back Meteor; so I integrated ExpressJS alongside GraphQL; created my own JWT authentication system with access token and a refresh token that refreshes automatically whenever the access token expires. Uses MongoDB for authentication, Prisma(Postgres) for schema+data storage and Redis for caching. So Meteor is basically a build tool with so much more. I can’t just stop using Meteor - it’s the greatest stack ever! The React frontend is separate from the backend. You can also use any frontend stack you like…think NextJS.


Check out it’s easy to migrate to

1 Like

we do new projects no longer in meteor (but often with nextjs + graphql nexus + prisma).

but i adopted the way meteor handles resume tokens, so maybe i can help:

  • when user logs in (through username/pw or google), meteor creates a random resume-token, hashes it (with sha256) and stores it to db and passes the unhashed version to the client
  • the client will do requests using that token (in meteor from localstorage and passed through ddp). You can also use a cookie, but make sure to use a http only cookie
  • the server can now find the user by hashing the resume token from the client and comparing that to the stored hashes

So if you would migrate an existing app, you could theoretically keep logged in users logged in, but i would argue that its ok to ask users to login in this case.

I used this snippet to create new tokens and get hashes from that:

import crypto from "crypto"

export const newToken = () => crypto.randomBytes(32).toString("hex")
export const getHash = (token: string) => {
  const hash = crypto.createHash("sha256")

  return hash.digest("base64")

that is more or less how meteor creates hashes


This has been asked few times before.

Echoing @macrozone answer, to migrate account, you’ll need to use npm crypto and bcryptjs to encode/decode the password string. You can use passport JS local strategy and use the following method to compare the supplied password against an existing Meteor account password.

checkPassword: function(inputPassword) {
    const userInput = crypto

    return bcrypt.compareSync(userInput,;

For DB calls you’ll probably need something like mongoose and convert simpleSchme (if you’ve used it) to mongoose schema.

Keep in mind you you’ll need to do the reset/change password flows and the social auth (if you’re using those), also maintain node, mongo driver and other dependencies yourself and you will lose access to Meteor packages ecosystem.

Good luck I hope that helps!