Invite-Only Early Access — Think Throo GitHub App is currently invite-only. Request access here.
2025May

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. Email: ramu.narasinga@gmail.com

Tired of AI-generated code that works but nobody understands?

I spent 3+ years studying OSS codebases and wrote 350+ articles on what makes them production-grade. I built an open source tool that reviews your PR against your existing codebase patterns.

Your codebase. Your patterns. Enforced.

Get started for free —thinkthroo.com

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