Skip to content

Vanilla

With no framework involved, tabus-js is used as-is: create the instance, subscribe, and emit.

import { Tabus } from "tabus-js";
const bus = new Tabus<{ "cart:add": { id: string } }>("shop");
bus.on("cart:add", ({ id }) => addToCart(id));
bus.emit("cart:add", { id: "sku_42" });

On a page with multiple scripts or modules, it’s best to keep a single instance per channel and share it:

bus.ts
import { Tabus } from "tabus-js";
export const bus = new Tabus<{ "cart:add": { id: string } }>("shop");
cart.ts
import { bus } from "./bus";
bus.on("cart:add", ({ id }) => addToCart(id));
checkout.ts
import { bus } from "./bus";
bus.emit("cart:add", { id: "sku_42" });

If your page is an SPA that mounts and unmounts views, call bus.destroy() when the view is discarded. If it’s a traditional, single-load page, beforeunload is enough:

window.addEventListener("beforeunload", () => bus.destroy());

Check out the full shared cart example, which expands on this same pattern.