Skip to content

Domain

@alchemy.run/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
decide: {
DepositMoney: (account, cmd) =>
account._tag !== "Open"
? new NotOpen()
: [new MoneyDeposited({ amount: cmd.amount, balanceAfter: account.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
pnpm add -D skills-npm
pnpm 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
pnpx 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.

Want the whole picture? The concepts read as a manual, one building block per chapter, starting with Domain Model and ending with Story. Each chapter explains the idea, how to find it in your business, and how to write it: Command, Event, Aggregate, View, Projection, Stream, Policy, Saga, External System and Api.