Derived Modular Arch
Guides

Migrating to DMA

How to adopt DMA in an existing project without a big-bang rewrite.

Migrating to DMA is not "rewrite everything in one sprint." It is incremental tightening: first boundaries and checks, then promotion and shared — driven by graph signals.

Phase 0: Define the goal

You want to:

  • stop arguing about imports in code review;
  • catch cycles and feature-to-feature edges in CI;
  • grow through colocation, not premature shared/.

If a style guide on Confluence is enough — DMA may be overkill.

Phase 1: Tree and tooling (day 1)

  1. Shape src/ into the baseline layout:
src/
├── app/          # or pages/, routes/
├── features/
└── shared/       # can be nearly empty
  1. Install the CLI:
npm install -D @derived-modular/cli
  1. Add to CI:
npx @derived-modular/cli check . --format json
  1. Wire up a linter (ESLint or Biome).

The first dma check run shows the real picture — don't be scared by a long list.

Phase 2: Composition root (week 1)

Goal: routes and layout import only */public/*.

BeforeAfter
import { X } from '@/features/foo/internal'import { X } from '@/features/foo/public/foo-page'
Logic in page.tsxThin shell + mount from feature

Don't touch module internals until entry points are fixed.

Phase 3: Remove feature → feature (weeks 2–3)

Typical pre-DMA pattern:

features/catalog → features/checkout/internal

Fix options:

  1. Promotion — shared product code in services/
  2. Lift to shared — portable helper without product logic
  3. Wiring in app — props, events, providers (cross-module wiring)

After each refactor — npx @derived-modular/cli check ..

Phase 4: Public API and barrels (week 3–4)

  • Remove barrel index.ts re-exports inside modules
  • Move public symbols to public/ with direct paths
  • Keep stage-0 files (features/profile.tsx) if the module is a single file

Phase 5: Promotion and shared (on signals)

Don't create services/ upfront. Wait for:

  • feature-has-inbound in check — time to promote
  • shared-candidate in doctor — time to consider a lift

Run npx @derived-modular/cli doctor . once per sprint during planning.

Strategies for large codebases

Strangler by feature

Pick one vertical (e.g. checkout), lay it out with DMA, and temporarily exclude the rest from dma check via a separate package/folder — not by disabling rules globally.

Monorepo

dma check — один граф на корень; с корня монорепо доступен multi-root discover:

npx @derived-modular/cli check .
npx @derived-modular/cli check apps/web
npx @derived-modular/cli check --roots apps/web,apps/admin

See Monorepo for details.

Legacy utils/ and components/

Don't rename everything at once. New code follows DMA. Touch old code on second use or when you edit the file.

Readiness checklist

  • dma check in CI on every PR
  • Composition root imports only public/
  • No feature → feature
  • No barrels inside modules
  • Linter in the editor for fast feedback
  • Team knows Code evolution and Where to put a file

What's next

On this page