Skip to content
Improve Codebase Architecture

Improve Codebase Architecture Skill

Matt Pocock's /improve-codebase-architecture command: finds shallow modules worth deepening, renders them as a visual HTML report with before/after diagrams, then grills you through the one you pick.

GitHub Docs

Install

Install with the skills CLI

One command for Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf and dozens of other agents. Needs Node.js; the skill is fetched straight from mattpocock/skills.

$ npx skills add mattpocock/skills --skill improve-codebase-architecture

Run it in a terminal. The CLI finds the agents installed on your machine, asks which ones to add the skill to, and whether to install it into the folder you ran it from or for all your projects.

Other ways to install

Copy the whole skill folder — SKILL.md and any scripts or references beside it — into ~/.claude/skills/improve-codebase-architecture/, where Claude Code picks it up in every project. Only git is needed.

tmp=$(mktemp -d) && \
  git clone --depth 1 --branch main https://github.com/mattpocock/skills.git "$tmp" && \
  mkdir -p ~/.claude/skills && \
  cp -R "$tmp"/skills/engineering/improve-codebase-architecture ~/.claude/skills/improve-codebase-architecture

No scripts or references next to it? Saving the SKILL.md alone as ~/.claude/skills/improve-codebase-architecture/SKILL.md works too.

Using another agent? Its personal skills folder
Codex
~/.agents/skills/
Cursor
~/.cursor/skills/
GitHub Copilot
~/.copilot/skills/
Gemini CLI
~/.gemini/skills/
Windsurf
~/.codeium/windsurf/skills/
OpenCode
~/.config/opencode/skills/

About

  • User-invoked only; scopes the scan from git history hot spots
  • Explores with a fresh-context sub-agent and applies the deletion test
  • Writes a visual HTML report with before/after diagrams outside the repo
  • Grills you through the chosen refactor and keeps GLOSSARY.md and ADRs current

Improve Codebase Architecture is a user-invoked command from Matt Pocock's skills collection (its frontmatter sets disable-model-invocation, so it runs only when you type it). It looks for deepening opportunities: refactors that turn shallow modules, whose interface is nearly as complex as their implementation, into deep ones that are easier to test and easier for an AI agent to navigate.

It starts by scoping. Unless you name an area, it walks the git history to find hot spots, then hands a sub-agent a fresh context to explore the code and note friction: concepts scattered across many small modules, pure functions extracted only for testability, coupling that leaks across seams, untested areas. Suspects get the deletion test: would removing the module concentrate complexity or just move it?

Candidates are written to a self-contained HTML report in the OS temp directory (Tailwind and Mermaid from a CDN), one card per candidate with the files involved, the problem, the proposed change, the benefits, a before/after diagram and a strength badge, ending in a top recommendation. Nothing lands in the repository. When you choose one, it calls the companion grilling skill to work through the design decisions, updates GLOSSARY.md as terms sharpen, and offers to record an ADR when you reject a candidate for a lasting reason. It depends on the codebase-design, grilling and domain-modeling skills from the same repository. MIT-licensed.

SKILL.md

The instructions your agent loads, as published by Matt Pocock.

SKILL.md
name
improve-codebase-architecture
description
Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick.
disable-model-invocation
true

Improve Codebase Architecture

Surface architectural friction and propose deepening opportunities: refactors that turn shallow modules into deep ones. The aim is testability and AI-navigability.

This command is _informed_ by the project's domain model and built on a shared design vocabulary:

  • Call the Skill tool with "codebase-design" for the architecture vocabulary (module, interface, depth, seam, adapter, leverage, locality) and its principles (the deletion test, "the interface is the test surface", "one adapter = hypothetical seam, two = real"). Use these terms exactly in every suggestion, and don't drift into "component," "service," "API," or "boundary."
  • The domain language in GLOSSARY.md gives names to good seams; ADRs in docs/adr/ record decisions this command should not re-litigate.
Process
1. Explore

Scope before you scan: YAGNI. Deepening a module pays off by making future changes to it easier, so put extra weight on the parts of the codebase that have recently changed. Decide where to look before you look:

  • If the user named a direction (a module, a subsystem, a pain point), take it, and skip the inference below.
  • Otherwise, walk back a good stretch of the commit history (git log --oneline) to find the codebase's hot spots, the files and areas that keep coming up, and let those paths pull your attention first. If the changes are scattered with no clear hot spot, widen the net.

