Blog
Mitt, a tiny 200b functional event emitter.

Mitt, a tiny 200b functional event emitter.

In this article, we will review mitt a functional event emitter. We will look at:

  1. What is Mitt?

  2. Mitt usage in nuqs codebase.

What is Mitt?

Mitt is a tiny 200 bytes functional event emitter. So what are its features?

  • Microscopic: weighs less than 200 bytes gzipped.

  • Useful: a wildcard "*" event type listens to all events.

  • Familiar: same names & ideas as Node’s EventEmitter.

  • Functional: methods don’t rely on this.

  • Great Name: somehow mitt wasn’t taken.

Install:

This is how you can install mitt.

$ npm install --save mitt

Usage:

import mitt from 'mitt'

const emitter = mitt()

// listen to an event
emitter.on('foo', e => console.log('foo', e) )

// listen to all events
emitter.on('*', (type, e) => console.log(type, e) )

// fire an event
emitter.emit('foo', { a: 'b' })

// clearing all events
emitter.all.clear()

// working with handler references:
function onFoo() {}
emitter.on('foo', onFoo)   // listen
emitter.off('foo', onFoo)  // unlisten

This code snippet is picked from usage in the mitt documentation.

Mitt usage in nuqs codebase.

I found mitt imported in a file named sync.ts in nuqs package.

import Mitt from 'mitt'

export type CrossHookSyncPayload = {
  state: any
  query: string | null
}

type EventMap = {
  [key: string]: CrossHookSyncPayload
}

export const emitter = Mitt<EventMap>()

emitter is used in a lot of places as you can see from the symbols:

we will pick an example from useQueryState.ts at line 265, emitter.on is called

 emitter.on(key, updateInternalState)

In the same file, emitter.emit is called at line 294.

// Sync all hooks state (including this one)
emitter.emit(key, { state: newValue, query })

At line 268, you can see that emitter.off is called 

  emitter.off(key, updateInternalState)

Overall, in the useQueryState.ts file, emitter.on, emitter.off and emitter.emit, these three API’s from the mitt are used. 

About me:

Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.

Configure features such as Changesets, Supabase auth in your Next.js project using Think Throo CLI.

Email — ramu@thinkthroo.com

My Github —  https://github.com/ramu-narasinga

My website —  https://ramunarasinga.com

My YouTube channel —  https://www.youtube.com/@ramu-narasinga

Learning platform —  https://thinkthroo.com

Codebase Architecture —  https://app.thinkthroo.com/architecture

Best practices —  https://app.thinkthroo.com/best-practices

Production-grade projects —  https://app.thinkthroo.com/production-grade-projects

References

  1. https://github.com/47ng/nuqs/blob/next/packages/nuqs/src/useQueryState.ts#L6

  2. https://github.com/47ng/nuqs/blob/next/packages/nuqs/src/useQueryState.ts#L265

  3. https://github.com/47ng/nuqs/blob/next/packages/nuqs/src/sync.ts

  4. https://www.npmjs.com/package/mitt

  5. https://github.com/developit/mitt/blob/main/src/index.ts