# Frontend architecture rules for enterprise apps

Source: https://tt-tech.io/blog/frontend-architecture-enterprise-boundaries
For Angular and React frontends. Add to AGENTS.md or save as a skill. Your project's own rules win where they differ.

## Rules

1. Split code by type, not only by feature: `domain` (pure models and rules), `data-access` (the only code that talks to the backend), `ui` (inputs and outputs only), `feature` (wires the three) and `app` (shell and routes). Put new code in the layer it belongs to.
2. Keep the "may import" contract: `ui` never imports `data-access`, `domain` imports nothing, and nothing modern imports the legacy code.
3. Enforce boundaries in lint, not in a wiki. On Nx, tag every project and set which tags may depend on which (`onlyDependOnLibsWithTags`). Without Nx, use Sheriff.
4. When the boundary lint fails, let it fail: fix the import, or record the crossing. Never switch the rule off to make the change pass.
5. When a boundary must move, write it down in an Architectural Decision Record (ADR) with the rationale, and reference it in the pull request.
6. Treat the design system as a library under the same rules. Components read colour from tokens by role, never from a raw hex value.
7. Keep the legacy corner frozen and wrapped. No new code imports it. Dependencies point one way, from old to new, so the old code stays deletable.
8. Treat monorepo or polyrepo as an organisational choice. One repository with boundaries inside fits teams that share a design system, a domain model and one release train. Separate repositories fit products that ship on their own schedules and share almost nothing, or when strict repository-level access control is a hard requirement.
9. Do not introduce micro-frontends to fix a messy codebase. They fit when separate organisations must deploy independently into one shell. Fix the missing boundary first.

## Before you say done

- Run the project's boundary lint (Nx module boundaries or Sheriff) and fix every new error.
- Search the diff for imports from `ui` into `data-access`, from modern code into legacy code, and for raw colour values in stylesheets.
- List every boundary crossing in the pull request with its ADR.
