Skip to content

Domain

alchemy/Domain models your business in its own terms. Commands ask for changes, aggregates decide them, and events record what happened. Views, projections and policies then answer questions, feed your own stores, and apply the business’s rules about what to do next.

The same model runs in memory for tests and on Cloudflare Durable Objects in production, with one ordered partition per key.

Commandschange somethingAggregatesdecideEventsthe recordViewsanswer readsQueriesread the views
CommandAggregateEventViewQuery

A command declares what it asks for and every way it can end:

src/DepositMoney.command.ts
export class MoneyDeposited extends Domain.Event("MoneyDeposited", {
amount: Schema.Int,
balanceAfter: Schema.Int,
}) {}
export class DepositMoney extends Domain.Command("DepositMoney", {
target: AccountId,
input: { amount: Schema.Int },
events: [MoneyDeposited],
rejects: [NotOpen],
reply: { balance: Schema.Int },
}) {}

The account aggregate decides it against its current state:

src/Account.aggregate.ts
DepositMoney: (s, cmd) =>
s._tag !== "Open"
? new NotOpen()
: [new MoneyDeposited({ amount: cmd.amount, balanceAfter: s.balance + cmd.amount })],

And a story tests it in memory, in the business’s own words: given this history, when this command, then these events.

test/Account.test.ts
it.effect("deposits into an open account and replies with the balance", () =>
story(
Story.given(account, new AccountOpened({ owner: "sam" })),
Story.when(account, new DepositMoney({ amount: 100 })),
Story.then(account, new MoneyDeposited({ amount: 100, balanceAfter: 100 })),
Story.replied({ balance: 100 }),
),
);

The alchemy-domain skill teaches a coding agent how to turn requirements into a model, lay out the project, test it with stories, host it on Cloudflare and drive it from foldkit.

Ship it with your dependencies, so the skill always matches the alchemy version you have installed:

Terminal window
bun add -d skills-npm
bunx skills-npm setup

setup adds a prepare script. Every install then links the skills your packages ship into each coding agent’s skills folder.

Or install it from GitHub, for any agent:

Terminal window
npx skills add alchemy-run/alchemy --skill alchemy-domain

In Claude Code, it’s also a plugin:

/plugin install alchemy --marketplace alchemy-run/alchemy

A skill installed from GitHub follows the repository’s main branch, so update it when you upgrade alchemy.

New to domain-driven design? What is Domain-Driven Design? introduces the ideas one at a time, with the bank as the example.

Want to build one? The tutorial builds a bank step by step, from a single account on your machine to an Api deployed on Cloudflare with a browser app.

Know the ideas and want the API? Domain Model shows how a model runs, and each building block has its own page: Command, Event, Aggregate, View, Projection, Stream, Policy and Api.