Jacob Paris
← Back to all content

Write a type-safe singleton module in Typescript

A singleton is a module that is only ever instantiated once, no matter how many times you import it. This is useful for things like database connections, where you want to be able to access the database from anywhere in your application, but you don't want to create a new connection every time you import the module.

Good candidates for singleton modules is anything that takes configuration or processing power to create, such that you want to make sure that it is only ever created once.

Writing a singleton in Typescript

The basic singleton structure is to declare a global variable that will hold the singleton instance, and then check if that variable is already set before creating a new instance.

ts
let cache: Cache | undefined
declare global {
var cache: Cache | undefined
}
if (!global.cache) {
global.cache = new Cache()
}
cache = global.cache
export default cache

Singletons for Hot Module Reloading

Some third party libraries, such as ioredis, already handle their own connection pooling and will only create a new connection when the server starts for the first time. In this case, you don't need to use the singleton pattern.

Unfortunately, developer tooling will often restart the server every time you make changes to your code, which will cause ioredis to create a new connection every time.

In these scenarios, you may want to return a singleton specifically during development mode and forgo it in production.

ts
let cache: Cache | undefined
declare global {
var cache: Cache | undefined
}
if (process.env.NODE_ENV === "production") {
cache = new Cache()
} else {
if (!global.cache) {
global.cache = new Cache()
}
cache = global.cache
}
export default cache
Professional headshot
Moulton
Moulton

Hey there! I'm a developer, designer, and digital nomad building cool things with Remix, and I'm also writing Moulton, the Remix Community Newsletter

About once per month, I send an email with:

  • New guides and tutorials
  • Upcoming talks, meetups, and events
  • Cool new libraries and packages
  • What's new in the latest versions of Remix

Stay up to date with everything in the Remix community by entering your email below.

Unsubscribe at any time.