Read the project's domain glossary (GLOSSARY.md) and any ADRs in the area you're touching first.

Then spawn a sub-agent with a fresh context window to walk the codebase. Don't follow rigid heuristics; explore organically and note where you experience friction:

  • Where does understanding one concept require bouncing between many small modules?
  • Where are modules shallow, with an interface nearly as complex as the implementation?
  • Where have pure functions been extracted just for testability, but the real bugs hide in how they're called (no locality)?
  • Where do tightly-coupled modules leak across their seams?
  • Which parts of the codebase are untested, or hard to test through their current interface?

Apply the deletion test to anything you suspect is shallow: would deleting it concentrate complexity, or just move it? A "yes, concentrates" is the signal you want.

2. Present candidates as an HTML report

Write a self-contained HTML file to the OS temp directory so nothing lands in the repo. Resolve the temp dir from $TMPDIR, falling back to /tmp (or %TEMP% on Windows), and write to <tmpdir>/architecture-review-<timestamp>.html so each run gets a fresh file. Open it for the user (xdg-open <path> on Linux, open <path> on macOS, start <path> on Windows) and tell them the absolute path.

The report uses Tailwind via CDN for layout and styling, and Mermaid via CDN for diagrams where a graph/flow/sequence reliably communicates the structure. Mix Mermaid with hand-crafted CSS/SVG visuals: use Mermaid when relationships are graph-shaped (call graphs, dependencies, sequences), and hand-built divs/SVG when you want something more editorial (mass diagrams, cross-sections, collapse animations). Each candidate gets a before/after visualisation. Be visual.

For each candidate, render a card with:

  • Files: which files/modules are involved
  • Problem: why the current architecture is causing friction
  • Solution: plain English description of what would change
  • Benefits: explained in terms of locality and leverage, and how tests would improve
  • Before / After diagram: side-by-side, custom-drawn, illustrating the shallowness and the deepening
  • Recommendation strength: one of Strong, Worth exploring, Speculative, rendered as a badge

End the report with a Top recommendation section: which candidate you'd tackle first and why.

Use GLOSSARY.md vocabulary for the domain, and the `/codebase-design` vocabulary for the architecture. If GLOSSARY.md defines "Order," talk about "the Order intake module," not "the FooBarHandler," and not "the Order service."

ADR conflicts: if a candidate contradicts an existing ADR, only surface it when the friction is real enough to warrant revisiting the ADR. Mark it clearly in the card (e.g. a warning callout: _"contradicts ADR-0007, but worth reopening because…"_). Don't list every theoretical refactor an ADR forbids.

See [HTML-REPORT.md](HTML-REPORT.md) for the full HTML scaffold, diagram patterns, and styling guidance.

Do NOT propose interfaces yet. After the file is written, ask the user: "Which of these would you like to explore?"

3. Grilling loop

Once the user picks a candidate, call the Skill tool with "grilling" to walk the decision tree with them: constraints, dependencies, the shape of the deepened module, what sits behind the seam, what tests survive.

Side effects happen inline as decisions crystallize; call the Skill tool with "domain-modeling" to keep the domain model current as you go:

  • Naming a deepened module after a concept not in `GLOSSARY.md`? Add the term to GLOSSARY.md. Create the file lazily if it doesn't exist.
  • Sharpening a fuzzy term during the conversation? Update GLOSSARY.md right there.
  • User rejects the candidate with a load-bearing reason? Offer an ADR, framed as: _"Want me to record this as an ADR so future architecture reviews don't re-suggest it?"_ Only offer when the reason would actually be needed by a future explorer to avoid re-suggesting the same thing; skip ephemeral reasons ("not worth it right now") and self-evident ones.
  • Want to explore alternative interfaces for the deepened module? Call the Skill tool with "codebase-design" and use its design-it-twice parallel sub-agent pattern.
Install

Reduces accumulated complexity without changing behaviour, using Chesterton's Fence to avoid deleting the thing that was load-bearing.

Skill: TDD

by Matt Pocock

New

Matt Pocock's test-driven development skill: one red-to-green slice at a time, tests only at seams agreed with you first, and a named list of test anti-patterns to avoid.

A controlled upgrade path from Inngest SDK v3 to v4 — triggers into createFunction options, EventSchemas to eventType, realtime imports, step.invoke string IDs — with a scan-first, verify-last order.

An evidence-first audit skill: walk an existing TypeScript repo, name the exact call sites where background work can be lost, and land an incremental durability plan.

Browse all skills →