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
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 brokersThe 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.