Noureddine RAMDI / QueueDash: A unified tRPC dashboard for Bull, BullMQ, Bee-Queue, and GroupMQ job queues

Created Tue, 05 May 2026 13:37:39 +0000 Modified Sat, 23 May 2026 20:41:27 +0000

alexbudure/queuedash

Queue management libraries in Node.js like Bull, BullMQ, Bee-Queue, and GroupMQ each come with their own APIs and quirks, making it a headache to monitor and manage multiple queue types in one place. QueueDash tackles this by providing a unified dashboard that abstracts these different backends behind a single type-safe API and a React-based UI. It’s a practical approach for teams running diverse job queues who want a consistent monitoring interface.

What QueueDash does and how it’s built

QueueDash is a TypeScript project split into two main packages: @queuedash/api and @queuedash/ui. The API package exposes a tRPC router that provides type-safe endpoints for queue operations, abstracting over multiple queue libraries including Bull, BullMQ, Bee-Queue, and GroupMQ. This abstraction is especially useful given these libraries differ in how they handle jobs, events, and metadata.

The UI package is a React dashboard that consumes the tRPC API to display queue states, job details, and statistics. The UI is designed to be clean and compact, positioning itself as a modern alternative to older tools like bull-board and bull-arena.

QueueDash supports integration with several popular Node.js frameworks: Express, Fastify, and Next.js (both App Router and Pages Router). This flexibility allows developers to embed the dashboard into their existing apps without major architectural changes.

Under the hood, the API middleware pattern allows injecting different queue instances and types, configured through environment variables or code. Docker support is included, facilitating standalone deployment with queue configuration passed as environment variables.

How QueueDash handles multi-queue abstraction and type safety

The standout technical aspect is the API layer’s use of tRPC combined with a middleware pattern to abstract multiple queue backends. Each queue type differs significantly — Bull and BullMQ have Redis-backed architectures but different APIs, Bee-Queue is simpler, and GroupMQ has its own semantics.

QueueDash models these differences through a shared interface with discriminated unions (e.g., a type field distinguishing queue libraries) and adapter layers. This lets the tRPC router expose a consistent set of operations like listing jobs, retrying, or cleaning queues, regardless of the underlying library.

This approach trades some complexity in maintaining type definitions and adapters for a unified developer experience: consumers of the API interact with a single contract rather than multiple incompatible ones.

The codebase is surprisingly clean and modular, with clear separation between the core API logic, queue adapters, and UI components. The React UI uses modern hooks and components, styled with CSS imported from the package. The dashboard UI focuses on compactness and clarity, avoiding the clutter common in older queue UIs.

Integrating with Next.js is notably well documented, with example code showing how to set up API routes using fetchRequestHandler from tRPC and how to embed the QueueDashApp React component in both App Router and Pages Router setups. This makes it straightforward to add queue monitoring as an admin panel in existing Next.js apps.

Quick start with Express and Next.js

The repo README includes precise code examples for getting started quickly.

For Express, after installing @queuedash/api:

import express from "express";
import Bull from "bull";
import { createQueueDashExpressMiddleware } from "@queuedash/api";

const app = express();
const reportQueue = new Bull("report-queue");

app.use(
  "/queuedash",
  createQueueDashExpressMiddleware({
    ctx: {
      queues: [
        {
          queue: reportQueue,
          displayName: "Reports",
          type: "bull" as const,
        },
      ],
    },
  }),
);

app.listen(3000, () => {
  console.log("Listening on port 3000");
  console.log("Visit http://localhost:3000/queuedash");
});

This snippet shows how to wrap an Express app with QueueDash middleware, passing an array of queues with their types and display names.

For Next.js App Router, the integration involves two parts: an API route handler using tRPC’s fetchRequestHandler and a React component importing QueueDashApp from the UI package:

// app/admin/queuedash/[[...slug]]/page.tsx
"use client";

import { QueueDashApp } from "@queuedash/ui";
import "@queuedash/ui/dist/styles.css";

function getBaseUrl() {
  if (process.env.VERCEL_URL) {
    return `https://${process.env.VERCEL_URL}/api/queuedash`;
  }
  return `http://localhost:${process.env.PORT ?? 3000}/api/queuedash`;
}

export default function QueueDashPages() {
  return <QueueDashApp apiUrl={getBaseUrl()} basename="/admin/queuedash" />;
}
// app/api/queuedash/[...trpc]/route.ts
import { fetchRequestHandler } from "@trpc/server/adapters/fetch";
import { appRouter } from "@queuedash/api";
import Bull from "bull";

const reportQueue = new Bull("report-queue");

function handler(req: Request) {
  return fetchRequestHandler({
    endpoint: "/api/queuedash",
    req,
    router: appRouter,
    allowBatching: true,
    createContext: () => ({
      queues: [
        {
          queue: reportQueue,
          displayName: "Reports",
          type: "bull" as const,
        },
      ],
    }),
  });
}

export { handler as GET, handler as POST };

This pattern cleanly separates API handling and UI rendering, while preserving type safety end-to-end.

Verdict: who should consider QueueDash

QueueDash is relevant for Node.js teams running multiple job queues across Bull, BullMQ, Bee-Queue, or GroupMQ and wanting a unified, modern dashboard. Its tRPC-based API abstraction and React UI provide a clean developer experience and a consistent interface across queue backends.

The repo’s tradeoff is the complexity of maintaining adapters and type definitions for multiple queue libraries, which means it may not expose 100% of every backend’s unique features. Also, it’s focused on monitoring and job management rather than job creation or orchestration.

If you’re currently juggling multiple dashboards or struggling with older tools like bull-board, QueueDash is worth trying. The integration examples for Express and Next.js lower the barrier to adoption.

Overall, QueueDash balances practical engineering tradeoffs to solve a real problem with a clean, extensible architecture and a type-safe API surface that fits well into modern TypeScript backend and frontend stacks.


→ GitHub Repo: alexbudure/queuedash ⭐ 414 · TypeScript