agentleFS
narenaryannarenaryan/agent-skills/skills/engineering/modularize-large-files/SKILL.md

modularize-large-files

Skill0 starsChanged 39 days agoMITView on GitHub

Use when a source file has grown past ~2k lines or a "god module" is hard to navigate - finds the largest files, splits them along cohesion seams (not arbitrary line counts), preserves the public API with re-exports, and moves in behavior-preserving steps verified by tests between each extraction

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 6 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Treat anything over ~2k lines as a candidate.

    line 25
  2. Distinctive:

    Run typecheck + tests. Green before the next extraction.

    line 48
  3. Distinctive:

    Commit per extraction — small, revertable, reviewable diffs.

    line 49
  4. Distinctive:

    Only after all seams are out and green, migrate callers off the barrel to direct imports if the project prefers that, as a separate commit.

    line 51
  5. Distinctive:

    Never mix a refactor with a behavior change in the same commit.

    line 56
  6. Distinctive:

    If a function needs private module state to move, extract the state too or pass it explicitly.

    line 60

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Modularize Large Files

Line count is a symptom, not the disease. A 2k-line file is a prompt to look for seams, not a mandate to chop it into ten 200-line files that all import each other. Split along cohesion boundaries so each new module has one reason to change; if the pieces still need each other's internals, you have moved the mess, not fixed it.

Find the offenders

Rank by size, then read before cutting:

# Largest tracked source files by line count (skip vendored/generated)
git ls-files '*.ts' '*.tsx' '*.js' '*.py' '*.go' '*.rs' \
  | grep -Ev '(dist|build|vendor|node_modules|\.min\.)' \
  | xargs wc -l | sort -rn | head -20

Treat anything over ~2k lines as a candidate. Do not auto-split: a large file that is genuinely one cohesive thing (a generated parser, a single state machine) can be fine.

Find the seams

Inside the file, look for clusters that move together:

  • Types/domain — interfaces, enums, schemas with no runtime behavior. These become a leaf module everything else imports; extract them first.
  • Pure vs I/O — pull pure helpers away from DB/network/filesystem code.
  • Distinct responsibilities — a group of functions sharing a prefix, a concern (auth, formatting, validation), or the same private state.

The best cut is the one that produces the fewest cross-imports between the new modules. If two candidate modules would import each other's internals, the seam is wrong — merge them or lift the shared piece into a third leaf module.

Move without breaking callers

  1. Extract one seam into a new file; keep names identical.
  2. In the original file, re-export what you moved (export * from './x' or a barrel index) so external callers keep working unchanged.
  3. Run typecheck + tests. Green before the next extraction.
  4. Commit per extraction — small, revertable, reviewable diffs.

Only after all seams are out and green, migrate callers off the barrel to direct imports if the project prefers that, as a separate commit.

Guardrails

  • Never mix a refactor with a behavior change in the same commit.
  • Watch for circular imports the split introduces — the shared piece belongs in a leaf, not in either sibling.
  • Preserve test file structure: split the test file along the same seams.
  • If a function needs private module state to move, extract the state too or pass it explicitly; don't reach across module boundaries with globals.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.