# Emmett: event sourcing for Node.js without the ceremony

> Emmett is an opinionated but flexible event sourcing framework for Node.js, with pluggable event stores for PostgreSQL, EventStoreDB, MongoDB, SQLite and in-memory storage, built-in projections, and testing utilities that use BDD-style syntax. It suits a Node team that wants events as the source of truth, and its licensing is still being decided.

**event-driven-io/emmett** — Emmett - a Node.js library taking your event-driven applications back to the future!

- Repository: https://github.com/event-driven-io/emmett
- Website: https://event-driven-io.github.io/emmett/
- Stars: 552 · Forks: 54
- Language: TypeScript
- License: not declared
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/event-driven-io-emmett

## What the framework is trying to fix

Emmett is described as an opinionated yet flexible framework that implements Event Sourcing for Node.js applications, and the readme's own framing of the problem is the clearest statement of its scope.

The premise is that storage is cheap but information is priceless, and Event Sourcing keeps all the facts that happened in the system as events. That gives observability of the business process and enables event-driven capabilities such as building read models and easier integration between components.

Then comes the problem statement, and it is a list of five concrete difficulties rather than a general claim. There is an additional learning curve for new developers. There is the question of knowing how to structure the code. There is the work of implementing event storage. There is difficulty in setting up proper testing strategies. And there is the challenge of integrating with existing frameworks and infrastructure.

Emmett answers each of those five with a matching capability. Pragmatic abstractions reduce the boilerplate. Clear patterns cover common operations. Multiple testing approaches come with built-in utilities. Ready-to-use event store implementations are included. And there is simple integration with Express.js.

The design attitude is stated in the summary line: it focuses on composition rather than magic, providing lightweight abstractions and clear patterns. The features table repeats that as Lightweight Design, focused on composition over replacement, allowing integration with existing systems. That is the term to hold onto when judging the framework later, because it is the reason the abstractions look the way they do. Emmett is not trying to replace your HTTP framework or your database driver, it is trying to give you a coherent event model that sits inside what you already have.

The project is TypeScript, the topics list event-driven, event-sourcing, event-store, nodejs and typescript, and the documentation site is event-driven-io.github.io/emmett.

## The nine features, and what each one commits you to

The features table is short enough to read line by line, and each row implies a decision.

Event-centric modeling is the structured approach to modelling business processes through events. That is the framework's core assumption: your domain is a set of events and the commands that produce them.

Multiple event stores gives built-in support for PostgreSQL, EventStoreDB, MongoDB, SQLite and in-memory storage. Five backends behind one interface is the most substantial piece of the framework, and it is what makes the choice of infrastructure reversible. The in-memory store matters more than it looks: it is what lets a test run without a database.

Command handling patterns provide a standardized approach to command processing and event handling. This is where the opinionated part lives, and it is the piece you either accept or replace.

Building read models is covered by built-in projections that build read models from recorded events. Read models are usually where event sourcing projects grow complicated, because the projection has to handle events it has never seen and stay idempotent when replayed.

Type safety is first-class TypeScript support with structural typing. Structural typing is the right choice for a framework whose whole point is composition: a projection you write does not have to nominally extend anything to be used with the framework's machinery.

Express.js integration comes with conventional error handling. Being explicit about error handling matters here, since a command that fails to produce events has to fail in a way that maps onto an HTTP status.

Comprehensive testing support covers unit, integration and E2E testing with BDD-style syntax. The dedicated article on the author's blog about testing event sourcing in the Emmett edition suggests this is the part the author cares about most.

Docker testing integration adds support for Testcontainers to simplify database setup in tests, which is how the PostgreSQL, MongoDB and EventStoreDB adapters can be exercised in an integration test without a hand-rolled fixture.

## Testing, which the author treats as the main event

Two things in the readme point at testing being the centre of gravity rather than an afterthought.

The first is the feature row itself: tools for unit, integration and E2E testing with BDD-style syntax. Three levels of test are supported rather than one, which reflects a real difficulty with event-sourced systems. A command handler can be tested as a pure function over a list of events, a projection can be tested by feeding it a stream, and the whole store can be tested against a real database in a container.

The second is the list of blog articles linked from the readme. There is a post on testing event sourcing in the Emmett edition, a post on writing and testing event-driven projections with Emmett, Pongo and PostgreSQL, and a post on using event metadata in event-driven projections. Projections and their tests are the recurring theme, and that is the part of an event-sourced system that is genuinely harder than the write side.

