Embedded
NestJS
Mount Bullstudio as a NestJS dashboard module.
Bullstudio supports NestJS applications running on the Express or Fastify platform adapter.
Install
pnpm add @bullstudio/nestjs @bullstudio/bullmq-adapter bullmq ioredisInstall the Nest platform your app already uses:
pnpm add @nestjs/common @nestjs/core @nestjs/platform-expressor:
pnpm add @nestjs/common @nestjs/core @nestjs/platform-fastifyMount with dependency injection
Use BullstudioModule.forRootAsync() when queues are provided by Nest dependency injection.
import { createBullMqQueueAdapter } from "@bullstudio/bullmq-adapter";
import { BullstudioModule } from "@bullstudio/nestjs";
import { Module } from "@nestjs/common";
import { Queue } from "bullmq";
import IORedis from "ioredis";
export const REDIS_CONNECTION = Symbol("REDIS_CONNECTION");
export const EMAIL_QUEUE = Symbol("EMAIL_QUEUE");
@Module({
providers: [
{
provide: REDIS_CONNECTION,
useFactory: () =>
new IORedis(process.env.REDIS_URL!, {
maxRetriesPerRequest: null,
}),
},
{
provide: EMAIL_QUEUE,
inject: [REDIS_CONNECTION],
useFactory: (connection: IORedis) => new Queue("email", { connection }),
},
],
exports: [REDIS_CONNECTION, EMAIL_QUEUE],
})
export class QueueModule {}
@Module({
imports: [
QueueModule,
BullstudioModule.forRootAsync({
imports: [QueueModule],
inject: [EMAIL_QUEUE],
useFactory: (emailQueue: Queue) => ({
mountPath: "/ops/bullstudio",
queues: [
createBullMqQueueAdapter(emailQueue, {
key: "email",
label: "Email",
}),
],
protection: {
type: "session",
username: process.env.BULLSTUDIO_USERNAME ?? "operator",
password: process.env.BULLSTUDIO_PASSWORD!,
sessionSecret: process.env.BULLSTUDIO_SESSION_SECRET!,
},
}),
}),
],
})
export class AppModule {}Open http://localhost:3000/ops/bullstudio.
Mount directly
Use BullstudioModule.forRoot() when queue adapters can be created directly.
import { createBullMqQueueAdapter } from "@bullstudio/bullmq-adapter";
import { BullstudioModule } from "@bullstudio/nestjs";
import { Module } from "@nestjs/common";
import { Queue } from "bullmq";
import IORedis from "ioredis";
const connection = new IORedis(process.env.REDIS_URL!, {
maxRetriesPerRequest: null,
});
const emailQueue = new Queue("email", { connection });
@Module({
imports: [
BullstudioModule.forRoot({
mountPath: "/ops/bullstudio",
queues: [
createBullMqQueueAdapter(emailQueue, {
key: "email",
label: "Email",
}),
],
protection: {
type: "session",
username: process.env.BULLSTUDIO_USERNAME ?? "operator",
password: process.env.BULLSTUDIO_PASSWORD!,
sessionSecret: process.env.BULLSTUDIO_SESSION_SECRET!,
},
}),
],
})
export class AppModule {}Mount path
mountPath is the public dashboard URL. Bullstudio mounts directly on the underlying Express or Fastify server and does not use app.setGlobalPrefix().
Bullstudio only shows supplied queues. It does not create queues, register processors, or own the queue and Redis connection lifecycle.