Learn Development at Frontend Masters
An event bus is a design pattern (and while we’ll be talking about JavaScript here, it’s a design pattern in any language) that can be used to simplify communications between different components. It can also be thought of as publish/subscribe or pubsub.


The idea is that components can listen to the event bus to know when to do the things they do. For example, a “tab panel” component might listen for events telling it to change the active tab. Sure, that might happen from a click on one of the tabs, and thus handled entirely within that component. But with an event bus, some other elements could tell the tab to change. Imagine a form submission which causes an error that the user needs to be alerted to within a specific tab, so the form sends a message to the event bus telling the tabs component to change the active tab to the one with the error. That’s what it looks like aboard an event bus.
Pseudo-code for that situation would be like…
Do you need a JavaScript library to this? (Trick question: you never need a JavaScript library). Well, there are lots of options out there:
Also, check out Mitt which is a library that’s only 200 bytes gzipped. There is something about this simple pattern that inspires people to tackle it themselves in the most succincet way possible.
Let’s do that ourselves! We’ll use no third-party library at all and leverage an event listening system that is already built into JavaScript with the addEventListener we all know and love.
The addEventListener API in JavaScript is a member function of the <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget">EventTarget</a> class. The reason we can bind a click event to a button is because the prototype interface of <button> (<a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLButtonElement">HTMLButtonElement</a>) inherits from EventTarget indirectly.
Different from most other DOM interfaces, EventTarget can be created directly using the new keyword. It is supported in all modern browsers, but only fairly recently. As we can see in the screenshot above, Node inherits EventTarget, thus all DOM nodes have method addEventListener.
I’m suggesting an extremely lightweight Node type to act as our event-listening bus: an HTML comment (<!-- comment -->).
To a browser rendering engine, HTML comments are just notes in the code that have no functionality other than descriptive text for developers. But since comments are still written in HTML, they end up in the DOM as real nodes and have their own prototype interface—<a href="https://developer.mozilla.org/en-US/docs/Web/API/Comment">Comment</a>—which inherits Node.
The Comment class can be created from new directly like EventTarget can:
We could also use the ancient, but widely-supported <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/createComment">document.createComment</a> API. It requires a data parameter, which is the content of the comment. It can even be an empty string:
Now we can emit events using <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent">dispatchEvent</a>, which accepts an Event Object. To pass user-defined event data, use <a href="https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/">CustomEvent</a>, where the detail field can be used to contain any data.
Internet Explorer 9-11 supports CustomEvent, but none of the versions support new CustomEvent. It’s complex to simulate it using document.createEvent, so if IE support is important to you, there’s a way to polyfill it.
Now we can bind event listeners:


If an event intends to be triggered only once, we may use { once: true } for one-time binding. Other options won’t fit here. To remove event listeners, we can use the native <a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener</a>.
The number of events bound to single event bus can be huge. There also can be memory leaks if you forget to remove them. What if we want to know how many events are bound to myEventBus?
myEventBus is a DOM node, so it can be inspected by DevTools in the browser. From there, we can find the events in the Elements → Event Listeners tab. Be sure to uncheck “Ancestors” to hide events bound on document and window.
One drawback is that the syntax of EventTarget is slightly verbose. We can write a simple wrapper for it. Here is a demo in TypeScript below:
The following demo provides the compiled JavaScript.
And there we have it! We just created a dependency-free event-listening bus where one component can inform another component of changes to trigger an action. It doesn’t take a full library to do this sort of stuff, and the possibilities it opens up are pretty endless.
Frontend Masters is the best place to get it. They have courses on all the most important front-end technologies, from React to CSS, from Vue to D3, and beyond with Node.js and Full Stack.
Frontend Masters is the best place to get it. They have courses on all the most important front-end technologies, from React to CSS, from Vue to D3, and beyond with Node.js and Full Stack.
Cool 🙂
You can think of event bus as hooks in WordPress. This one uses native JavaScript, but doesn’t use the Event API so it supports more browsers. Suitable to be extended in a tiny application:
https://github.com/taufik-nurrohman/hook

You may write comments in Markdown thanks to Jetpack Markdown. This is the best way to post any code, inline like `<div>this</div>` or multiline blocks within triple backtick fences (“`) with double new lines before and after. All comments are held for moderation. Be helpful and kind and yours will be published no problem.
The related posts above were algorithmically generated and displayed here without any load on my server at all, thanks to Jetpack.
CSS-Tricks* is created, written by, and maintained by Chris Coyier and a team of swell people. The tech stack for this site is fairly boring. That’s a good thing! I’ve used WordPress since day one all the way up to v17, a decision I’m very happy with. I also leverage Jetpack for extra functionality and Local for local development.
*May or may not contain any actual “CSS” or “Tricks”.
CodePen is a place to experiment, debug, and show off your HTML, CSS, and JavaScript creations.
CSS-Tricks is hosted by Flywheel, the best WordPress hosting in the business, with a local development tool to match.
ShopTalk is a podcast all about front-end web design and development.

source