The other linked articles cover the introduction to the framework itself, and event sourcing on PostgreSQL in Node.js, which the post says just became possible with Emmett. That is a useful hint about the intended positioning. Emmett is not trying to be the only event store; it is a framework with several store adapters, and the PostgreSQL one is the author's own contribution to making the mainstream choice work.

There is also a video tutorial for building a full application with the framework, and the samples directory in the repository holds a cloudflare sample and a webApi sample. The samples directory being a top-level entry rather than buried in the documentation suggests the maintainer expects people to read working code.

## Getting started from the samples rather than the docs

The readme points at a getting started page in the documentation, a Discord channel for questions, and a video tutorial for building a full application. For the code itself, the repository is the better starting point.

The samples/ directory at the repository root holds two sample applications, samples/cloudflare/ and samples/webApi/, and the webApi one is the natural first read for a Node team because it is the shape most people are building: an HTTP API over an event store. The cloudflare sample shows the framework deployed at the edge, which is also a reasonable place to see what the abstractions assume about the host environment.

There are setup scripts at the root, setup.sh and setup.ps1, which is a hint that local setup is scripted rather than documented step by step, and a .devcontainer/ directory for working inside a container. The .nvmrc file pins the Node version the project expects, which matters for a TypeScript project with a pre-1.0 API surface.

The repository also carries AGENTS.md, CLAUDE.md and ReferenceMaterials.md, and the .agents/, .claude/, .codex/ and .opencode/ directories, so the maintainer works with coding assistants and keeps the notes they use. Those files are worth a look before you write your own conventions, since they will tell you how the project expects to be extended.

## The licensing question, which is unusual and unresolved

There is a section of the readme titled Why there's no license, and it is the most consequential thing in the document for anyone planning to use Emmett in production.

The answer points at an open RFC pull request explaining the reasoning and the next steps, and then gives the summary: it will be, probably, AGPLv3 and or SSPL with an open and core model with paid tools around Emmett. The reasoning is stated in the first person. The author does not want to do a rug pull later, considers MIT too permissive, wants to build Emmett as a community project, and does not want the work to be unsustainable or for others to take advantage of it. The stated aim is a sustainable way to focus on delivering more value, and the author invites comments on the RFC and offers to clarify in the Discord.

So the library currently has no licence at all, and the repository listing shows no LICENSE file. The metadata records the licence as unknown.

That is a real constraint, and it cuts in a specific direction. Without a licence, the default position under copyright is that no permission is granted to copy, modify or distribute the code, so a company that depends on Emmett in a shipped product is in an awkward position until the licence lands. The author is explicit that this is deliberate and under discussion rather than an oversight.

The FAQ also asks whether it would be a competitor to other event stores, and the answer is that the intention is not to compete but to give more options to the community. Whether the open and core model ends up competitive with commercial stores is a separate question from the intent, and the roadmap items listed include building blocks for integration and running distributed processes, which is exactly the territory of commercial products.

The support section points at GitHub Sponsors, with bronze sponsor tiers, and says sponsoring is what makes the work sustainable.

## The roadmap, the FAQ, and the state of the release line

The FAQ asks what features the framework will have and answers we'll see, but for sure. The list that follows is a statement of intent rather than a plan with dates.

It includes an event store implementation using other storage engines such as DynamoDB and CosmosDB. Building blocks for integration and running distributed processes. A GraphQL API for event stores. Full stack development helpers with Next.js or HTMX. Built-in OpenTelemetry. Streaming data through an HTTP API, with integration scenarios enabled through it. Defining event transformations and projections with WebAssembly. And an open-ended etc.

The current release line is 0.42.x, with 0.42.4 published on 2026-08-12, 0.42.3 on 2026-05-22 and 0.42.2 also on 2026-05-22. The last push to the repository was on 2026-10-22, so work continues between releases.

The version numbering itself carries information. A library at 0.42 after a couple of years is pre-1.0 in SemVer terms, so the API is still allowed to break between minor versions, and the many patch releases suggest active iteration on a moving surface.

On production readiness, the author's answer is characteristically direct: what's there is safe to use, and more would be added to enhance the production experience, such as OpenTelemetry, but users are already using Emmett in their systems. That is a claim about the current state of the included features rather than a promise about the roadmap.

