Next.js & Vercel
There is no dedicated Next.js adapter — bull-board runs inside a Next.js API route using an existing adapter. Two runnable examples:
examples/with-nextjs-app— App Router,@bull-board/honoadapter.examples/with-nextjs-pages— Pages Router,@bull-board/expressadapter.
Both deploy to Vercel. The mounting differs by router; the Vercel-specific config is identical and is the part most people miss.
App Router (Hono)
A single optional catch-all Route Handler at
app/api/queues/[[...path]]/route.ts:
Pages Router (Express)
A single optional catch-all API route at pages/api/queues/[[...path]].ts that
delegates to an Express router. Disable bodyParser and enable
externalResolver so Express owns the response:
The Vercel fix (both routers)
@bull-board/api finds the UI's compiled assets with
eval(require.resolve('@bull-board/ui/package.json')). The eval deliberately
hides the require from bundlers — and that includes Next.js's static file tracer
(@vercel/nft). On Vercel the UI files are
never copied into the function, so you get:
Fix it in next.config.js:
If node_modules is hoisted to a workspace root (e.g. apps/web in a Turborepo),
add outputFileTracingRoot: path.join(__dirname, '../../') so the included paths
resolve from the right place.
serverExternalPackages and outputFileTracingIncludes are stable top-level
options in Next.js 15+ (in 13/14 they lived under experimental).
Alternative: uiBasePath
Instead of the trace config you can tell bull-board where the UI lives directly,
skipping the eval(require.resolve(...)) entirely:
You still need outputFileTracingIncludes so the files are actually deployed —
this only changes how the path is resolved, not whether the files are present.
Workers
BullMQ workers are long-running and cannot run inside serverless functions.
Next.js (the dashboard and any job-producing routes) deploys to Vercel; the
worker runs as a separate always-on process — a container, a VM, or a dedicated
worker service. Both examples ship a standalone worker.ts for local
processing.