# Compatibility

What is tested, what is supported but not tested, and what is not supported. "Tested" means a CI job or an integration test in the repository runs against it; the [Stability](https://berkcansavur.github.io/relaybus/stability) policy says how this list changes.

## Runtimes

|                              | Status                          | Evidence                                                                                                             |
| ---------------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| Node.js 22 (22.12 and newer) | tested                          | CI test matrix `22.x` and `24.x`                                                                                     |
| Node.js 24                   | tested                          | CI test matrix                                                                                                       |
| CommonJS and ESM             | built and type-checked for both | every package ships `import` and `require` entry points with their own types; `publint` and `attw` check them in CI  |
| NestJS 11 and 12             | tested                          | CI job `nestjs compat` re-resolves `@nestjs/*` to each major and runs the typecheck and the `@relaybus/nestjs` tests |
| Bun, Deno                    | untested, not supported         |                                                                                                                      |

## Stores

| Store               | Versions                                                              | Notes                                                                                                                                                                                     |
| ------------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PostgreSQL          | 13 and newer; integration tests run on 13 and 17                      | `pg` is the primary client and the only one with prepared statements.                                                                                                                     |
| `pg` pool or client | tested                                                                | `PostgresEventStore({ pool })`                                                                                                                                                            |
| Kysely              | integration tested                                                    | `createKyselyExecutor`                                                                                                                                                                    |
| Knex                | integration tested                                                    |                                                                                                                                                                                           |
| TypeORM             | integration tested                                                    |                                                                                                                                                                                           |
| Drizzle             | integration tested                                                    |                                                                                                                                                                                           |
| Prisma              | integration tested (Client 5.22, 6.19 and 7.10, `@prisma/adapter-pg`) | Full contract suite on a generated client. Give the store your `pg` pool as well for prepared statements and wake-ups at commit.                                                          |
| MongoDB             | 6.0 and newer, integration tests on 7                                 | **Replica set or sharded cluster only**: relaybus uses multi-document transactions. A single-node replica set is enough for development. Driver `mongodb` 6 or 7; Mongoose sessions work. |

## Transports

| Transport                                   | Tested                                                                            | Notes                                                                                                                                                                                                                                                                 |
| ------------------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Kafka with `kafkajs` 2.2.x                  | integration tested against a real broker (`confluentinc/cp-kafka:7.5.0`), 2.2.4   | `kafkajs` is **unmaintained**. It stays supported and is the default `client`; prefer Confluent for new services.                                                                                                                                                     |
| Kafka with `@confluentinc/kafka-javascript` | integration tested against the same broker, 1.11.0 (KafkaJS-compatible API)       | **Recommended**: maintained and librdkafka based. Pass `client: 'confluent'`; the transport puts its settings in the `kafkaJS` blocks and follows the group through `rebalance_cb`. Peer range `^1.11.0`. See [Choosing a client](https://berkcansavur.github.io/relaybus/packages/kafka#choosing-a-client). |
| RabbitMQ                                    | integration tested on RabbitMQ 4 (`rabbitmq:4-alpine`); 3.13 or newer is required | **Quorum queues** are used for the queue and the dead-letter queue. `amqplib` 0.10 or newer.                                                                                                                                                                          |

### Codecs

| Codec                         | Kafka                | RabbitMQ             |
| ----------------------------- | -------------------- | -------------------- |
| `cloudEventsBinary` (default) | tested, golden bytes | tested, golden bytes |
| `cloudEventsStructured`       | tested               | tested               |
| `jsonEnvelope({ ... })`       | tested               | tested               |
| `{ encode, decode }` (custom) | tested               | tested               |

## Explicitly unsupported

These are not planned for the current release line; no store or transport exists for them.

|                                                         | Why / what to use                                                                                                                                                             |
| ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| MySQL, SQL Server, SQLite                               | No store. relaybus needs `SELECT ... FOR UPDATE SKIP LOCKED`-style claims, advisory locks and a transactional outbox in your database; PostgreSQL and MongoDB are the stores. |
| MongoDB standalone                                      | No multi-document transactions. Use a replica set.                                                                                                                            |
| Amazon SQS and SNS, NATS, Google Pub/Sub, Redis Streams | No transport. Implement the small `Transport` interface (`publish`, `subscribe`, `close`) yourself if you need one; it is not tested by relaybus.                             |
| Bun, Deno                                               | Untested.                                                                                                                                                                     |

## Serverless and short-lived processes

relaybus delivers from a long-running dispatcher: it claims deliveries on a poll and, on PostgreSQL, wakes on `LISTEN`/`NOTIFY`, and it holds leases while a handler runs. A process that is frozen or killed between requests cannot do that.

- **Publishing from a function works**: publish inside your database transaction and let the commit make the event durable. Set `dispatcher: { enabled: false }` in the function and run the dispatcher in a long-running worker ([Tuning](https://berkcansavur.github.io/relaybus/tuning)).
- **Dispatching from a function** is possible only by calling `bus.runOnce()` per invocation (one batch) and finishing before the platform freezes the process. Expect higher latency, no `NOTIFY` wake-ups, and leases that expire when an invocation is cut short, which makes the delivery run again (at-least-once holds).
- Behind a connection pooler in transaction mode, use the settings in [Tuning](https://berkcansavur.github.io/relaybus/tuning) (`wakeUp: 'poll'`, `preparedStatements: false` where needed).

## Where this is checked

CI (`.github/workflows/ci.yml`): `quality` (Prettier, ESLint, typecheck, performance budgets), `test` on Node 22 and 24 with 100 % coverage thresholds, `build` (all packages, `publint`, `attw`), `nestjs-compat` on NestJS 11 and 12. Integration tests start their databases and brokers with Testcontainers.
