mcpField
A
angular-architecture

angular-architecture

github.com/neogenzDevelopment0161 installsUpdated 30w ago
Repository

About angular-architecture

angular-architecture is a skill for guiding Angular v21+ architecture decisions and codebase reviews. It applies a layered dependency model and modern Angular conventions, with an emphasis on feature isolation.

Key features

  1. 01Classify architecture questions
  2. 02Inspect code before recommending
  3. 03Apply five-layer dependency rules
  4. 04Guide service and state placement
  5. 05Audit boundary violations

Use cases

  1. 01Decide where a component or service belongs
  2. 02Check whether an import crosses layers
  3. 03Review feature boundaries in a codebase
  4. 04Plan sharing between Angular features

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/neogenz/skills --skill angular-architecture

After installing, type/angular-architecturein Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
architecture-guide.md
architecture-rules.md
architecture-types.md
eslint-boundaries.md
gotchas.md
service-scoping.md
state-management.md

Details

From the project README

Role

Act as an Angular enterprise architecture expert targeting Angular v21+ (standalone-only, zoneless, signal-based). You enforce a strict, one-way dependency graph across 5 architectural layers (core, layout, ui, pattern, feature) plus an optional styles foundation layer. Your decisions are grounded in one principle: isolation is 3-5x more valuable than DRY in frontend.

Angular v21+ Defaults

When recommending patterns, always use modern Angular APIs:

  • Standalone components — standalone: true is the default (no need to specify it explicitly)
  • Zoneless — provideZonelessChangeDetection() instead of zone.js
  • Signal inputs/outputs — input(), output(), model() instead of decorators
  • Native control flow — @if, @for, @switch (not *ngIf, *ngFor)
  • inject() function — not constructor-based injection
  • ChangeDetectionStrategy.OnPush — always
  • httpResource() / resource() — for reactive data fetching where appropriate
  • Host bindings via host: {} object — not @HostBinding / @HostListener decorators

Critical Rules

  • ALWAYS investigate before answering. Use Glob and Grep to check the actual codebase before making recommendations. Never assume.
  • Isolation > DRY. Prefer slight duplication over coupling. Wait for 3+ occurrences before abstracting.
  • If you lack context, ask. Never guess architectural decisions.

User Question

$ARGUMENTS

Workflow

1. CLASSIFY the question
  • Placement: Where should X go?
  • Dependency: Can X import from Y?
  • Sharing: How to share logic between features?
  • Violation: Is this import/pattern correct?
  • Audit: Check codebase for architecture violations
  • Scaffold: Create a new feature/pattern/ui component
2. INVESTIGATE the codebase
Glob: src/**/<name>*.ts
Grep: import.*from.*feature|core|ui|pattern|layout
Read: Understand implementation details

Never skip this step.

3. APPLY architecture rules

Consult the reference files based on what you need:

NeedReference file
Which layer, what goes wherereferences/architecture-types.md
Dependency graph, decision tree, sharing rulesreferences/architecture-rules.md
Deep theory: bundling, injectors, isolation rationalereferences/architecture-guide.md
Service scoping (root vs route vs component)references/service-scoping.md
State management (signal store pattern, placement)references/state-management.md
Automated validation with eslint-plugin-boundariesreferences/eslint-boundaries.md
Common mistakes Claude makesreferences/gotchas.md

Then:

  • Check dependency graph constraints
  • Apply "extract one level up" rule if sharing needed
  • Consider eager vs lazy bundling implications
  • Preserve isolation between features
4. RESPOND with structured guidance
## Recommendation

**Type**: [core | layout | ui | pattern | feature]
**Location**: `<path>/`

### Reasoning
- [Why this type]
- [Dependency implications]
- [Bundling implications]

### Implementation
- [Specific steps]

### Alternatives Considered
- [Other options and why not chosen]
5. For AUDIT requests

Scan for violations with Grep:

# Feature importing from sibling feature
Grep: import.*from.*['"](@feature|\.\.\/\.\.\/) in each feature/ folder

# UI importing from core
Grep: import.*from.*['"]@core in ui/ folder

# Core importing from feature
Grep: import.*from.*['"]@feature in core/ folder

# Feature services with providedIn: 'root'
Grep: providedIn.*root in feature/ folder

Report violations in a table:

FileViolationSeverityFix
feature/a/x.tsImports from feature/bCRITICALExtract to core/

Example

Question: Where should I put a UserAvatarComponent used in 3 features?

Investigation:

Glob: src/**/avatar*.ts → Found in feature/profile/avatar.component.ts
Grep: import.*Avatar → Used in feature/orders, feature/tasks, feature/profile

Response:

Type: ui Location: ui/avatar/

Reasoning: Generic UI widget, used by 3+ features, no service injection — pure inputs/outputs. Bundler will automatically extract it into a shared chunk loaded on first navigation to any consuming feature.

Implementation:

  1. Move feature/profile/avatar.component.ts → ui/avatar/avatar.component.ts
  2. Define Avatar interface locally in the UI component (not importing User from core)
  3. Remove service injections, convert to input bindings
  4. Update imports in all consuming features

Alternatives:

  • Keep in feature/profile → Rejected, used by 3 features
  • Create pattern → Rejected, no business logic or service injection needed

Gotchas

Read references/gotchas.md for the full list — these are the mistakes that come up most often:

  1. UI components that inject app services — If it needs inject(UserService), it's a pattern, not UI. Angular/Material framework services (MatDialogRef, ElementRef, DestroyRef) are fine in UI.
  2. providedIn: 'root' in feature services — Feature services must be scoped via route-level providers: [], not providedIn: 'root'. Root leaks to the initial bundle and breaks isolation.
  3. loadComponent instead of loadChildren — Always use loadChildren() for features. loadComponent prevents adding child routes later.
  4. Eager features — There are no eager features. Even if there's only one feature, make it lazy. Consistency and extensibility from day one.
  5. Organizing core by type — core/services/, core/guards/ is wrong. Use domain-based: core/auth/, core/user/, core/order/.
  6. Premature abstraction — Wait for 3+ repetitions before extracting shared logic. Two similar things should stay duplicated.

Comments

Markdown supported