Architecture

A small runtime-neutral core, and isolated provider adapters around it.

Core

The core owns message envelopes, codecs, middleware, consumers, lifecycle, errors, provider capabilities, registries, and the lazy manager. It never imports a broker SDK. That is what keeps QueueKit runnable on Node 20+, Bun, and Deno 2+ and installable with zero broker dependencies.

Adapters

Every adapter preserves native configuration, responses, incoming messages, and acknowledgements through generic types. A provider advertises only capabilities that have real semantics for that broker. QueueKit does not translate Kafka partitions into priority, or a BullMQ attempt count into an SQS delivery guarantee — normalization stops where it would start lying.

Lazy manager

createQueueManager constructs providers lazily. Calling manager.provider('events') is the point at which that provider may load its SDK; warmup() explicitly initializes all configured providers. close() is idempotent and closes initialized consumers and clients.

Repository layout

text
src/
  core/       envelope, codec, middleware, lifecycle, errors, types
  drivers/     kafka, rabbitmq, bullmq, redis, nats, sqs
  testing/     in-memory fake driver with deterministic controls
  manager.ts   lazy multi-provider manager
  registry.ts  typed destination/payload registries
  factory.ts   createQueue switch over BuiltInQueueConfig
tests/
  e2e/         produce → consume → acknowledge round-trips against live brokers

The e2e suites run against a local broker stack (docker compose up -d: Redis, RabbitMQ, Kafka, NATS, LocalStack SQS) and skip with a hint when a broker is not reachable.