/modularity — Modular Design Enforcement
Every design, plan, and implementation MUST produce small, focused modules where any single change touches the fewest files possible and every touched file fits comfortably in context.
Why this matters: When files are large or tightly coupled, Claude must compact context to fit them — risking loss of key details. Modular design prevents this by keeping each unit small enough to reason about completely.
When to invoke: During PLANNING (after brainstorming, before or alongside writing-plans) and during REVIEW (as part of code review criteria). This skill applies to both new code and modifications to existing code.
The Rules
Rule 1: File Size Limits
| File type | Soft limit | Hard limit | Action at hard limit |
|---|
| Source code (logic) | 150 lines | 300 lines | MUST split before proceeding |
| Test files | 200 lines | 400 lines | MUST split into focused test suites |
| Config / data | 100 lines | 200 lines | MUST split into per-concern configs |
| Documentation | 300 lines | 500 lines | MUST split into linked pages |
Soft limit: Refactor soon. Flag in code review.
Hard limit: Do not proceed. Split first, then continue.
Line counts exclude blank lines and comments. If a file approaches the soft limit during implementation, split it before the next commit — not "later."
Rule 2: Single Responsibility Per File
Every file answers ONE question:
- "What does this file do?" must have a one-sentence answer.
- If the answer contains "and," the file does too much — split it.
- If two developers could work on different parts of the file simultaneously on unrelated tasks, it should be two files.
Rule 3: Change Locality
Design so that any single feature, fix, or change touches at most 3-5 files (excluding tests). If a change requires touching more than 5 source files:
- STOP. The design has a coupling problem.
- Identify which files are changing for the same reason — they should share an abstraction.
- Identify which files are changing for different reasons — they need a cleaner interface between them.
Rule 4: Interface-First Design
Before writing any implementation:
- Define the module's public interface — what it exposes to consumers.
- Define its dependencies — what it imports/requires.
- The interface should be understandable without reading the implementation.
- Consumers should never need to know implementation details.
If you can't define the interface in <10 lines, the module is too complex — decompose further.
Rule 5: Context-Window-Aware Decomposition
When designing a system, apply this test to every module:
"Can Claude read this file, its tests, and the files it directly depends on — all at once — without exceeding context or needing to compact?"
If no: the module is too large or has too many dependencies. Decompose until the answer is yes.
Practical guideline: Any single task (implement, fix, review) should require reading at most 5-7 files totaling under 1500 lines. Design the system to make this true.
Rule 6: Dependency Direction
- Dependencies flow ONE direction (no circular imports).
- High-level modules depend on abstractions, not low-level details.
- If module A imports module B and module B imports module A, extract the shared concern into module C.
Rule 7: Co-location
Files that change together live together. Organize by feature/domain, not by technical layer.
WRONG (layer-based):
controllers/user.ts
controllers/order.ts
services/user.ts
services/order.ts
models/user.ts
models/order.ts
RIGHT (feature-based):
user/controller.ts
user/service.ts
user/model.ts
order/controller.ts
order/service.ts
order/model.ts
When a change to "users" only touches files in
, modularity is working.
Applying This Skill
During Planning (brainstorming / writing-plans)
Before finalizing any design or plan, run the Modularity Checklist:
If any item fails: redesign before proceeding to implementation. Do not defer modularity to refactoring — it is far cheaper to decompose correctly upfront.
During Implementation (executing-plans)
As you write code:
- Check file size after each commit. If approaching the soft limit, split NOW.
- If a function grows beyond 30 lines, extract sub-functions or a helper module.
- If you're adding a new feature and touching >5 files, stop and ask: "Is there a missing abstraction?"
During Review (code-review / receiving-code-review)
Verify these as part of every code review:
- No file exceeds the hard limit
- Each file's responsibility is clear and singular
- Change locality: the PR touches a reasonable number of files
- No circular dependencies introduced
- New modules have well-defined interfaces
When Modifying Existing Code
If existing code violates these rules:
- You are NOT required to fix all violations in unrelated files.
- You ARE required to not make violations worse.
- If the file you're modifying already exceeds the hard limit, include a split as part of your change.
- If your change would push a file past the soft limit, split first.
Splitting Strategies
When a file needs to be split, use these patterns:
By abstraction level: →
,
,
Extract shared logic: If two files share helper functions, extract to a shared module rather than duplicating.
Anti-Patterns
| Pattern | Problem | Fix |
|---|
| "God file" — one file does everything | Impossible to change safely | Split by responsibility |
| "Shotgun surgery" — one change touches 10+ files | Missing abstraction | Extract shared concern |
| "Barrel files" re-exporting everything | Hides dependency structure | Import directly from source |
| Premature abstraction for one use case | Unnecessary complexity | Three similar blocks > one premature abstraction |
| Layer-based organization | Unrelated files change together | Reorganize by feature |
| "Utils" or "helpers" grab-bag | No clear responsibility | Split by domain or delete |
Rationalization Prevention
| Excuse | Reality |
|---|
| "It's just one more function" | That's how 800-line files happen. Split now. |
| "Splitting will create too many files" | Many small files > few large files. Always. |
| "I'll refactor later" | You won't. The soft limit exists to prevent this. |
| "This file is the natural home for this" | If it exceeds the limit, it's not. Find a better home. |
| "It's all related" | Related is not the same as same-responsibility. |
| "The framework forces this structure" | Most frameworks work fine with smaller modules. Check. |