Domain modeling
The @beignet/core/domain subpath provides small helpers for domain-driven design: entities and value objects.
These helpers are optional. Plain TypeScript objects and functions are fine domain code; reach for the helpers when validation or immutable-update patterns start repeating across a feature.
bun add @beignet/corePlacement
Put domain code with the feature that owns the business concept:
features/posts/domain/post.ts
features/posts/domain/events/published.ts
features/comments/domain/events/comment-added.tsUse features/shared/domain/ only for true shared-kernel concepts that are
genuinely used by multiple features, such as EmailAddress, Money, or
TenantId. Do not put feature-specific domain code there.
Value objects
Immutable, validated types that represent a concept with no identity (e.g. an email address, a currency amount):
import { defineValueObject } from "@beignet/core/domain";
import { z } from "zod";
const Email = defineValueObject("Email")
.schema(z.string().email())
.build();
const email = await Email.create("user@example.com"); // validated string
await Email.isValid("not-an-email"); // falseEntities
Domain objects with identity and behavior. Entities are immutable — methods return new instances:
import { defineEntity } from "@beignet/core/domain";
import { z } from "zod";
const Todo = defineEntity("Todo")
.props(z.object({
id: z.string(),
title: z.string(),
completed: z.boolean(),
}))
.methods((self) => ({
complete: () => self.with({ completed: true }),
rename: (title: string) => self.with({ title }),
}))
.build();
const todo = await Todo.create({ id: "1", title: "Buy milk", completed: false });
const done = await todo.complete(); // new instance with completed: trueEvery entity gets a .with() method for partial updates, returning a new instance.
Domain events
Feature event declarations live in features/<feature>/domain/events/, but
the event APIs are owned elsewhere: declare events with defineEvent(...)
from Events, and emit them from use cases with .emits(...) as
shown in Use cases.
Schema libraries
Both helpers work with any Standard Schema library — Zod, Valibot, ArkType, etc.