Quickstart

From zero to a running worker with a dashboard in five minutes.

You need a Redis URL and Bun (or Node). That's it.

1. Install and initialize

bun add @openqueue/sdk
bun add -d @openqueue/cli
bunx openqueue init

The CLI package ships the openqueue binary — once it's installed locally, bunx openqueue resolves it from your node_modules. (Without installing first, use bunx @openqueue/cli init.)

init scaffolds a config, a starter task, .env files, and a Dockerfile, and adds worker:dev / worker:build / worker:start scripts to your package.json. The two files you'll touch:

worker.config.ts
import { defineConfig } from '@openqueue/sdk';

export default defineConfig({
  namespace: process.env.OPENQUEUE_NAMESPACE ?? 'my-app',
  dirs: ['./worker'],
  redis: { url: process.env.REDIS_URL! },
  concurrency: {
    global: 8,
  },
  workbench: {
    enabled: true,
    title: 'Jobs',
    basePath: '/workbench',
  },
});
worker/example.ts
import { task } from '@openqueue/sdk';
import { z } from 'zod';

export const exampleTask = task({
  id: 'example',
  schema: z.object({
    message: z.string().default('Hello from OpenQueue'),
  }),
  run: async (payload, ctx) => {
    ctx.logger.info('received message', { message: payload.message });
    await ctx.progress({ step: 'done' });
    return { ok: true };
  },
});

2. Run the worker

bunx openqueue dev

dev loads worker.config.ts, discovers every exported task under dirs, starts the BullMQ workers, and serves Workbench. It watches your task files and restarts on change.

Open Workbench at the printed URL and you'll see your queue, live counters, and a Test page with an editable JSON body — enqueue a job straight from the browser.

3. Trigger from your app

The worker serves a control API; createClient({ host }) binds it as the process runtime so trigger() goes over HTTP — no Redis connection in your app.

import { createClient } from '@openqueue/sdk/client';
import { exampleTask } from './worker/example';

createClient({ host: 'http://localhost:8288' });

await exampleTask.trigger({ message: 'deploy finished' });

trigger validates the payload against the schema, enqueues the job, and returns an EnqueueResult{ runId, jobId }, where runId is the durable handle you inspect run status with. Options let you delay or deduplicate:

await exampleTask.trigger(payload, { delay: 60_000 });

4. Ship it

bunx openqueue build   # compiles the worker into a Nitro artifact (.output)
bunx openqueue start   # runs the built artifact (or from source if absent)

See Deployment for Docker and production notes.

On this page