Quick Start — Build Your First Bun Job Queue in 5 Minutes
This guide will get you up and running with bunqueue in 5 minutes.
Choose Your Mode
Section titled “Choose Your Mode”bunqueue supports two deployment modes:
| Embedded Mode | TCP Server Mode | |
|---|---|---|
| Best for | Single-process apps, serverless | Multi-process, microservices |
| Setup | Zero config | Run bunqueue start first |
| Option needed | embedded: true | None (default) |
| Persistence | DATA_PATH env var | --data-path flag |
This guide covers Embedded Mode (most common). For TCP Server Mode, see Server Guide.
Create a Queue
Section titled “Create a Queue”import { Queue } from 'bunqueue/client';
// Create a typed queueinterface EmailJob { to: string; subject: string; body: string;}
const emailQueue = new Queue<EmailJob>('emails', { embedded: true });Add Jobs
Section titled “Add Jobs”// Add a single jobconst job = await emailQueue.add('send-email', { to: 'user@example.com', subject: 'Welcome!', body: 'Thanks for signing up.'});
console.log(`Job created: ${job.id}`);
// Add with optionsawait emailQueue.add('send-email', data, { priority: 10, // Higher = processed first delay: 5000, // Wait 5 seconds before processing attempts: 3, // Retry up to 3 times backoff: 1000, // Wait 1 second between retries});
// Add multiple jobs (batch optimized)await emailQueue.addBulk([ { name: 'send-email', data: { to: 'a@test.com', subject: 'Hi', body: '...' } }, { name: 'send-email', data: { to: 'b@test.com', subject: 'Hi', body: '...' } },]);Create a Worker
Section titled “Create a Worker”import { Worker } from 'bunqueue/client';
const worker = new Worker<EmailJob>('emails', async (job) => { console.log(`Processing: ${job.name}`);
// Update progress await job.updateProgress(50, 'Sending email...');
// Do the work await sendEmail(job.data);
// Log messages await job.log('Email sent successfully');
// Return a result return { sent: true, timestamp: Date.now() };}, { embedded: true, // Required for embedded mode concurrency: 5, // Process 5 jobs in parallel});Handle Events
Section titled “Handle Events”worker.on('completed', (job, result) => { console.log(`Job ${job.id} completed:`, result);});
worker.on('failed', (job, error) => { console.error(`Job ${job.id} failed:`, error.message);});
worker.on('progress', (job, progress) => { console.log(`Job ${job.id} progress: ${progress}%`);});
worker.on('active', (job) => { console.log(`Job ${job.id} started`);});Full Example
Section titled “Full Example”import { Queue, Worker, shutdownManager } from 'bunqueue/client';
interface EmailJob { to: string; subject: string;}
// Producer - must have embedded: trueconst queue = new Queue<EmailJob>('emails', { embedded: true });
// Add some jobsawait queue.add('welcome', { to: 'new@user.com', subject: 'Welcome!' });await queue.add('newsletter', { to: 'sub@user.com', subject: 'News' });
// Consumer - must have embedded: trueconst worker = new Worker<EmailJob>('emails', async (job) => { console.log(`Sending ${job.data.subject} to ${job.data.to}`); await job.updateProgress(100); return { sent: true };}, { embedded: true, concurrency: 3 });
worker.on('completed', (job) => { console.log(`✓ ${job.id}`);});
// Graceful shutdownprocess.on('SIGINT', async () => { await worker.close(); shutdownManager(); process.exit(0);});With Persistence (SQLite)
Section titled “With Persistence (SQLite)”To persist jobs across restarts, pass dataPath in the constructor or set DATA_PATH before importing:
import { Queue, Worker } from 'bunqueue/client';
// Option 1: Pass dataPath directly (recommended)const queue = new Queue('tasks', { embedded: true, dataPath: './data/bunqueue.db' });const worker = new Worker('tasks', processor, { embedded: true, dataPath: './data/bunqueue.db' });
// Option 2: Environment variable// DATA_PATH=./data/bunqueue.db bun run app.tsSimple Mode (All-in-One)
Section titled “Simple Mode (All-in-One)”Want less boilerplate? Bunqueue wraps Queue + Worker in a single object with routes, middleware, cron, and more:
import { Bunqueue } from 'bunqueue/client';
const app = new Bunqueue('notifications', { embedded: true, routes: { 'send-email': async (job) => { await sendEmail(job.data.to); return { sent: true }; }, 'send-sms': async (job) => { await sendSMS(job.data.to); return { sent: true }; }, }, concurrency: 10,});
// Middleware (wraps every job)app.use(async (job, next) => { const start = Date.now(); const result = await next(); console.log(`${job.name}: ${Date.now() - start}ms`); return result;});
// Cron jobsawait app.cron('daily-report', '0 9 * * *', { type: 'summary' });
// Add jobsawait app.add('send-email', { to: 'alice@example.com' });
// Graceful shutdownawait app.close();Simple Mode also includes circuit breaker, batch processing, TTL, priority aging, deduplication, and debouncing. See Simple Mode guide for the full reference.
Connect AI Agents (MCP)
Section titled “Connect AI Agents (MCP)”bunqueue includes a native MCP server with 73 tools. AI agents can schedule tasks, manage pipelines, and monitor queues via natural language — no code needed.
# Claude Codeclaude mcp add bunqueue -- bunx bunqueue-mcp// Claude Desktop / Cursor / Windsurf{ "mcpServers": { "bunqueue": { "command": "bunx", "args": ["bunqueue-mcp"] } }}Once connected, agents can add jobs, manage crons, retry failures, set rate limits, and monitor everything. See MCP Server guide for the full reference.
Workflow Engine
Section titled “Workflow Engine”Need to orchestrate multi-step processes? bunqueue includes a built-in Workflow Engine with branching, saga compensation, and human-in-the-loop signals:
import { Workflow, Engine } from 'bunqueue/workflow';
const flow = new Workflow('order-pipeline') .step('validate', async (ctx) => { const { orderId } = ctx.input as { orderId: string }; return { orderId }; }) .step('charge', async (ctx) => { return { txId: 'tx_123' }; }, { compensate: async () => { // Auto-rollback if a later step fails await refundPayment('tx_123'); }, }) .waitFor('manager-approval') // Pauses until signal received .step('ship', async (ctx) => { const approval = ctx.signals['manager-approval']; return { shipped: true }; });
const engine = new Engine({ embedded: true });engine.register(flow);
const run = await engine.start('order-pipeline', { orderId: 'ORD-1' });
// Later, when the manager approves:await engine.signal(run.id, 'manager-approval', { approved: true });Built on top of bunqueue’s Queue and Worker — no new infrastructure. Workflow Engine guide for the full reference.
Next Steps
Section titled “Next Steps”- Workflow Engine - Multi-step orchestration with branching and saga compensation
- Simple Mode - All-in-one Queue + Worker with routes, middleware, cron
- Queue API - Full queue operations
- Worker API - Worker configuration
- MCP Server - Connect AI agents (Claude, Cursor, Windsurf)
- Server Mode - Run bunqueue as a standalone server
- Code Examples & Recipes - More complete examples