Quick start
Install the CLI, bootstrap with dma init, run dma check, and wire CI.
Minimal path from an empty or existing project to working DMA enforcement. We assume a TypeScript app with src/ (or you create it via init).
Using an AI agent? Copy the prompt — it suggests skill install, dma init, and verification steps for your repo.
1. Install the CLI
npm install -D @derived-modular/cli2. Bootstrap the layout
From the app package directory (in a monorepo: apps/web, not the workspace root):
npx @derived-modular/cli init .init is safe on existing projects — strict skip, never overwrites:
| Creates (if missing) | Skips |
|---|---|
src/, features/, shared/ | Existing files and folders |
app/ — unless pages/ or routes/ already exists | dma.config.*, scripts.dma, AGENTS.md markers |
dma.config.ts, scripts.dma in package.json | Lint configs |
DMA block in AGENTS.md (append-only) | services/ |
Resulting tree (minimal):
src/
├── app/ # or pages/, routes/ — composition root for your framework
├── features/
└── shared/Do not create services/ upfront — it appears on the first promotion when another module imports the code.
More: dma init · Project layout.
Prefer manual layout? Create the same folders yourself. Optional dma.config.* — dma.config.
3. Mount a feature from the composition root
The composition root imports modules only through public/:
// src/app/page.tsx
import { CatalogPage } from "@/features/catalog/public/catalog-page";
import { CheckoutPage } from "@/features/checkout/public/checkout-page";
export default function Page() {
return (
<div>
<CatalogPage />
<CheckoutPage />
</div>
);
}A feature may pull services/*/public/* and shared/, but not other features. Live example — examples/next-app.
4. Run the check
npx @derived-modular/cli check .Single app with src/ — one graph. Monorepo root without src/ — the CLI discovers apps (or use --roots). Each root is a separate graph.
Typical first errors:
| Rule | What happened | What to do |
|---|---|---|
public-api | Import into features/foo/model, not public/ | Export the symbol in public/ or import from there |
feature-to-feature | Feature A imports feature B | Promote to services/ or extract to shared/ (second use) |
layer-direction | Import “upward”, e.g. from shared into features | Reverse the dependency |
All rules — dma check. Monorepo — Monorepo guide.
5. Add to CI
npx @derived-modular/cli check . --format jsonMore — CI.
6. (Optional) Linter in the editor
Fast feedback on save — not a substitute for dma check:
npm install -D @derived-modular/eslint-plugin eslint// eslint.config.js
import dma from "@derived-modular/eslint-plugin";
export default [
...dma.configs.recommended,
{
settings: {
dma: {
srcRoot: "src",
compositionRoots: ["app", "pages", "routes"],
},
},
},
];ESLint can soft-load srcRoot / compositionRoots from dma.config.* when settings.dma is unset. Setup — ESLint.
7. Local growth signals
npx @derived-modular/cli doctor .doctor does not fail CI (exit 0) but hints when to extract to shared, split segments, or promote a feature to a service. More — dma doctor.