One Year of EventSourcingDB, and the Language That Belongs Beside It¶
A year ago today, on the 5th of May, 2025, we shipped EventSourcingDB 1.0. We've spent the months since watching teams take it into production, hearing the stories of what they built on top of it, and learning more about the rough edges of event-driven work than we did in the decade before. Today, exactly twelve months later, we're not here to celebrate the past. We're here to take the next step.
Because somewhere along that year, a quiet thought turned into a loud one: a great place to store your events isn't enough. The events themselves carry meaning that lives outside the database, in the model you and your team carry around in your heads, on whiteboards, in slide decks. That model deserves a home of its own. Today, we're giving it one. Meet ESDM, the Event-Sourced Domain Modeling language.
A Year We Didn't See Coming¶
When we hit the publish button on EventSourcingDB 1.0 last year, we knew the database was good. We didn't know what would happen next. You happened next. Teams in finance, healthcare, logistics, and small product shops alike picked it up, wired it into their systems, and quietly started rebuilding the way they think about state. Every week brought a new conversation, a new question, a new model someone wanted us to look at.
We grew alongside that. Client SDKs landed for Elixir, .NET, and more. The MCP server opened the door to AI-assisted development on top of EventSourcingDB. Our friends at Digital Frontiers shipped OpenCQRS 1.0 for the JVM, and just yesterday our friends at Overlap shipped Nimbus for TypeScript. The ecosystem we hoped for started to take shape, and that, more than anything, is what made the gap impossible to ignore.
If we're honest, the year felt longer and shorter than twelve months at the same time. Longer, because every milestone surfaced ten more questions we wanted to answer. Shorter, because real adoption changes the velocity of everything around it. The community pulled us forward, and we noticed something the database alone could not solve.
The Quiet Problem We Couldn't Stop Seeing¶
The pattern showed up in almost every conversation. A team would describe their domain in beautiful, precise language on a call. Then they'd send us a PDF of a Miro board, a screenshot of a Confluence page, three half-aligned README.md files, and a Slack thread where the real model lived. The vocabulary was shared. The artifacts were not.
We've written before, in If You Apply DDD to DDD, You Won't Get DDD, that the patterns of Domain-Driven Design too often become a hiding place for the actual work, the conversations, the listening, the language. But we'd missed something else. Even when teams did the conversations, did the listening, and did arrive at a shared language, the language had nowhere to live. It evaporated the moment the meeting ended.
That's a loss the field has paid for over and over. It's the reason why models drift, why new joiners reverse-engineer the domain from code, why the answer to "is this an Aggregate or a Process Manager?" depends on which slide deck you find first. A model that doesn't live in version control isn't a model. It's a memory.
A Language for the Model¶
ESDM gives the model a first-class home. It is a YAML language plus a built-in toolchain. The schema defines what a model document may contain. The toolchain reads, validates, and renders those documents. Today the binary ships with a linter that catches structural and modeling errors, a view command that renders a hierarchical summary of a model, and helpers that materialize the schemas locally for editor support.
The vocabulary is exactly the one practitioners already use every day: Domains, Subdomains, Bounded Contexts, Aggregates, Commands, Events, Queries, Read Models, Process Managers, Dynamic Consistency Boundaries, Policies, Event Handlers, Domain Services, Value Objects, Actors, External Systems, and Context Mappings. Each of those is one kind of document. Each kind has a defined shape. Together they describe an event-sourced system in enough detail that a tool, yours, ours, or third-party, can do something useful with it.
A model in ESDM is a folder of .esdm.yaml files. You write them by hand, you write them with an LLM, you generate them from existing code, or you do all three. They sit next to your source, they show up in pull requests, they get reviewed like the rest of your codebase. The model is files. The files live next to the code. That single shift is what unlocks every other tool we want to build, and every tool anyone else might want to build, on top of it.
What ESDM Is Not¶
We want to be honest about the boundaries, because the wrong expectation will leave you disappointed. ESDM is not an event store. It is not a runtime. It is not a code generator. It is not a framework. It does not execute your domain. It does not know about your database, your message bus, or your deployment pipeline.
That separation is deliberate, and we hold it sacred. A modeling language that also tries to be a framework forces you into specific runtime choices. A runtime that tries to also be a modeling language buries the model under implementation detail. ESDM keeps the two apart so you can mix it with whatever you actually run in production, EventSourcingDB included, anything else included, both at once included.
ESDM is a static, descriptive layer that lives alongside your code and helps you keep the model honest. That's a smaller promise than a framework would make, and we think that's the point.
Two Worlds, One Story¶
So how do ESDM and EventSourcingDB fit together? Cleanly, and on purpose.
ESDM describes what your system is. The Aggregates, the Events, the Commands, the relationships, the invariants. EventSourcingDB stores what your system has done. The append-only log of facts, the dynamic consistency boundaries, the cryptographic signatures, the replay. The model is the map. The database is the territory.
The bridge between them is small but precise. An Event in an ESDM model can carry a CloudEvents type in its annotations, exactly the type EventSourcingDB will see in production. The model says which Event is expected. The database guarantees that every Event of that type is stored tamper-evident and replayable. You can read this connection in our Event Storming guide, our Modeling Events guide, and our Designing Aggregates guide, three places where ESDM is already woven into the recommended workflow. The two products were designed for each other, and they show it.
This is also why ESDM is its own product, not a feature of EventSourcingDB. Your model is bigger than your database. It includes systems we don't store, processes we don't run, services we don't host. ESDM should describe all of them, even when only part of the picture lives in EventSourcingDB. Standardization is the point. When the format is fixed, anyone, you, us, a third party, an LLM, can build against it.
Beyond the Core: Discovery and Behavior¶
The core vocabulary is what most teams need most days. But two activities surround the modeling work, and both deserved their own home. So ESDM ships with two extensions, each with its own schema, each validated by the same toolchain.
Domain Storytelling, in the format defined by Stefan Hofer and Henning Schwentner, captures discovery stories. A story is a sequence of sentences, each a numbered set of arrows between Actors and Work Objects, with the arrows labeled by activities. Read in order, the sentences tell what actually happens in the domain, in the language the domain experts already use. Capturing those stories as ESDM documents means they survive the workshop. Names stay consistent across sessions. The file lives in version control next to the rest of the code. The story that informed the design stays reachable, and you can come back to it when the design needs to change.
Given-When-Then, in the canonical pattern Greg Young popularized for aggregate tests, captures behavioral specifications. Given some past Events, when a Command, Event, timer, or Query happens, then a particular outcome is expected. ESDM extends that to all four kinds of consistency unit: Aggregate, Dynamic Consistency Boundary, Process Manager, and Read Model. The Scenarios live alongside the model, double as living documentation, and serve as input for tests. An implementation can run them as fixtures and verify that the system actually produces what the spec calls for.
Neither extension injects kinds into the core, and a core document never validates against an extension. The core stays lean. The surface grows. That asymmetry is what lets us add new extensions over time without ever destabilizing what's already there.
Built for Humans, and for AI Modelers Too¶
There's another reason a precise, schema-defined modeling language matters now, more than it might have five years ago. LLMs read YAML well. They read schemas even better. They read English prose explanations of vocabulary best of all. ESDM is all three at once, on purpose.
If you ask a modern LLM to extract a model from an existing codebase, the question becomes: into what? Into a free-text answer that's gone the moment you close the chat, or into a set of files that match a defined schema, that lint cleanly, and that can be checked back into your repository? The latter is what ESDM enables. The same Concepts pages that teach the vocabulary to a human teach it to a model. The same linter that catches a junior's mistake catches an LLM's. The same view command that gives you a hierarchical overview gives an AI agent a structure to reason about.
We think that's how AI-assisted modeling becomes useful instead of impressive. Not by generating prose, but by generating artifacts that a tool can verify and a team can review.
Free, in the Way That Matters¶
ESDM is free of charge, including for commercial use. There is no per-instance license, no event-count threshold, no commercial tier waiting to gate the features that matter. You can install it, run it, embed it in your CI pipelines, and ship its findings into your code review process at no cost.
Every release publishes pre-built binaries for macOS, Linux, and Windows, on both arm64 and amd64. The binaries are self-contained, with the schemas embedded, so a single download is enough to lint a project. The friction of starting is intentionally close to zero. We want the language to be picked up, used, and shaped by the people who actually model event-sourced systems.
One Year On, and Just Getting Started¶
A year ago today, we gave Events a home. Today, we're giving the model that gives those Events meaning a home of its own. Both are free, both are built to work together, and both are built to outlive any one project, including ours. That's what a foundation is supposed to be.
We're not done. This is the beginning of ESDM, not the final word. The core language is stable and useful today, and we'll keep growing the toolchain around it: more extensions, more integrations, more ways to bridge from a model to running code. But the most important part is already in place, and it has been all along: the model belongs in version control, beside the code, in a language that everyone, you, your team, your tools, your AI assistants, can speak together.
Twelve months in, we want to thank everyone who took a chance on EventSourcingDB when it was new, who sent us models, who told us where the rough edges were, and who kept asking the question that eventually became ESDM: where does the model itself live? You shaped both products, even when you didn't know you were doing it. Today, on this small anniversary, that gratitude is the loudest thing we feel.
If you'd like to see ESDM in action, head over to esdm.io and follow the Your First Model guide there. You'll have a complete, lint-clean model on disk in about fifteen minutes, and you'll already see how naturally it sits next to whatever EventSourcingDB project you're running. And if you'd like to talk to us about how ESDM fits into your team's modeling work, or about anything else in the world of Event Sourcing, CQRS, and Domain-Driven Design, write to us at hello@thenativeweb.io. Happy birthday, EventSourcingDB. And welcome to the world, ESDM.