NestJS
NestJS. bull-board ships a NestJS module plus a plain adapter you can wire manually.
Install
Also install the adapter for the HTTP platform your Nest app uses (Express is the default):
Supported NestJS versions
@bull-board/nestjs supports NestJS 9, 10, 11 and 12. The suite runs against both 11 and 12 on
every CI build.
NestJS 12 ships as ESM only, so a Nest 12 application has to be ESM itself. @bull-board/nestjs
is published as CommonJS and its named exports are importable from an ESM app, so nothing about
the setup below changes on Nest 12.
Module-based setup (recommended)
Register BullBoardModule.forRoot() in your root module, then BullBoardModule.forFeature() per queue from the feature module.
forRoot() options:
route: base path where the dashboard is mounted.adapter: server adapter class (ExpressAdapterorFastifyAdapter).boardOptions: forwarded tocreateBullBoard(e.g.uiConfig,uiBasePath).middleware: optional Express/Fastify middleware (basic auth, etc.).
forFeature() options (pass either name or queue):
name: queue name registered withBullModule.registerQueue. The module resolves the instance from Nest's DI container.queue: a queue instance to register directly, instead of resolving it byname. See Queues with the same name below.adapter:BullMQAdapterorBullAdapter.options: queue adapter options likereadOnlyModeordescription.
To register several queues at once, pass multiple option objects:
Queues with the same name
@nestjs/bullmq builds a queue's DI token from its name alone, and the prefix is not part of it. So if you run the same queue name under two prefixes (a common multi-tenant setup), both share one DI token and a name lookup can only ever return one of them. Registering both by name makes one queue shadow the other on the board.
Pass the instances directly via queue instead. Hold the queues somewhere you control (a provider, a service, wherever you created them) and hand them to forFeature:
The board keys entries by prefix + name, so the two show up as tenant-a:emails and tenant-b:emails. Set each adapter's prefix to match the queue's own prefix so the labels line up.
There's also BullBoardModule.forRootAsync() which accepts useFactory, imports, inject for dynamic config.
You can inject the board instance anywhere:
Plain adapter setup
If you'd rather wire the server adapter yourself (custom middleware, existing Nest conventions), do it in a module's configure():
Full runnable examples
- NestJS module (recommended):
examples/with-nestjs-module - Plain adapter:
examples/with-nestjs - Fastify platform with auth:
examples/with-nestjs-fastify-auth
Next steps
- UIConfig: title, logo, locale, polling.
- Read-only mode: disable destructive actions.
- Visibility guard: scope visible queues per request.
- Formatters: rewrite job fields for the UI.