Software architecture skill: 10 reviews Claude can run
Ten architecture reviews you can run today with the software architecture skill — the utils-folder audit, a bounded-context carve-up, monolith vs. microservices for your constraints, an ADR from a design chat, and a pre-merge gate — each as one Claude prompt with the exact artifact it returns.
This is a guidance skill, not a generator. It is grounded in Clean Architecture and Domain-Driven Design, so it reviews and refactors your real files against named rules — layering, separation of concerns, library-first, domain naming — rather than producing a diagram. If you came for diagrams, the companion piece is 10 diagrams from one prompt with the Claude mermaid skill. Pick the architecture skill to decide the structure; pick mermaid to draw it.
Already know what skills are? Skip to the cookbook. First time? Read the explainer then come back. Need the install? It’s on the /skills/software-architecture page.

On this page · 21 sections▾
- What this skill does
- The cookbook
- Install + README
- Watch the foundation
- 01 · The utils/ folder audit
- 02 · Bounded-context map for a service
- 03 · Monolith vs. microservices, for your constraints
- 04 · Separation-of-concerns audit on a controller
- 05 · Library-first check before you write the util
- 06 · Untangle the deep-nesting and long-function smells
- 07 · ADR drafted from a design discussion
- 08 · Catch the NIH and anti-pattern smells in review
- 09 · Error-handling and typed-catch pass
- 10 · Pre-merge architecture gate in CLAUDE.md
- Community signal
- The contrarian take
- Real projects
- Gotchas
- Pairs well with
- FAQ
- Sources
What this skill actually does
Sixty seconds of context before the cookbook — what the software architecture skill reviews against, what Claude hands back when you invoke it, and the one job it deliberately leaves to another tool.
What this skill actually does
“Guide for quality focused software architecture. This skill should be used when users want to write code, design architecture, analyze code.”
— davila7, the skill author · /skills/software-architecture
What Claude returns
When triggered, Claude reviews or designs against Clean Architecture and Domain-Driven Design rules rather than writing freehand. It separates domain entities from infrastructure, keeps business logic out of frameworks and UI, names modules for the domain (no utils/helpers/common/shared), checks npm for an existing library before approving custom code, and holds functions under ~50 lines, files under ~200, nesting under three levels. The output is a review or a refactor plan — findings, move lists, decision notes — keyed to your files.
What it does NOT do
It does not generate C4 or UML diagrams itself — pair it with a diagram skill for that. And it advises on your architecture; it does not silently rewrite your repo without showing the plan first.
How you trigger it
Review this controller for separation-of-concerns violations.Carve this service into bounded contexts using DDD.Should this be a monolith or microservices for our constraints?Cost when idle
~100 tokens at idle (the skill name + description in the system prompt). The full ruleset loads only when you trigger an architecture review.
The cookbook
Each entry is a review or design pass you could run this week. They climb in scope — the early ones clean one file (the utils audit, a fat controller), the middle ones make structural calls (bounded contexts, monolith vs. microservices, an ADR), and the last one wires the rules into a pre-merge gate. Every entry pairs with a skill or MCP server you already have on mcp.directory.
Install + README
If the skill isn’t on your machine yet, here’s the one-liner. The full install panel (Codex, Copilot, Antigravity variants) is on the skill page — the same UI is embedded below.
One-line install · by davila7
Open skill pageInstall
mkdir -p .claude/skills/software-architecture && curl -L -o skill.zip "https://mcp.directory/api/skills/download/658" && unzip -o skill.zip -d .claude/skills/software-architecture && rm skill.zipInstalls to .claude/skills/software-architecture
Watch the foundation
The skill says it is based on Clean Architecture. This is the talk where Robert C. Martin lays out the dependency rule and the concentric layers the skill enforces — worth eighty minutes before the cookbook, because every prompt below is that rule applied to real files.
The utils/ folder audit
Point the skill at a junk-drawer module and get back a rename plan. Every function in `utils.js` is reassigned to a domain-named home — `OrderCalculator`, `InvoiceFormatter` — with the move list and the new file each belongs in.
ForAnyone who inherited a 50-function utils.js and is afraid to touch it.
The prompt
Read `src/lib/utils.ts` and `src/lib/helpers.ts`. For each exported function, decide which bounded context it really belongs to and propose a domain-specific home — never a generic `utils`/`helpers`/`common` name. Return a table: current function → proposed module (e.g. `pricing/OrderCalculator.ts`) → one-line reason. Flag any function that does two unrelated things and should be split. Do not rename anything yet; give me the move plan first.What slides.md looks like
# Move plan — src/lib/utils.ts (14 functions)
calcTax, applyDiscount, roundCurrency
→ pricing/OrderCalculator.ts (all touch order totals)
formatInvoiceNo, invoiceDueDate
→ billing/InvoiceFormatter.ts (invoice-shaped, not generic)
slugify
→ keep in text/Slug.ts (cross-cutting, genuinely shared)
parseAndEmail ⚠ SPLIT
→ parsing/CsvRowParser.ts + notifications/Mailer.ts
(one function doing two jobs — parse, then send)One-line tweak
Swap the table for a `git mv` script plus the import-rewrite edits, and the audit becomes an executable refactor instead of a plan.
Bounded-context map for a service
Hand the skill a feature spec and get a Domain-Driven Design carve-up: which entities live in which context, where the seams are, and the ubiquitous-language term for each. The output is a folder layout you can scaffold from.
ForEngineers starting a new service who want the boundaries right on day one.
The prompt
Here is the spec for a checkout service (`docs/checkout-spec.md`). Apply DDD: identify the bounded contexts, assign each domain entity to one context, and name the contexts with the team's ubiquitous language — not technical layers. For each context list its core entities and the one public operation other contexts call. Return it as a directory tree under `src/` with one folder per context. Keep domain logic out of any infrastructure folder.What slides.md looks like
src/
ordering/ # context: "placing an order"
Order.ts Cart.ts PlaceOrder.ts ← use case
ports/ PaymentGateway.ts (interface)
pricing/ # context: "what it costs"
PriceList.ts OrderCalculator.ts
fulfilment/ # context: "getting it shipped"
Shipment.ts DispatchOrder.ts
shared-kernel/
Money.ts CustomerId.ts ← value objects only
# infra adapters live in src/infrastructure/, never inside a contextOne-line tweak
Ask for a one-line context-relationship list (upstream/downstream) and you get the start of a context map without leaving the prompt.
Monolith vs. microservices, for your constraints
Give the skill the team size, deploy cadence, and traffic shape; get a reasoned recommendation instead of a Medium-article default. It argues from your numbers and names the modular-monolith middle path when it fits.
ForTech leads being pushed toward microservices by hype rather than need.
The prompt
We are 4 engineers, deploying twice a week, ~200 req/s peak, one Postgres, no platform team. A stakeholder wants microservices. Argue the trade-off against THESE constraints: operational overhead, transaction boundaries, team cognitive load, and time-to-first-revenue. Recommend one of: monolith, modular monolith, or microservices — and say what would have to change for the answer to flip. Be specific; do not give a both-sides non-answer.What slides.md looks like
Recommendation: modular monolith.
Why, against your constraints
• 4 engineers, no platform team → microservices' ops tax (CI per
service, distributed tracing, network failure modes) buys you
nothing yet. It's a part-time SRE you don't have.
• One Postgres + real money → keep transactions in-process; a
saga across services to avoid a single COMMIT is pure downside.
• Module boundaries (per ctx, use case 2) give you 80% of the
decoupling with 0% of the network.
Flip the call when: a context needs independent scaling (e.g.
search at 10x the rest), OR headcount passes ~15 with >3 teams.One-line tweak
Drop in real latency SLOs and the skill weighs network hops explicitly, sharpening the same recommendation for a performance-bound system.
Separation-of-concerns audit on a controller
Feed the skill a fat controller and get the layering violations called out by name — SQL in the handler, business rules in the route, a domain rule leaking into the view. Each finding ships with the move that fixes it.
ForTeams whose controllers quietly grew database queries and pricing logic.
The prompt
Review `src/routes/orders.ts`. Apply the separation-of-concerns rules: no database queries in controllers, no business logic mixed into the HTTP layer, framework code out of the domain. List each violation with file:line, classify it (persistence / business-rule / framework-leak), and give the one-line fix — which layer the code should move to. Order findings worst-first. Keep the controller as a thin orchestrator.What slides.md looks like
orders.ts — 3 violations
✗ business-rule L41 discount math inlined in the POST handler
→ move to pricing/OrderCalculator.applyDiscount()
✗ persistence L58 raw `db.query('SELECT … orders')` in route
→ move behind orders/ports/OrderRepository (interface)
✗ framework-leak L72 domain Order imports `express` Request type
→ pass a plain DTO into the use case; keep express at the edge
After: the handler is 9 lines — parse, call PlaceOrder, map result.One-line tweak
Ask it to also emit the extracted `OrderRepository` interface and you get the seam stubbed out, ready to wire an adapter behind.
Library-first check before you write the util
Before greenlighting custom retry/validation/state code, ask the skill to find the established library that already does it. It returns the named package and the carve-out where rolling your own is actually justified.
ForReviewers who keep approving home-grown code that npm already solved.
The prompt
We are about to write a custom retry wrapper, a custom form validator, and our own auth session store. For each, apply the library-first rule: name the established library that solves it (the skill cites `cockatiel` for retries as the canonical example), and state the one condition under which writing it ourselves is justified. If custom is the right call, say why in one line — security control, unique business logic, or dependency overkill.What slides.md looks like
Library-first verdicts
retry wrapper → use cockatiel (policies: retry, circuit-breaker,
timeout). Custom only if you need a backoff curve
the lib can't express — you don't.
form validation → use zod / valibot. Schema is data; hand-rolled
validators rot into a second source of truth.
auth sessions → use the framework's session + Auth0/Supabase.
Custom ONLY if a compliance control forces full
control of token storage. Default: don't.
Rule of thumb: every line of custom code is a liability you must
test, document, and maintain. Borrow before you build.One-line tweak
Point it at your `package.json` first and it will prefer libraries you already depend on, avoiding a new transitive tree for a one-off.
Untangle the deep-nesting and long-function smells
Run the skill's code-quality pass over a gnarly module: functions over 50 lines, nesting past three levels, files over 200 lines. It returns a refactor list using early returns and extracted, domain-named helpers.
ForAnyone staring at a 400-line file with five levels of indentation.
The prompt
Apply the code-quality rules to `src/billing/processInvoice.ts`: flag every function over ~50 lines, any nesting deeper than 3 levels, and the file itself if it's over 200 lines. For each, propose the fix — early-return guard clauses to kill the arrow-of-doom, and extractions into smaller functions with domain names (no `helper2`). If the file is too big, propose the split into multiple files. Show the before/after shape of the worst offender.What slides.md looks like
processInvoice.ts — 312 lines, splits into 3
worst offender: validateAndCharge() — 71 lines, 5-deep nesting
fix: invert the pyramid with guard clauses
// before // after
if (inv) { if (!inv) return err('no invoice')
if (inv.lines) { if (!inv.lines.length) return err('empty')
if (paid) { … } if (!paid) return err('unpaid')
} return charge(inv) // happy path, flat
}
split: → InvoiceValidator.ts · InvoiceCharger.ts · processInvoice.tsOne-line tweak
Cap the change at 'guard clauses only, no file split' when you want a low-risk diff that a reviewer can read in one sitting.
ADR drafted from a design discussion
Paste a messy Slack thread or meeting notes where the team argued about a choice; get back a clean Architecture Decision Record — context, options weighed, decision, consequences — using the skill's trade-off discipline.
ForWhoever got volunteered to 'write up what we decided' after the meeting.
The prompt
Turn these notes into an ADR. We debated event-driven vs. direct calls between the ordering and fulfilment contexts. Notes: `docs/meeting-2026-06.md`. Use the standard ADR shape — Context, Options considered (with the trade-off for each), Decision, Consequences (good and bad). Ground the reasoning in our actual constraints from the notes; don't invent a rationale we didn't discuss. Keep it under one page.What slides.md looks like
# ADR-014: Ordering → Fulfilment integration
## Context
Order placement must trigger dispatch. Contexts deploy together
today (modular monolith, ADR-009).
## Options
1. Direct call PlaceOrder → DispatchOrder
+ simplest, in-process transaction
− couples the two contexts at compile time
2. Domain event OrderPlaced, fulfilment subscribes
+ contexts stay decoupled; ready to split later
− eventual consistency; needs an outbox for reliability
## Decision
Domain event via an in-process bus + transactional outbox.
## Consequences
+ Splitting fulfilment to its own service later is a config change.
− We accept eventual consistency on dispatch; surface it in the UI.One-line tweak
Ask for a one-line 'Status: proposed' header and a link to the prior ADR it supersedes, and the record drops straight into a `docs/adr/` log.
Catch the NIH and anti-pattern smells in review
Give the skill a diff and ask it to flag the Not-Invented-Here moves and the named anti-patterns — custom auth where Auth0 fits, a `common/shared.js` dumping ground, business logic in a React component — before they reach main.
ForCode reviewers who want the architectural smells flagged automatically.
The prompt
Review this PR diff for the anti-patterns the architecture skill calls out: NIH syndrome (custom auth/state/validation where a standard library exists), generic-naming dumping grounds (`utils`, `helpers`, `common`, `shared`), and separation-of-concerns breaks (DB queries in controllers, business logic in UI components). For each hit, name the anti-pattern, the file:line, and the standard alternative. Skip style nits — only structural smells.What slides.md looks like
PR #218 — 3 architectural smells
⚠ NIH auth/session.ts — hand-rolled JWT refresh
→ use the framework session or Auth0; this is the
exact case the skill warns against owning.
⚠ generic-naming common/shared.ts — 9 unrelated exports added
→ split by domain; "shared" hides coupling.
⚠ concern-leak CartView.tsx L88 — tax calc inside the component
→ move to pricing/; UI renders, it doesn't compute.
No correctness bugs found — these are design-debt flags.One-line tweak
Restrict it to 'NIH only' on a dependency-light project where the team's bias is the opposite — too many libraries, not too few.
Error-handling and typed-catch pass
Ask the skill to harden a module's failure paths: typed catch blocks instead of swallowed errors, no empty `catch {}`, failures that map to a domain error rather than leaking a stack trace to the caller.
ForBackend engineers whose 'it works' code has no real failure story.
The prompt
Apply the error-handling rules to `src/payments/charge.ts`. Find every bare `catch` that swallows or re-throws raw, every place a third-party error leaks past the domain boundary, and any failure with no typed result. Propose typed catch blocks and a domain error type (e.g. `PaymentDeclined`, `GatewayUnavailable`) so callers branch on meaning, not on string matching. Keep the happy path readable; don't drown it in try/catch.What slides.md looks like
charge.ts — error-handling fixes
✗ L23 catch (e) { console.log(e) } ← swallowed, charge looks ok
→ rethrow as GatewayUnavailable; let PlaceOrder decide retry
✗ L40 Stripe.CardError leaks to the HTTP layer
→ map at the adapter: CardError → PaymentDeclined(reason)
✗ no Result type — callers can't tell decline from outage
type ChargeError = PaymentDeclined | GatewayUnavailable
async function charge(o: Order): Promise<Result<Receipt, ChargeError>>One-line tweak
Ask it to also add the matching `never`-exhaustiveness switch at the call site so a new error variant fails the build, not production.
Pre-merge architecture gate in CLAUDE.md
Wire the skill's rules into a repeatable review the agent runs on every feature branch: layering intact, no generic-named files added, no new custom util that a library covers, functions and files within the size budget.
ForLeads who want the architecture standards enforced without nagging in every PR.
The prompt
Draft a short architecture-gate checklist I can drop in CLAUDE.md so the agent self-reviews before proposing a merge. Base it on the software-architecture skill: (1) no DB queries in controllers, (2) no new `utils/helpers/common/shared` files, (3) no custom code where an established library exists, (4) functions under ~50 lines, files under ~200, nesting under 3, (5) domain-named modules only. Phrase each as a yes/no the agent answers with file:line evidence.What slides.md looks like
## Architecture gate (run before proposing a merge)
For this branch, answer each with evidence or "n/a":
[ ] Any DB query added inside a controller? (file:line)
[ ] Any new utils/helpers/common/shared file? (file:line)
[ ] Any custom code a known library covers? (which lib?)
[ ] Any function > ~50 lines or file > ~200? (file:line)
[ ] Any module with a generic, non-domain name? (file:line)
[ ] Business logic living in a UI component? (file:line)
If any box is checked, fix or justify before merge.One-line tweak
Add a final line — 'output PASS or a numbered fix list' — so the gate returns a machine-readable verdict your CI step can grep for.
Community signal
Three voices on why architectural judgment is the part of coding that does not come for free. The first is a working engineer; the next two are the canonical references the skill leans on — the dependency rule and the bounded-context pattern.
“Architecture decisions. AI builds what you ask for. It doesn't tell you 'hey, this feature should be behind a paywall' ... You need engineering judgment for that.”
u/JustinBundrick (17-year software engineer) · Reddit
A 17-year veteran who shipped 5 iOS apps with Claude Code — his sharpest takeaway is that architectural judgment is the gap the model doesn't fill on its own. A skill that encodes that judgment is exactly the fix.
“The overriding rule that makes this architecture work is The Dependency Rule. This rule says that source code dependencies can only point inwards.”
Robert C. Martin (Clean Coder blog) · Blog
The dependency rule is the spine of the skill's 'keep business logic independent of frameworks' and 'separate domain from infrastructure' guidance.
“Bounded Context is a central pattern in Domain-Driven Design. It is the focus of DDD's strategic design section which is all about dealing with large models and teams.”
Martin Fowler (martinfowler.com) · Blog
Use case 2 asks the skill to carve a service into bounded contexts — Fowler's definition is the canonical reference for what that boundary is and why it matters.
The contrarian take
The fair objection to any architecture skill comes from the same veteran in the community signal above:
“Without the engineering foundation, AI output would've been garbage I couldn't debug.”
u/JustinBundrick · Reddit
From a thread on shipping production apps with Claude Code — the limit of AI without an engineering foundation.
The honest critique of any architecture skill: it can't hand you judgment you don't have. True — but that's the point of encoding the rules. The skill turns 'follow Clean Architecture and DDD' from a sentence you have to already understand into a checklist Claude applies to your actual files, with the file:line evidence a junior dev can learn from. It narrows the experience gap; it doesn't pretend to erase it.
One more honest caveat: this skill is opinionated. Its rules — early returns, ~50-line functions, no utils folder, library-first — reflect a Clean Architecture and DDD worldview. If your team has a deliberate reason to diverge (a performance-critical hot path that justifies custom code, say), the skill will still flag it, and you override with a one-line justification. Treat it as a sharp reviewer with strong defaults, not a linter that is always right.
Worth naming the boundary too: there is no single MCP server that replaces this. The closest analogues are code-quality servers like Semgrep for static rules and DeepSource for automated review — they catch mechanical smells well, but they do not reason about bounded contexts or whether a feature belongs in a different layer. The skill brings the judgment; pair it with those servers for reach into CI.
Real projects in this shape
Public code that targets the same structure the skill reviews for — useful as a target shape when you write the prompt, and as proof the rules map to real production systems, not just textbooks.
- 45ck — software-architecture-skills, a public skill pack for architecture views, trade-offs, quality attributes and decision support
- davila7 — claude-code-templates (28k+ stars), the CLI and component library this skill ships in
- marcoturi — fastify-boilerplate, a production app built on Clean Architecture + DDD + CQRS, the shape these reviews target
- Armando1514 — Event-Driven-Microservices-Advanced, DDD + saga + outbox, the reference for use case 7's event-vs-direct ADR
- Robert C. Martin — The Clean Architecture, the dependency-rule essay the skill is built on
Gotchas (the four that bite)
Where an architecture skill goes wrong if you point it at the wrong thing or take its output uncritically. Read these before the first run.
It won't draw the diagram
The skill reasons about structure; it does not emit C4, UML, or sequence diagrams. If you ask for a picture, you get prose or a folder tree. Pair it with the mermaid skill (use case 2's tweak) when you need the rendered view.
Its rules are defaults, not laws
The ~50-line function and ~200-line file limits are heuristics from Clean Architecture, not universal truth. A dense, well-named state machine can exceed them and still be correct. When the skill flags one, judge the flag — override with a reason rather than mechanically splitting.
Library-first can over-reach
Pushed too hard, 'use a library' adds a transitive dependency tree for ten lines of code you could own. The skill names the carve-outs (security control, unique business logic, dependency overkill) — make it justify the library, not just name one.
Big refactors need the plan, not the diff
A bounded-context carve-up or a controller un-tangling touches callers across the repo. Always ask for the move plan first (every prompt above does). Approving a 30-file rewrite you didn't read is how a 'cleanup' breaks a release.
Pairs well with
Curated to match the cookbook’s real integrations: the same author’s line-level companion (clean-code), the review and design skills (code-reviewer, system-design, backend-architecture), and the MCP servers the reviews lean on for repo reach and CI.
Related skills
Related MCP servers
Two posts that compose well with this cookbook: What are Claude Code skills? covers the loading mechanism that keeps this skill near-free at idle, and 10 diagrams from one prompt with the Claude mermaid skill is the natural pair when the architecture you just designed needs to be drawn.
Frequently asked questions
What does the software architecture skill actually enforce?
Concrete rules, not vibes. It is based on Clean Architecture and Domain-Driven Design, so it separates domain logic from infrastructure, keeps database queries out of controllers and business rules out of UI components, and names modules for the domain instead of dumping them in utils/helpers/common/shared. It also applies code-quality limits — functions under roughly 50 lines, files under 200, nesting under three levels, typed error handling — and a library-first rule that pushes you toward an established package before you write a custom util.
Is this the same as an architecture review skill or an architecture review agent?
It is the practical version of one. The software architecture skill turns 'review my architecture' into a repeatable pass Claude runs over your real files: it flags layering violations, NIH (Not-Invented-Here) anti-patterns, generic-named dumping grounds, and oversized functions, each with file and line evidence. Use cases 4, 8, and 10 above are exactly an architecture review — on a single controller, on a PR diff, and as a pre-merge gate you wire into CLAUDE.md.
Does the software architecture skill support hexagonal architecture?
It supports the principle directly even though it names Clean Architecture and DDD. Hexagonal (ports and adapters) is the same core idea: business logic in the center, infrastructure at the edges behind interfaces. The skill's 'keep business logic independent of frameworks' and 'separate domain from infrastructure' rules produce ports-and-adapters seams — use case 2 stubs a `ports/PaymentGateway` interface, and use case 4 extracts an `OrderRepository` port out of a controller. Ask for ports explicitly and it will frame the review in hexagonal terms.
Can it write an Architecture Decision Record (ADR) for me?
Yes — use case 7 is built for it. Paste the meeting notes or Slack thread where the team argued a choice, and the skill returns a standard ADR: Context, Options with the trade-off for each, Decision, and Consequences. It grounds the reasoning in the constraints you actually discussed rather than inventing a rationale, and it keeps the record under a page so it drops straight into a docs/adr/ log.
Will it just rewrite my code, or does it propose a plan first?
It proposes first by design. Every cookbook entry asks for a review or a move plan — the utils audit returns a rename table, the controller audit returns a worst-first violation list, the smell pass shows the before/after shape — before any edit. That is deliberate: architecture changes touch callers across the repo, so you want the plan to read in one sitting and then approve the diff, not discover a 30-file rewrite after the fact.
How is the skill different from pasting Clean Architecture rules into CLAUDE.md?
A skill loads only when an architecture task triggers it — roughly 100 tokens at idle — so it costs almost nothing on unrelated work. A CLAUDE.md block loads on every single turn, so you pay the full ruleset tax even when you're fixing a typo. Use the skill for the occasional review or design pass; reserve CLAUDE.md for the short gate in use case 10 that you genuinely want checked on every branch.
Is there an MCP server that does architecture review instead?
Not a single drop-in equivalent, but the skill pairs with several MCP servers to do the job. Code-quality servers like Semgrep let you turn a recurring smell into a static rule that fails CI, the GitHub server posts the skill's findings as inline PR review comments, and the Filesystem server lets Claude read the whole src/ tree before proposing a rename. The skill supplies the architectural judgment; the MCP servers give it reach into your repo and pipeline.
Sources
Primary
- davila7 / claude-code-templates — software-architecture SKILL.md (the skill source)
- Robert C. Martin — The Clean Architecture (the dependency rule)
- Martin Fowler — Bounded Context (Domain-Driven Design)
- Simon Brown — the C4 model (context / container / component / code)
Community
- u/JustinBundrick (17-year software engineer) — Reddit
- Robert C. Martin (Clean Coder blog) — Blog
- Martin Fowler (martinfowler.com) — Blog
- gnbitcom — Robert C. Martin - Clean Architecture and Design (YouTube)
- GOTO Conferences — Modular Monoliths • Simon Brown • GOTO 2018 (YouTube)
Internal