The reason for Node.js is given too: the author's preference for a minimalistic approach and flexibility, TypeScript's shapeshifter capabilities, and having been asked for such a store for Node.js. The name comes from Emmett Brown, and the repository also carries AGENTS.md and CLAUDE.md files along with.claude/,.codex/,.opencode/ and.agents/ directories, which tell you that the project is developed with coding assistants in the loop.

## Where Emmett is the wrong choice

The first limitation is the licence, and it comes before any technical consideration. A framework with no licence cannot legally be depended upon by a commercial product today, and the intended AGPLv3 or SSPL with paid core tooling model is a very different set of obligations from MIT. If your organisation's legal review is a gating step, Emmett is blocked until the RFC resolves, and it is not your call when that happens.

The second is that event sourcing is a commitment, not a library choice. Once your state lives in an event stream, every read path is either a projection you maintain or a replay, and every schema change to an event is a change to history that already happened. Emmett makes the mechanics easier, but it cannot make that decision cheap. A team whose real problem is a reporting query does not need an event store, and a team whose domain is genuinely append-only gets real value from it.

The third is the opinionated core. Command handling patterns are standardised, which is the point and also the constraint. If your existing codebase has its own command bus, its own validation and its own error conventions, adopting Emmett means reconciling them. The Express.js integration is built in, but built-in support for a new application is not the same as support for an existing one, and the readme does not document migration paths for either.

The fourth is the pre-1.0 surface. Version 0.42 means breaking changes are permitted in minor releases, and there is no long-term support story described. The four-times-a-year-to-monthly patch cadence suggests a single maintainer pushing hard, which is excellent for velocity and a risk for a product that has to keep up.

The fifth is the distance between the roadmap and what exists. Distributed processes, GraphQL, OpenTelemetry, streaming over HTTP, WebAssembly projections: these are the features that would let Emmett serve a production platform team, and none of them are in the released library. Adopting Emmett today means adopting the event store adapters, the command handling, the projections and the testing tools, and accepting that the operational features come later if they come at all.

## Conclusion

Emmett fits a Node.js team that wants events as the source of truth and does not want to design its own command handling, projection and testing story, since the framework ships the store adapters, the command and event handling patterns, the projection machinery and a testing approach with a BDD syntax on top. It is the wrong choice if you need a settled licence today, because the readme explains there is no licence yet and the plan is probably AGPLv3 or SSPL with an open and core model, and it is the wrong choice if you need features the roadmap only lists as intentions, such as distributed processes, OpenTelemetry or GraphQL. Before adopting it, read the open RFC on the licensing decision, and note that the last push was on 2026-10-22 with 0.42.4 published on 2026-08-12.

## FAQ

### What is Emmett?

Emmett is an opinionated yet flexible framework implementing Event Sourcing for Node.js applications. It focuses on composition rather than magic, with lightweight abstractions, standardised command and event handling, built-in projections and pluggable event store implementations.

### Which databases can Emmett use for event storage?

Built-in support for PostgreSQL, EventStoreDB, MongoDB, SQLite and in-memory storage. The in-memory store is what allows tests to run without a database, and Testcontainers integration is provided for testing the container-backed stores.

### Does Emmett have a licence?

Not yet. The readme has a section explaining there is no licence, points to an open RFC on the subject, and states the plan is probably AGPLv3 and or SSPL with an open and core model with paid tools around Emmett, on the grounds that MIT is too permissive and the work needs to be sustainable.

### How do I test an Emmett application?

The framework ships testing support for unit, integration and E2E testing with BDD-style syntax, and supports Testcontainers to simplify database setup. The author has also published separate articles on testing event sourcing in the Emmett edition and on writing and testing event-driven projections.

### Is Emmett production ready?

The author answers that what is there is safe to use and that users are already using Emmett in their systems, while noting that more would be added to enhance the production experience, such as OpenTelemetry. The current version is 0.42.4, published on 2026-08-12, with the last push to the repository on 2026-10-22.

## Sources

- [event-driven-io/emmett on GitHub](https://github.com/event-driven-io/emmett)
- [Issues](https://github.com/event-driven-io/emmett/issues)
- [Project website](https://event-driven-io.github.io/emmett/)
- [README](https://github.com/event-driven-io/emmett/blob/main/README.md)
- [Releases](https://github.com/event-driven-io/emmett/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/event-driven-io-emmett
