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

@bull-board/cli

v9.10.1

Published

Run the bull-board dashboard against a Redis instance from the command line.

Readme

@bull-board/cli

Run the bull-board dashboard against a Redis instance, no app to wire it into.

npx @bull-board/cli -r redis://localhost:6379

That opens http://127.0.0.1:3000 with the dashboard for every Bull and BullMQ queue it finds under the bull key prefix.

bull-board dashboard

When you'd reach for this

  • The workers live in a repo or a container you are not editing, and you want to watch jobs move without adding a route to an app you would then have to remember to remove.
  • Your producers are not Node. BullMQ has an official Python package and gets written to over the raw protocol from other languages. Those teams have no app to embed the dashboard into.
  • You want to look at a queue on staging or production through a tunnel, without deploying anything.
  • You are evaluating bull-board and would rather see your own queues than wire up an integration first.

This is not a replacement for mounting an adapter in your own server: there's no auto-login, no framework-level auth to inherit, and every option has to be passed on the command line, an env var, or a config file instead of code.

Options

Usage:
  bull-board [options]
  npx @bull-board/cli [options]

Options:
  -r, --redis <url>       Redis connection URL          [redis://localhost:6379]
      --sentinel <list>   Comma separated sentinel host:port list, port [26379]
      --sentinel-name <n> Redis master group name, required with --sentinel
      --sentinel-password <pass>
                          Password for the sentinel nodes themselves
      --redis-username <name>
                          Username for the Redis nodes behind the sentinels
      --redis-password <pass>
                          Password for the Redis nodes behind the sentinels
      --redis-db <n>      Database to select behind the sentinels
  -p, --port <port>       Port to listen on             [3000]
      --host <address>    Interface to bind             [127.0.0.1]
      --prefix <list>     Comma separated key prefixes  [bull]
      --queues <list>     Use these queue names instead of discovering
      --scan-interval <s> Seconds between rescans, 0 to scan once  [10]
      --base-path <path>  Serve the dashboard under a path prefix
      --read-only         Disable every destructive action
      --user <name>       Basic auth user (requires --password)
      --password <pass>   Basic auth password (requires --user)
      --board-title <s>   Dashboard title
      --history           Record and serve long-retention metrics history
      --history-retention-days <n>
                          Days of history to keep            [90]
      --config <file>     Path to a config file
      --browser <command> Command to open the browser with     [$BROWSER]
      --no-open           Do not open a browser
      --no-retry          Exit if Redis is unreachable instead of retrying
  -h, --help              Show this help
  -v, --version           Show the version

Every flag also has an environment variable equivalent (BULL_BOARD_REDIS_URL, BULL_BOARD_PORT, BULL_BOARD_READ_ONLY, and so on), and a bull-board.config.{mjs,js,cjs,json} file for anything that doesn't fit on a command line. Flags win over environment variables, which win over the config file, which wins over the built-in default.

If Redis is unreachable when the CLI starts, it still opens: it serves a diagnostic page explaining why (the URL it dialled, the underlying error, and the likely causes), keeps retrying every 3 seconds, and switches to the real dashboard on its own the moment Redis answers, no restart needed. That only covers startup, though: once the dashboard is live it stays live, even if Redis later goes away. The diagnostic page does not come back; API requests just stop returning until Redis is reachable again, and Ctrl-C still works. Pass --no-retry for the old behaviour instead: print the error and exit 1 immediately, without ever opening a port, which is what a script or CI checking the exit code wants.

// bull-board.config.js
module.exports = {
  redis: 'redis://localhost:6379',
  prefix: ['bull', 'tenant-a'],
  uiConfig: {
    boardTitle: 'Ops Dashboard',
  },
  queues: {
    'payment-webhooks': { readOnlyMode: true },
  },
};

Redis Sentinel

--sentinel connects through Redis Sentinel rather than to one instance directly, for a deployment where the master address is not fixed:

npx @bull-board/cli --sentinel s1.internal:26379,s2.internal:26379 --sentinel-name mymaster

A port is optional per entry and defaults to 26379. --sentinel-name is the master group name from your sentinel configuration and is required. --sentinel and --redis are mutually exclusive, and passing both is an error rather than a silent preference for one.

ioredis resolves the current master through the sentinels listed and follows a failover on its own, so the whole dashboard moves with it: queue reads, the Bull subscriber, and --history recording all share the one connection.

Credentials in sentinel mode come from their own flags, since there is no URL to carry them. --redis-username, --redis-password and --redis-db apply to the Redis nodes behind the sentinels, while --sentinel-password authenticates to the sentinel nodes themselves, which commonly have a different password. Passing any of them alongside a Redis URL is an error, because ioredis would take the URL's own credentials and ignore them.

For anything beyond that, including TLS to the sentinel nodes, the config file's redis key accepts a full ioredis options object and is passed through untouched:

// bull-board.config.js
module.exports = {
  redis: {
    sentinels: [
      { host: 's1.internal', port: 26379 },
      { host: 's2.internal', port: 26379 },
    ],
    name: 'mymaster',
    sentinelPassword: process.env.SENTINEL_PASSWORD,
    enableTLSForSentinelMode: true,
  },
};

Historical metrics

--history turns on the long-retention metrics that otherwise need @bull-board/metrics wired into an app of your own:

npx @bull-board/cli -r redis://localhost:6379 --history

Every queue chart gains a 60m / 7d / 30d / 90d range selector, and a cross-queue Metrics history page shows up in the sidebar. The CLI process does the recording itself, copying throughput, wait time, run time and queue age into Redis once a minute under the bull-board:metrics: namespace, never over a key Bull or BullMQ owns. Recording follows discovery, so a queue that appears between rescans is picked up on the next tick.

--history-retention-days sets the window, 90 days by default. Per-tier retention, the snapshot interval and latency: false go in the config file under a history key. --read-only keeps the reading and stops the writing, for a board that only displays what another process records.

Completed and failed history comes out of BullMQ's own metrics buffer, so it stays empty unless your workers were built with metrics: { maxDataPoints: MetricsTime.ONE_WEEK }; the CLI warns at startup when no discovered queue has any. Latency and queue age need nothing from your workers. See the historical metrics recipe for storage sizing and what the charts show.

Docker

docker run --rm -p 127.0.0.1:3000:3000 \
  -e BULL_BOARD_USER=admin -e BULL_BOARD_PASSWORD=secret \
  ghcr.io/felixmosh/bull-board --redis redis://host.docker.internal:6379

ghcr.io/felixmosh/bull-board is this package as an image, built for amd64 and arm64 on every release and tagged with the exact version, the major, and latest. The entrypoint is the CLI, so flags and BULL_BOARD_* variables work exactly as they do above. The only things the image decides for you are BULL_BOARD_HOST=0.0.0.0 and BULL_BOARD_OPEN=false, the two defaults that make no sense in a container, and you can override both. Run with Docker covers Compose, tags and mounting a config file.

Discovery only reads Redis, so BullMQ v6 queues backed by PostgreSQL aren't found here; use a server adapter in your own app for those. --prefix doesn't take wildcards either, list the prefixes you need explicitly.

See the CLI guide for the full flag and environment variable reference and the basic auth walkthrough.