From mcclowes-skills
Use when deciding how to organise code in an AI-assisted codebase — whether to split or merge a file, where to draw module boundaries, how big a file should get, or whether to separate logic from rendering/styles/data. Triggers on "should I split this file", "this file is getting too big", "separate concerns", "where should this code live", reviewing or refactoring file/module organisation, structuring a new component or feature, or any architecture decision where part of the audience is an AI coding agent. Apply this whenever someone is choosing how to lay code out across files and an LLM will be reading or editing it, even if they only say "refactor this" or "clean up the structure" without mentioning AI.
How this skill is triggered — by the user, by Claude, or both
Slash command
/mcclowes-skills:ai-aware-code-structureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
How to organise code across files when an AI coding agent is one of the readers. This is not "AI changes everything" — good, well-abstracted code reads well for humans and machines alike. But at the margins (how aggressively to split, how much to co-locate, how self-contained each file must be), AI shifts the trade-offs, and this skill is about getting those margins right.
How to organise code across files when an AI coding agent is one of the readers. This is not "AI changes everything" — good, well-abstracted code reads well for humans and machines alike. But at the margins (how aggressively to split, how much to co-locate, how self-contained each file must be), AI shifts the trade-offs, and this skill is about getting those margins right.
Reach for this whenever the question is where code lives, not what it does: splitting a growing file, drawing a module boundary, deciding whether to peel logic out of a component, or reviewing an existing layout. It assumes an LLM will read or edit the result — which today is almost always true.
Code organisation has always balanced two readers: human readability (can someone understand this?) and maintainability (can it change safely?). AI adds a third: machine readability — can an agent operating in a limited context window understand and safely edit this?
For the most part these align. Clear structure with good abstractions serves all three. The interesting decisions are the ones where they pull apart.
AI tools are remarkably reluctant to look at other files. They work with what's in front of them, and getting them to proactively explore adjacent files is like pulling teeth. A human navigates a four-file component intuitively — glances at the sibling, holds the model across files without thinking. An agent doesn't. It works with the open file and makes confident changes that break because it never checked how a prop was shaped two files over.
This produces a genuine tension, and both halves are real:
The resolution isn't "split less" or "split more." It's to split along boundaries that survive the agent's reluctance to look around.
Don't ask "is this a separate concern?" Ask:
Can this concern be understood in isolation?
That single question resolves most cases:
So separation is still good — but the boundary has to be one where each side stands on its own.
Co-locate tightly coupled code. If two pieces are always changed together and each needs the other for context, keep them in one file. This is the single highest-value move: it removes the cross-file lookup that an agent is most likely to skip, so it works from a complete picture instead of a partial one.
Raise the file-size threshold. The old rule — "if it doesn't fit on a screen, split it" — was calibrated for human scrolling. Agents handle larger files well, roughly up to a few hundred lines before quality degrades. A cohesive 150-line file that keeps logic and rendering together beats two 75-line files that are meaningless apart. There's still a ceiling: past ~300 lines signal-to-noise drops and you should split — but split for that reason, not out of reflex.
Prefer abstractions over file structure. A well-named custom hook (or function, or module) beats splitting files, because it's a real abstraction: it has an interface, it hides its implementation, and the consuming code is understandable without reading the internals. The agent reads useCheckout() at the call site and knows enough to proceed. Splitting a file only relocates code; an abstraction actually reduces the context needed to work with it. When tempted to split for readability, ask whether the right move is an abstraction instead.
When you do split, make each side self-contained. The test for a good split is whether each resulting file can be understood and edited without opening the others. If a file references props, types, or values that only make sense by reading a sibling, the boundary is in the wrong place — either move it or merge back.
| Situation | Lean toward |
|---|---|
| Pure presentation (props → output, no side effects) | Separate — self-documenting, low external context |
| Logic + rendering that need each other to make sense | Co-locate — splitting just doubles unperformed lookups |
| File growing but still one coherent concern, < ~300 lines | Keep together — cohesion beats line count |
| File past ~300 lines or covering several concerns | Split — signal-to-noise is now the problem |
| Tempted to split a file purely for readability | Extract an abstraction (hook/function/module) instead |
| A proposed split leaves files that only make sense together | Don't split — the boundary is wrong |
This is a current trade-off, not a permanent law. The reluctance to read adjacent files is a limitation of today's tools, not a fundamental one — as agents get better at navigating codebases, the threshold will drift back toward aggressive separation. Structure for the tools you have.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub mcclowes/skills --plugin mcclowes-skills