Skip to content

Installation

This library consists of a core module @ocoda/event-sourcing that provides the building blocks and can be complemented with an integration library for setting up a persistence layer for your events using a specific database provider.

By default the core library will use an in-memory event- and snapshot-store, which is useful for testing and prototyping, but not recommended for production use.

The packages require Node.js 22.12 or later and NestJS 12. They are published as ES modules only: CommonJS applications can keep using require() (or TypeScript’s CommonJS output), which Node.js supports for ES modules since 22.12. TypeScript projects need TypeScript 5.4 or later: the typed buses use NoInfer in their type declarations.

The database drivers are peer dependencies of the integration libraries, so you install the driver next to the integration and choose its version yourself. TypeScript projects using PostgreSQL also need @types/pg and @types/pg-cursor.

Upgrading an application from 3.x? Follow Migrating from 3.x to 4.0. Want to see the pieces of these guides together first? The example application runs on PostgreSQL and starts with docker compose.

  1. Terminal window
    pnpm add @ocoda/event-sourcing
  2. MariaDB or MySQL

    Terminal window
    pnpm add @ocoda/event-sourcing-mariadb mariadb

    MongoDB

    Terminal window
    pnpm add @ocoda/event-sourcing-mongodb mongodb

    PostgreSQL

    Terminal window
    pnpm add @ocoda/event-sourcing-postgres pg pg-cursor

    From 4.1, the MariaDB integration also runs on MySQL, with the same mariadb connector. To sign in to MySQL over TCP without TLS, the connector needs allowPublicKeyRetrieval: true or the server’s public key (cachingRsaPublicKey): see Connecting to MySQL. For managed services, servers that are compatible with one of these databases, and the databases that aren’t supported, see Other databases.

For setting up the module you need to import the EventSourcingModule and configure it.

For the basic setup you don’t need to configure a store, the module falls back to an in-memory event- and snapshot-store. The events array, an array of event classes that are used to define the events, is optional: you can also register the events per feature module, see Module configuration. While this is great for testing and prototyping, you won’t be able to persist the events and snapshots. If you require persistence skip to the advanced setup.

import { Module } from '@nestjs/common';
import { EventSourcingModule } from '@ocoda/event-sourcing';
import {
AccountOpenedEvent,
AccountCreditedEvent,
AccountDebitedEvent,
AccountClosedEvent,
} from './app.providers';
@Module({
imports: [
EventSourcingModule.forRoot({
events: [
AccountOpenedEvent,
AccountCreditedEvent,
AccountDebitedEvent,
AccountClosedEvent,
],
}),
],
})
export class AppModule {}

If you want to use a specific database provider for event- and snapshot-persistence you need to provide the eventStore and snapshotStore configuration. Each integration library comes with a driver and interface to indicate which parameters are required for connecting to the specified store. For the other ways to configure the module, such as the forRoot and forRootAsync variants, see Module configuration.

import { Events } from './app.providers';
import { PostgresEventStore, type PostgresEventStoreConfig } from '@ocoda/event-sourcing-postgres';
import { MongoDBSnapshotStore, type MongoDBSnapshotStoreConfig } from '@ocoda/event-sourcing-mongodb';
@Module({
imports: [
EventSourcingModule.forRootAsync<PostgresEventStoreConfig, MongoDBSnapshotStoreConfig>({
useFactory: () => ({
events: Events,
eventStore: {
driver: PostgresEventStore,
host: '<URL>',
port: 5432,
user: '<username>',
password: '<password>',
database: '<database>',
},
snapshotStore: {
driver: MongoDBSnapshotStore,
url: '<URL>',
},
}),
}),
],
})
export class AppModule {}