npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@maxax/x-plugins-mitt

v1.0.1

Published

A lightweight event bus wrapper based on mitt for Maxax projects

Readme

@maxax/x-plugins-mitt

A lightweight event bus wrapper based on mitt for Maxax projects. This package provides a powerful event bus system designed for micro-frontend architectures, supporting communication between master and slave applications.

npm version License

Features

  • Lightweight: Built on top of mitt, minimal footprint
  • Type-safe: Full TypeScript support with generic types
  • Micro-frontend Ready: Built-in support for master-slave application communication
  • Flexible: Multiple ways to get event bus instances (singleton, factory)
  • Powerful: Supports wildcards, once events, and comprehensive event management

Installation

npm install @maxax/x-plugins-mitt mitt
# or
pnpm add @maxax/x-plugins-mitt mitt
# or
yarn add @maxax/x-plugins-mitt mitt

Quick Start

Basic Usage

import { getEventBus, createEventBus } from '@maxax/x-plugins-mitt'

// Option 1: Use singleton instance
const eventBus = getEventBus()

// Option 2: Create a new instance
const eventBus = createEventBus()

// Define event types
interface MyEvents {
  userLoggedIn: { userId: string; username: string }
  notification: { message: string; type: 'info' | 'warning' | 'error' }
  [key: string]: any
}

// Subscribe to events
eventBus.on('userLoggedIn', (data) => {
  console.log(`User ${data.username} logged in with ID: ${data.userId}`)
})

// Publish events
eventBus.emit('userLoggedIn', { userId: '123', username: 'john' })

// Unsubscribe
const unsubscribe = eventBus.on('notification', (data) => {
  console.log('Notification:', data.message)
})
unsubscribe()

Manager Usage (Micro-frontend)

For micro-frontend architectures, use the MaxEventBusManager to coordinate events between master and slave applications:

import { getMaxEventBusManager } from '@maxax/x-plugins-mitt'

// Get manager instance
const manager = getMaxEventBusManager()

// ============ Master Application ============

// Listen for events from any slave application
manager.onAnySlave('dataUpdated', (data, appName) => {
  console.log(`Received data update from ${appName}:`, data)
})

// Broadcast to all applications
manager.broadcast('globalNotification', {
  message: 'System will restart in 5 minutes',
  severity: 'warning'
})

// ============ Slave Application ============

// Send event to master
manager.toMaster('slaveReady', { appName: 'dashboard', timestamp: Date.now() })

// Send event to specific slave
manager.toSlave('orderApp', 'newOrder', { orderId: 'ORD-001', amount: 99.99 })

// Listen to master events
manager.onMaster('configChanged', (data) => {
  console.log('New configuration:', data)
})

API Reference

MaxEventBus

The core event bus class.

Constructor

constructor()

Creates a new event bus instance.

Methods

emit
emit<Key extends keyof MaxEvents>(type: Key, data: MaxEvents[Key]): void

Publishes an event with data.

eventBus.emit('userCreated', { userId: '123', email: '[email protected]' })
emitWithout
emitWithout<Key extends keyof MaxEvents>(type: ...): void

Publishes an event without data.

on
on<Key extends keyof MaxEvents>(event: Key, callback: Handler<MaxEvents[Key]>): () => void

Subscribes to an event. Returns an unsubscribe function.

const unsubscribe = eventBus.on('message', (data) => {
  console.log('Received message:', data)
})

// Later, unsubscribe
unsubscribe()
once
once<Key extends keyof MaxEvents>(event: Key, callback: Handler<MaxEvents[Key]>): () => void

Subscribes to an event that only fires once.

eventBus.once('initComplete', () => {
  console.log('Initialization complete!')
})
onBoth
onBoth(handler: WildcardHandler<MaxEvents>): () => void

Subscribes to all events (wildcard).

eventBus.onBoth((event, data) => {
  console.log(`Event "${event}" fired with data:`, data)
})
off
off<Key extends keyof MaxEvents>(event: Key, callback?: Handler<MaxEvents[Key]>): void

Unsubscribes from an event. If no callback provided, removes all listeners for that event.

clear
clear(): void

Removes all event listeners.

Factory Functions

// Get or create singleton instance
function getEventBus(): MaxEventBus

// Create a new instance
function createEventBus(): MaxEventBus

// Reset singleton instance
function resetEventBus(): void

MaxEventBusManager

Event bus manager for micro-frontend architectures.

Methods

getMasterBus
getMasterBus(): MaxEventBus

Returns the master application event bus.

registerSlaveBus
registerSlaveBus(appName: string, slaveEventBus: MaxEventBus): void

Registers a slave application event bus.

unregisterSlaveBus
unregisterSlaveBus(appName: string): void

Unregisters a slave application.

broadcast
broadcast<K extends string>(event: K, data?: any): void

Broadcasts an event to all applications (master + all slaves).

toMaster
toMaster<K extends string>(event: K, data?: any): void

Sends an event to the master application.

toSlave
toSlave<K extends string>(appName: string, event: K, data?: any): void

Sends an event to a specific slave application.

toSlaves
toSlaves<K extends string>(appNames: string[], event: K, data?: any): void

Sends an event to multiple slave applications.

onMaster
onMaster<K extends string>(event: K, callback: (data: any) => void): () => void

