Share a single global instance throughout our application.
For example, we can have a `Counter` singleton, which contains a `getCount`, `increment`, and `decrement` method. This singleton can be shared globally across multiple files within the application. The imports of this Singleton all reference the same instance.
<video src="https://res.cloudinary.com/dq8xfyhu4/video/upload/q_auto/v1652717288/FM%20Workshop/Screen_Recording_2022-05-16_at_11.05.50_AM_xzeo41.mov" controls="controls" style="width: 100%;"></video>
## How to Create Singleton?
```ts
let counter = 0;
export default Object.freeze({
getCount: () => counter,
increment: () => ++counter,
decrement: () => --counter,
});
```
> [!info] what is `Object.freeze`?
> `Object.freeze()` is a built-in JavaScript method that prevents the modification of an object's existing properties and prevents the addition of new properties. When you invoke `Object.freeze()` on an object, it makes the object immutable, meaning its state cannot be changed.
since `counter` is private in this file. And there is no other way to access counter. This object is a singleton.
## Use `remember`
[epicweb-dev/remember: Simple, type-safe, "singleton" implementation. (github.com)](https://github.com/epicweb-dev/remember)
```js
// Borrowed/modified from https://github.com/jenseng/abuse-the-platform/blob/2993a7e846c95ace693ce61626fa072174c8d9c7/app/utils/singleton.ts
/**
* Remembers and retrieves a value by a given name, or the value generated by `getValue` if the name doesn't exist.
* The return type is inferred from the return type of `getValue`.
*
* @template Value
* @param {string} name - The name under which to remember the value.
* @param {() => Value} getValue - The function that generates the value to remember.
* @returns {Value} - The remembered value.
*/
export function remember(name, getValue) {
const thusly = globalThis
thusly.__remember_epic_web ??= new Map()
if (!thusly.__remember_epic_web.has(name)) {
thusly.__remember_epic_web.set(name, getValue())
}
return thusly.__remember_epic_web.get(name)
}
```
```ts
import { remember } from '@epic-web/remember'
export const prisma = remember('prisma', () => new PrismaClient())
```
basically you ask if the global has `prisma`, if no, create the new `PrismaClient()`. The constructor will only be called if global doesn't have it.