Installation

This tutorial builds a small event-sourced User model backed by PostgreSQL. You need Node.js 22 or newer, a NestJS 10 or 11 application, and a PostgreSQL database that your application can reach.

Install the packages

Install the core library, the PostgreSQL adapter, and the adapter's pg peer dependency:

pnpm add @event-nest/core @event-nest/postgresql pg

Your application must also have these peer dependencies:

  • @nestjs/common
  • @nestjs/core
  • reflect-metadata
  • rxjs

A standard Nest application already includes them.

Prepare PostgreSQL

The tutorial uses a schema named event_nest. Create the database and schema before starting the application. Event Nest can create its tables, but it does not create the schema itself.

CREATE DATABASE event_nest;
sql

Connect to that database, then create the schema:

CREATE SCHEMA IF NOT EXISTS event_nest;
sql

Set the connection string in your environment:

export DATABASE_URL="postgresql://postgres:password@localhost:5432/event_nest"
bash

Configure the adapter

Import EventNestPostgreSQLModule once in the application root:

src/app.module.ts
import { EventNestPostgreSQLModule } from "@event-nest/postgresql";
import { Module } from "@nestjs/common";

@Module({
    imports: [
        EventNestPostgreSQLModule.forRoot({
            aggregatesTableName: "aggregates",
            connectionUri: process.env.DATABASE_URL ?? "postgresql://postgres:password@localhost:5432/event_nest",
            ensureTablesExist: true,
            eventsTableName: "events",
            schemaName: "event_nest"
        })
    ]
})
export class AppModule {}
ts

forRoot() registers a global module and exports the event store under the EVENT_STORE injection token. The important options are:

OptionPurpose
connectionUriPostgreSQL connection string.
schemaNameExisting schema that owns the Event Nest tables.
aggregatesTableNameStores each aggregate ID and current version.
eventsTableNameStores the ordered event history and payloads.
ensureTablesExistCreates missing tables during application bootstrap when true. Defaults to false.

Automatic initialization is convenient for this tutorial. For production, migrations are usually preferable because initialization errors are logged and the application must still be operated with a known schema.

Snapshots are intentionally disabled for this tutorial to keep things simple.

Check the connection

Start the Nest application once. With ensureTablesExist: true, the event_nest.aggregates and event_nest.events tables should exist after bootstrap. No row is written until an aggregate commits an event.

Next, define the events, aggregate, repository provider, and application service in Your First Aggregate .

Last update at: 2026/09/02 00:14