One model, whole contract
Types, validation, queries, permissions and errors are compiled from the same IR into every layer — backend, web client, admin. They cannot drift apart.
DomainCraft compiles a single domain.yaml into a production API, a typed web client and an admin panel. Types, validation, queries and permissions stay consistent across every layer — by construction.
project:
name: MyShop
database: postgresql
auth:
type: jwt
entity: User
roles: [Admin, User]
entities:
User:
fields:
id: uuid [primary]
email: string [email, unique]
password: string [hidden]
Product:
features: [audit, soft_delete]
fields:
id: uuid [primary]
title: string [required, min:3]
price: decimal [required, gte:0]
permissions:
read: ["*"]
create: [Admin]The stack it ships with
The problem
CRUD endpoints, repositories, DTOs, migrations, auth wiring, validation, permissions — days of repetitive work that is error-prone and tedious.
Write 50+ files per entity by hand
Define 1 entity in ~10 lines of YAML
Repeat CRUD logic on every project
Generate it consistently every time
Fix the same boilerplate bugs everywhere
Fix bugs in templates, fixed everywhere
Switch language? Rewrite everything
Switch bridges, keep the same domain
API changed — the frontend silently broke
Regenerate: every layer updates from one model
Permissions scattered across the codebase
Declared beside entities, wired end-to-end
How it works
Your domain.yaml flows through a deterministic compiler — not a black box.
Entities, fields, relations, permissions, features and seed data live in one readable, diffable domain.yaml.
A strict parser, lexer and validator catch logic errors before anything is generated; an intermediate representation links every relation.
Pluggable bridge templates translate the IR into idiomatic code for your target stack — with a file manifest and migration snapshot.
Features
Each feature is a few declarative words in domain.yaml. The template does the rest — consistently, every single time.
Types, validation, queries, permissions and errors are compiled from the same IR into every layer — backend, web client, admin. They cannot drift apart.
Custom code survives regeneration. Generated partials stay refreshed, your hooks stay yours — no wipe on regen.
read: ["*"], update: ["@Owner", Admin] — public, role and ownership rules compiled to auth policies.
Snapshots, old_name renames, orphan cleanup and --prune — domain refactors land safely.
Bridges are plain templates and a manifest — no Go code required. Add a language in an afternoon.
domaincraft generate --admin ships a CRUD admin panel for your API with zero extra config.
Declare queue, cache, secrets and storage — wire Dapr, event_sourced and enterprise plumbing declaratively.
Who it is for
DomainCraft serves everyone who touches the product — the API, the web client and the screens in between.
A production ASP.NET Core + PostgreSQL API out of the box — JWT auth, migrations, permission checks. Business logic goes into Generation Gap hooks, never into generated files.
A typed client compiled from the same model — types, queries and permissions that cannot drift from the API, because they are compiled from the same IR.
Screens are built against a certified client — permissions and query schema are already part of the types, so the agent writes UI instead of guessing about the API.
The agent describes the domain, DomainCraft compiles the API and its typed TypeScript client from one model, the agent drops business logic into hooks — then docker compose up runs it. Zero forgotten wiring, nothing hand-built.
One file is the whole spec — entities, relations, permissions, features. Everything else the compiler derives from it.
domaincraft generate emits a production ASP.NET Core API plus its typed TypeScript client and an admin panel — deterministic on every run.
The agent implements hooks in Services/<Entity>Service.cs (overwrite: false) — the exact files the generator never touches.
docker compose up boots API + Postgres. Change the model and regenerate — tables are renamed for you, your data survives.
You → agent
You are building an online store with DomainCraft.
1. Draft the domain: Product + Category entities with
relations, audit + soft_delete features and permissions
(public read, Admin create/delete, @Owner update).
2. I'll run: domaincraft generate
3. Then I'll write the custom business logic in the hooks.
4. And deploy it: docker compose up
Output only a valid domain.yaml.Agent → domain.yaml
entities:
Product:
features: [audit, soft_delete]
fields:
id: uuid [primary]
title: string [required, min:3]
price: decimal [required, gte:0]
categoryId: relation(Category) [optional]
permissions:
read: ["*"]
create: [Admin]
update: ["@Owner"]
Category:
fields:
id: uuid [primary]
name: string [required, unique]$ domaincraft generate
✓ Schema valid (2 entities)
✓ 42 files generated · compiles clean
src/WebApi/Controllers/ProductsController.g.cs
src/Application/Generated/ProductService.g.cs
tests/ApiTests.g.csAgent → business hooks
// ProductService.cs — your file, overwrite: false
protected override async Task<HookResult> OnBeforeCreateAsync(
Product entity, CancellationToken ct)
{
if (entity.Price <= 0)
return HookResult.Fail("Price must be positive");
return HookResult.Success();
}$ docker compose up
[+] Running 2/2
✔ Container postgres Started
✔ Container api Started
✓ API :8080 · Postgres · health readyDomainCraft Studio
Drag-and-drop entity diagrams, a permission matrix and a real-time YAML editor with WASM validation — everything you draw is a valid domain.yaml.

Bridges
Each bridge is a pluggable template pack. The core never knows a language — it ships the IR and constrains nothing. Composition gives you 1 core + N thin adapters, not N×M bridges. Screens are built by AI agents against the typed client.
ASP.NET Core + EF Core + PostgreSQL + JWT (core → domain → efcore → rest).
Thin TypeScript core — typed query DSL, wire-value enums, permission matrix.
Zod, JWT client, CRUD, TanStack Query hooks (extends ts-core).
Admin panel for any REST backend — one --admin flag.