Skip to main content

This is a contributors guide and NOT a user guide. Please visit these docs if you are using or evaluating SuperTokens.


  • Use typed strings as much as possible. For example, if a string variable can have a certain values, do not assign it type string, but instead use "val1" | "val2" ...

  • Use type instead of interfaces or namespace.

  • Classes must start with a capital letter, but variables with a small letter.

  • No switch statements, use if, else instead.

  • Camel case is preferred over using underscores.

  • Minimise use of old JS style coding:

  • Always use === and never ==

  • Always do explicit if checks. For example, if var1: string | undefined, do not do if (var1), instead, do if (var1 !== undefined). The only time something like if(var2) is acceptable, is when the type of var2: boolean.

  • if the return type of a function is an object, then specify the object's type in the function signature. If the object is used in several places, create a type for it in a types.ts file, and reference that.

  • If the return type of a function is an object that has a different structure based on the logic of the function, then use the | operator. For example, a return type can be:

    {status: "OK", name: string} | {status: "FAILED"} // good

    We prefer the above as opposed to

    {status: "OK" | "FAILED", name?: string} // bad

    because the second option expresses more possible types that what is possible - name will always be undefined if status: "FAILED".

    Also notice that we have a common field (status) across the different object types. This is necessary since if we don't have this, then the consumer of the return type would have a hard time knowing what the structure is.

  • Minimise the use of null. By convention, we prefer undefined over null.

  • Minimise the use of any and unknown. But if we must use these, we prefer using any.

  • Whenever creating an exportable module (to the user), we must allow them to import like:

    • import T from ".." and then do T.A()
    • import { A } from "..." and then do A()
  • We want to minimise the number of named types. Otherwise this can grow to a very long list, very quickly.

  • Miscellaneous functions like checkEmailFormat, or convertToBase64() can go into a utils.ts class. No need to create separate files for them.

  • Use @deprecated to deprecate functions and classes. When using this, make sure to use it in all functions that use the deprecated function as well (if applicable). If a user facing function needs to be deprecated, make sure to check that that's happening by using the playground.

Looking for older versions of the documentation?
Which UI do you use?
Custom UI
Pre built UI