Skip to main content

Migrating to SuperTokens

For login migration#

If you cannot migrate all existing users into db tables managed by SuperTokens#

You will want to use our override feature for this. Essentially, it allows you to override our core functions to use your existing database / identity provider for existing users, and use SuperTokens for new users.

Let's take an example in which we want to use the EmailPassword recipe. Here we assume that you have an existing database of userIds, emails and their password hashes. We can implement the migration code as below (this example is for NodeJS, but a similar code structure applies for other frameworks):

let supertokens = require("supertokens-node");let EmailPassword = require("supertokens-node/recipe/emailpassword");
supertokens.init({   supertokens: {...},   appInfo: {...},   recipeList: [      EmailPassword.init({         override: {            functions: (originalImpl) => {               return {                  ...originalImpl,                  signIn: async function (input) {                     // we check if the email exists in SuperTokens. If not,                     // then the sign in should be handled by you.                     if (await originalImpl.getUserByEmail({ email: }) === undefined) {                        // TODO: sign in using your db                     } else {                        return originalImpl.signIn(input);                     }                  },                  signUp: async function(input) {                     // all new users are created in SuperTokens;                     return originalImpl.signUp(input);                  },                  getUserByEmail: async function(input) {                     let superTokensUser = await originalImpl.getUserByEmail(input);                     if (superTokensUser === undefined) {                        let email =;                        // TODO: fetch and return user info from your database...                     } else {                        return superTokensUser;                     }                  },                  getUserById: async function(input) {                     let superTokensUser = await originalImpl.getUserById(input);                     if (superTokensUser === undefined) {                        let userId = input.userId;                        // TODO: fetch and return user info from your database...                     } else {                        return superTokensUser;                     }                  }               }            }         }      })   ]});

There are a few more function that can be overrided, but those need not be in most cases. To learn more about overriding functions, please visit the docs for the recipe that you want to use.

If you can migrate all existing users into db tables managed by SuperTokens#

You can find the database schema used by SuperTokens by visiting the recipe page > Quick setup > Database setup > And then choosing your db > Scrolling down and expanding the "See table structure" drop down.

If you are using our managed service, you can contact us via email or via Discord and ask us to move your users from your database to the one we host for you (we use PostgreSQL).

For session migration#

If you are OK with logging all users out#

This can be solved by replacing your session creation, verification and revocation calls with the ones from SuperTokens. Since SuperTokens' session verification is most likely going to be different, verification of existing session will most likely fail, logging out that user. Then when they log back in, they will be using SuperTokens session system.

If you want to keep all existing users logged in#

For this approach, you should change the session verification, creation and revocation for all your APIs, excepting for one. This one API will be a new API whose job is to verify a session created from your system, revoke it, and create a new session using SuperTokens.

For all users, on first page load, if your session exists (and not SuperTokens' session), you want to call this special API, wait for it to switch sessions, and then continue with the rest of the app load.