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

pubsub-dashboard

v1.0.0

Published

Local-first developer dashboard for Google Cloud Pub/Sub — runs entirely on 127.0.0.1, authenticates via gcloud ADC, zero telemetry.

Downloads

1,169

Readme

pubsub-dashboard

A local-first dashboard for Google Cloud Pub/Sub. It runs entirely on 127.0.0.1, authenticates with your existing gcloud Application Default Credentials, and never talks to anything except Google Cloud APIs.

  • Loopback only — binds 127.0.0.1, refuses non-local Host headers.
  • No credentials of its own — reuses gcloud auth application-default login.
  • No project inference — the active project comes only from gcloud config get-value project (never GOOGLE_CLOUD_PROJECT).
  • One commandnpx pubsub-dashboard boots and opens your browser.

Prerequisites

  • OS: macOS or Linux. Windows is not supported in v1.
  • Node.js: ≥ 20 LTS — check with node --version.
  • Google Cloud SDK (gcloud) installed and on PATH.
  • ADC configured: run gcloud auth application-default login once.
  • Active project: run gcloud config set project <PROJECT_ID> once.

Quickstart

gcloud auth application-default login   # once
gcloud config set project <PROJECT_ID>  # once
npx pubsub-dashboard                     # boots + opens http://127.0.0.1:4321

The block below is the verifiable quickstart — CI runs it on every PR (FR-019). It launches the server, waits for /api/health to report ok, then shuts it down. Set PUBSUB_BIN to point at a local build; it defaults to the published CLI. In CI, PUBSUB_DEMO_PROJECT lets the server boot without gcloud.

set -euo pipefail
PUBSUB_BIN="${PUBSUB_BIN:-npx pubsub-dashboard}"
PORT="${PORT:-4321}"

# Launch the loopback-only dashboard in the background.
$PUBSUB_BIN --port "$PORT" &
SERVER_PID=$!
trap 'kill "$SERVER_PID" 2>/dev/null || true' EXIT

# Poll the health endpoint until the server is ready.
ready=""
for _ in $(seq 1 40); do
  if curl -fsS "http://127.0.0.1:${PORT}/api/health" >/tmp/pubsub-health.json 2>/dev/null; then
    ready="yes"
    break
  fi
  sleep 0.25
done

test -n "$ready"
grep -q '"status":"ok"' /tmp/pubsub-health.json
echo "pubsub-dashboard health: ok"

A browser tab opens on http://127.0.0.1:4321 showing the active project ID, your identity, and a Diagnostics panel with the most recent backend operation.

GCP Resource Browser

The dashboard lets you browse all GCP projects accessible via your ADC credentials, and then inspect the Pub/Sub topics and subscriptions within each project.

Screenshot

Required IAM roles

Two roles must be granted on each project you want to browse:

| Role | Purpose | | ------------------------------------------------------------------------------------- | -------------------------------------------------------- | | roles/resourcemanager.projects.list (or resourcemanager.projects.list permission) | List all GCP projects via the Cloud Resource Manager API | | roles/pubsub.viewer | List topics and subscriptions within a project |

Grant pubsub.viewer to your account with:

gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="user:<YOUR_EMAIL>" \
  --role="roles/pubsub.viewer"

To list all your accessible projects the ADC account also needs resourcemanager.projects.list. On most GCP organisations this is already included in roles/viewer or roles/browser. If you only see a PERMISSION_DENIED error on the project list, grant it explicitly:

gcloud projects add-iam-policy-binding <PROJECT_ID> \
  --member="user:<YOUR_EMAIL>" \
  --role="roles/browser"

API endpoints

| Endpoint | Description | | -------------------------------------------- | ------------------------------------------------------------- | | GET /api/projects | Lists all GCP projects accessible to the current ADC identity | | GET /api/projects/:projectId/topics | Lists Pub/Sub topics in the given project | | GET /api/projects/:projectId/subscriptions | Lists Pub/Sub subscriptions in the given project |

All three endpoints propagate a traceId (UUID) in both the response body and the X-Trace-Id header so that individual requests can be correlated in logs.

Interface

The dashboard ships a "Kanagawa × Blade Runner" interface — a Japanese-ink palette with neon accents and HUD framing. It is presentation only: every capability of the resource browser, publisher, and receiver is unchanged. All preferences persist in localStorage and are applied before first paint (no flash of the wrong appearance); nothing leaves your machine.

  • Themes — Sumi-Ink dark (default) and Lotus light, toggled from the header.
  • Workspace layouts — switch between Rail, Triptych, and Console from the appearance settings (gear icon). Your active selection and the in-progress compose draft survive every layout change.
  • Command palette — press ⌘K / Ctrl+K (or the header ⌘K button) to jump to any project, topic, or subscription. Navigation only; type to filter, arrows to move, Enter to select, Esc to close.
  • Appearance settings — the gear icon opens theme, density (compact/regular/cozy), accent (cyan/magenta/amber/violet), and layout controls. (Neon intensity and scanlines are fixed defaults, minimized under prefers-reduced-motion.)
  • Keyboard-navigable lists — each resource list filters as you type, with ↑/↓, Home/End, Enter, and Esc, and a bounded scroll so the editors stay visible.
  • Live JSON highlighting — the publisher colorizes JSON as you type (display-only; the published bytes are exactly what you see).
  • Receiver auto-poll — opt-in Auto mode pulls every 2.5 s with a visible indicator; the running list is capped at the 60 newest messages. Manual Pull is always available.

Supported OS

macOS and Linux only. Windows is not supported in v1.

What's in scope (and what's not)

In scope for v1 (this release): one-command boot, gcloud ADC auth, active project + identity display, loopback-only operation with strict CSP and log redaction, and an in-app Diagnostics panel.

Out of scope for v1 (planned for feature 002+): publishing messages, subscribing/pulling messages, and JSON message composition. See docs/extension-points.md for how those features plug in without changing the boot or auth paths.

Flags

| Flag | Default | Effect | | ------------ | ------- | ------------------------------------------------------------------------------------- | | --port <n> | 4321 | Override the local port. Exits non-zero with a clear error if the port is in use. | | --verbose | off | Raise log level to debug. Payloads are revealed in logs; credentials stay redacted. | | --help | — | Print the flag list and exit 0. | | --version | — | Print the version and exit 0. |

Troubleshooting

| Symptom | Cause | Fix | | ------------------------------- | ----------------------- | -------------------------------------------------------- | | ADC not found exit | ADC login not run | gcloud auth application-default login | | gcloud not on PATH exit | Cloud SDK not installed | Install from https://cloud.google.com/sdk/docs/install | | No active gcloud project exit | No active project | gcloud config set project <PROJECT_ID> | | Port 4321 in use exit | Port busy | npx pubsub-dashboard --port 5173 | | Requires Node >= 20 LTS exit | Node too old | Install / switch to Node 20 LTS+ | | Browser does not open | No default browser | Open the printed URL manually |

Stop

Press Ctrl+C. The server stops within 1 second, releases the port, and leaves no orphan processes.

Contributing

See docs/contributing.md for the local verification workflow and CI / branch-protection setup.