Listens to events from the master application.

onSlave
onSlave<K extends string>(appName: string, event: K, callback: (data: any) => void): () => void

Listens to events from a specific slave application.

onAnySlave
onAnySlave<K extends string>(event: K, callback: (data: any, appName: string) => void): () => void

Listens to events from any slave application. Callback receives the data and app name.

getRegisteredApps
getRegisteredApps(): string[]

Returns a list of registered slave application names.

destroy
destroy(): void

Destroys the manager and all associated event buses.

Advanced Examples

Complete Micro-frontend Setup

// master.ts - Main application
import { getMaxEventBusManager, createEventBus } from '@maxax/x-plugins-mitt'

const masterBus = getMaxEventBusManager()

// Listen for all slave events
masterBus.onAnySlave('*', (event, data, appName) => {
  console.log(`[${appName}] ${event}:`, data)
})

// Send configuration to all apps
masterBus.broadcast('configUpdate', {
  theme: 'dark',
  language: 'en',
  apiUrl: 'https://api.example.com'
})

// Handle slave registration
masterBus.onSlave('reactApp', 'register', (data) => {
  console.log('React app registered:', data)
})

// -------------------------------------------------

// slave-react.ts - React micro-frontend
import { createEventBus, getMaxEventBusManager } from '@maxax/x-plugins-mitt'

const slaveBus = createEventBus()
const manager = getMaxEventBusManager()

// Register with master
manager.registerSlaveBus('reactApp', slaveBus)

// Notify master we're ready
manager.toMaster('register', {
  name: 'React Dashboard',
  version: '1.0.0',
  components: ['Chart', 'Table', 'Form']
})

// Listen for config changes
manager.onMaster('configUpdate', (config) => {
  applyConfig(config)
})

// Broadcast events to other apps
slaveBus.emit('dataLoaded', { count: 42, timestamp: Date.now() })

// -------------------------------------------------

// slave-vue.ts - Vue micro-frontend
import { createEventBus, getMaxEventBusManager } from '@maxax/x-plugins-mitt'

const slaveBus = createEventBus()
const manager = getMaxEventBusManager()

// Register with master
manager.registerSlaveBus('vueApp', slaveBus)

// Listen to all events from React app
manager.onSlave('reactApp', 'dataLoaded', (data) => {
  console.log('React app loaded data:', data)
})

// Send events to master
manager.toMaster('vueReady', { name: 'Vue Admin', status: 'active' })

Using with React

// useEventBus.ts
import { useEffect, useCallback } from 'react'
import { getEventBus } from '@maxax/x-plugins-mitt'

export function useEventBus<EventMap extends Record<string, any>>() {
  const eventBus = getEventBus()

  const subscribe = useCallback(<K extends keyof EventMap>(
    event: K,
    callback: (data: EventMap[K]) => void
  ) => {
    return eventBus.on(event, callback)
  }, [eventBus])

  const publish = useCallback(<K extends keyof EventMap>(
    event: K,
    data: EventMap[K]
  ) => {
    eventBus.emit(event, data)
  }, [eventBus])

  return { subscribe, publish }
}

// Component.tsx
import { useEventBus } from './useEventBus'

interface MyEvents {
  counterUpdate: { count: number }
  reset: void
}

function Counter() {
  const { subscribe, publish } = useEventBus<MyEvents>()
  const [count, setCount] = useState(0)

  useEffect(() => {
    return subscribe('counterUpdate', ({ count }) => {
      setCount(count)
    })
  }, [subscribe])

  const increment = () => {
    publish('counterUpdate', { count: count + 1 })
  }

  return <button onClick={increment}>{count}</button>
}

Using with Vue 3 Composable

// composables/useEventBus.ts
import { onUnmounted } from 'vue'
import { getEventBus } from '@maxax/x-plugins-mitt'

export function useEventBus<EventMap extends Record<string, any>>() {
  const eventBus = getEventBus()

  const on = <K extends keyof EventMap>(
    event: K,
    callback: (data: EventMap[K]) => void
  ) => {
    const unsubscribe = eventBus.on(event, callback)
    onUnmounted(unsubscribe)
    return unsubscribe
  }

  const emit = <K extends keyof EventMap>(
    event: K,
    data: EventMap[K]
  ) => {
    eventBus.emit(event, data)
  }

  return { on, emit }
}

TypeScript Support

This library is written in TypeScript and provides full type safety:

import { createEventBus } from '@maxax/x-plugins-mitt'

// Define your events
interface AppEvents {
  userLogin: { userId: string; username: string }
  userLogout: void
  notification: { message: string; type: string }
  [key: string]: any
}

// Create typed event bus
const eventBus = createEventBus<AppEvents>()

// Fully typed events
eventBus.on('userLogin', (data) => {
  // data is inferred as { userId: string; username: string }
  console.log(data.userId)
})

eventBus.emit('userLogin', { userId: '123', username: 'john' })

Performance Tips

  1. Unsubscribe when done: Always unsubscribe from events when components are destroyed to prevent memory leaks.

  2. Use once for one-time events: For initialization logic that should run only once, use once() instead of on().

  3. Manager for cross-app communication: Use MaxEventBusManager for micro-frontend scenarios instead of creating multiple independent event buses.

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

License

MIT License - see LICENSE for details.