0PricingLogin
Node.js Backend Development Bootcamp · Lesson

Events as the Source of Truth and the Append-Only Log

Replace mutable state with an immutable event stream and reconstruct state by replaying events.

The Problem with Mutable State

In a classic CRUD backend, you store the current state of an entity and overwrite it on every change. A user's balance is one row; when money moves, you UPDATE the number in place.

This is convenient but lossy. Once you overwrite the old value, the history is gone. You cannot answer:

  • How did the balance reach this value?
  • When and why did each change happen?
  • What did the state look like last Tuesday?

Event Sourcing flips this: instead of storing the latest state, you store the sequence of facts that produced it.

// Classic mutable CRUD: history is destroyed on every write
let account = { id: 'acc-1', balance: 100 };

function deposit(amount) {
  account.balance += amount; // old value is gone forever
}

function withdraw(amount) {
  account.balance -= amount; // no record of why or when
}

deposit(50);
withdraw(30);
console.log(account); // { id: 'acc-1', balance: 120 }
// We know the result, but not the journey.

Events as the Source of Truth

In Event Sourcing, an event is an immutable record of something that already happened. Events are named in the past tense: MoneyDeposited, MoneyWithdrawn, AccountOpened.

The event log becomes the source of truth. The current state is no longer stored directly — it is a derived value you compute by replaying events.

  • Events are facts: they cannot be changed or deleted.
  • State is an opinion: a projection of the facts at a point in time.

Each event captures intent and context, not just the resulting number.

// An event is an immutable, past-tense fact
const events = [
  { type: 'AccountOpened',  data: { accountId: 'acc-1', owner: 'Ada' }, at: '2026-01-01T09:00:00Z' },
  { type: 'MoneyDeposited', data: { accountId: 'acc-1', amount: 50 },  at: '2026-01-02T10:15:00Z' },
  { type: 'MoneyWithdrawn', data: { accountId: 'acc-1', amount: 30 },  at: '2026-01-03T11:30:00Z' }
];

// Each entry is a fact that already happened. Nothing is overwritten.
console.log(`Stored ${events.length} immutable facts.`);

All lessons in this course

  1. Events as the Source of Truth and the Append-Only Log
  2. Aggregates, Commands, and Domain Event Modeling
  3. Building Read Models and Projections
  4. Snapshots, Versioning, and Event Schema Evolution
← Back to Node.js Backend Development Bootcamp