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

@youneed/server-plugin-pubsub

v0.1.0

Published

Backend-agnostic publish/subscribe for @youneed/server: PubSub contract + MemoryPubSub + a ServerPlugin that surfaces channels in @youneed/server-plugin-devtools (flow graph, header tab, message sender). Re-exports the KV store.

Readme

@youneed/server-plugin-pubsub

Backend-agnostic publish/subscribe for @youneed/server — the same shape @youneed/server-plugin-store gives KV. You code against one PubSub contract (publish/subscribe, messages are strings) and pick the transport via an adapter: in-process MemoryPubSub (built-in), or Redis / Postgres / Deno / Kafka through a sibling adapter package.

pubsub(bus) is a ServerPlugin: it mounts small introspection routes and, when @youneed/server-plugin-devtools is present, surfaces a Pub/Sub node on the flow graph, its own header tab, and a "send a message" panel. The package also re-exports @youneed/server-plugin-store (KV contract + MemoryKV) for convenience.

import { Application } from "@youneed/server";
import { createPubSub, pubsub } from "@youneed/server-plugin-pubsub";

// Wrap a backend (default = in-process MemoryPubSub) in a tracker for devtools.
const bus = createPubSub();

const app = Application()
  .plugin(pubsub(bus)) // exposes /__pubsub/channels + /__pubsub/publish, and inspect()
  .listen(3000, () => {});

// Subscribe — handler receives (message, channel). Messages are strings, so serialize.
const sub = await bus.subscribe("orders", (message, channel) => {
  const order = JSON.parse(message);
  console.log(`[${channel}]`, order.id);
});

// Publish from anywhere (a handler, a job, …).
await bus.publish("orders", JSON.stringify({ id: 42 }));

// Later: stop delivery.
await sub.close();

Using a real transport

createPubSub(backend) wraps any PubSub implementation in a TrackedPubSub so its traffic shows up in devtools. Pass an adapter as the backend:

import { createPubSub, pubsub } from "@youneed/server-plugin-pubsub";
import { postgresPubSub } from "@youneed/server-plugin-pubsub-postgres";

const bus = createPubSub(postgresPubSub({ connectionString: process.env.DATABASE_URL }));
Application().plugin(pubsub(bus)).listen(3000, () => {});

Adapters (each implements the PubSub contract):

API

  • pubsub(bus, opts?) → ServerPlugin. bus must be a TrackedPubSub. Mounts GET {basePath}/channels and POST {basePath}/publish ({ channel, message }), and reports an inspect() payload (kind: "pubsub") for devtools.
    • basePath — internal route prefix (default "/__pubsub").
    • exposeDevtools — mount the introspection + publish routes (default true).
  • createPubSub(backend?, opts?) → TrackedPubSub. Wraps backend (default MemoryPubSub) in tracking. opts.recent — ring-buffer size of recent messages kept per channel (default 25).
  • TrackedPubSub — a PubSub that records per-channel counts/subscribers/recent messages. .channels() returns the activity snapshot. Pass the same instance to pubsub(...) and your handlers so all traffic is tracked.
  • MemoryPubSub — in-process PubSub, fine for a single instance / dev.

The PubSub contract

interface PubSub {
  readonly name?: string; // adapter name, shown in devtools
  publish(channel: string, message: string): Promise<void>;
  subscribe(channel: string, handler: Subscriber): Promise<Subscription>;
  close?(): Promise<void>;
}
type Subscriber = (message: string, channel: string) => void | Promise<void>;
interface Subscription { close(): void | Promise<void>; }

Also exported: ChannelStat, PubSubInspect, PubSubPluginOptions, and everything from @youneed/server-plugin-store.