DEV Community

Cover image for I treated skills like dotfiles. Then they started spawning subagents.
Vineeth N Krishnan
Vineeth N Krishnan

Posted on • Originally published at vineethnk.in

I treated skills like dotfiles. Then they started spawning subagents.

I treated skills like dotfiles. Then they started spawning subagents.

A row of cartoon config files on a shelf, one of them sprouting little arms and calling three small helper robots through a glowing portal, flat illustration, soft colors, modern editorial style.

TL;DR: My CLAUDE.md was turning into a Frankenstein .bashrc. Universal rules and one-off behaviours mashed together into a config file that kept growing by a few lines every week. Then Claude Code skills landed and my first instinct was, oh, these are basically dotfiles for Claude. The instinct was half right. Skills do behave like dotfiles in how they load. Opinionated, intent-triggered, version-controlled. But they go one step further. Skills can dispatch work to subagents. A dotfile sits there. A well-shaped skill knows how to recruit help when the task is bigger than one prompt. Dotfiles never did that. Skills go to work.

So let me back up a little.

The CLAUDE.md that ate itself

A while back I noticed my CLAUDE.md had quietly become the longest config file in my home directory. Not the most-edited. Not the most-read. Just the longest. Every hard lesson I had paid for in production ended up there. The schema-verification protocol I built after one too many "column does not exist" errors. The pre-merge audit checklist that catches regressions in a diff. The refactor playbook that forces every rename to trace its call sites before touching code. Every time a bug came back to bite me, I would tab over to that file and tack on the guardrail I wished had been in place.

Some sections genuinely belonged there. A rule like "never assume, verify before you respond or troubleshoot" is exactly the kind of always-on guardrail you want every session to start with. But other sections were not like that. The schema-verification protocol was a long, layered procedure with its own decision tree, fallback commands, and known gotchas for the legacy database. I do not need that loaded when I am writing prose or wiring up a frontend component. I need it loaded the moment I am about to touch a query. Different moment, different need.

But CLAUDE.md does not care. CLAUDE.md is sourced every time. It is the .bashrc of the Claude world. Whatever you put in there shows up in every conversation, whether you wanted it there or not.

If your config file has crossed a few hundred lines and you still keep adding to the bottom, you already know the shape of the problem.

My first instinct was dotfiles

When skills landed in Claude Code, my first reaction was the same one I imagine most developers had. Oh nice, these are just dotfiles for Claude.

The vibe is right. Skills are:

  • Opinionated. They reflect how you write, how you commit, how you review.
  • Version-controlled. They live in a folder. You can git track them. You can share them.
  • Intent-triggered. A skill loads when it becomes relevant, not before.
  • Composable. You install the ones you want, ignore the ones you do not.

That is dotfiles. That is exactly the model. The same way I keep a .zshrc because I do not want to retype aliases on every machine I touch, I now reach for skills because I do not want to paste the same workflow rules every time I am about to do something specific.

So I started moving things out of CLAUDE.md. The schema-verification protocol, with its full audit machinery and database-specific gotchas, became a verify-before-query skill. The pre-merge audit became a ship-readiness skill, complete with diff scanning, regression-pattern flagging, and a test-coverage gate. The refactor playbook, the one that traces every call site before allowing a rename, became its own skill. Slowly, CLAUDE.md shrank. The bloated file became leaner, and the sections that remained genuinely deserved to be always-on.

The split that worked

After a few rounds of pulling things out, a pattern showed up. Two kinds of rules ended up in two different places.

Always-on, universal rules stayed in CLAUDE.md:

  • Behavioural guardrails (verify before responding, ask when uncertain, do not invent APIs)
  • Naming and coding conventions that apply to every file you write
  • Testing standards that should be remembered any time tests are involved
  • Quality gates that you want enforced regardless of task

On-demand, situational rules moved into skills:

  • Schema-verification protocol (only matters when you are about to query or migrate a database)
  • Pre-merge ship-readiness audit (only matters right before you push a branch)
  • Refactor planning playbook that fans out call-site discovery (only matters when you are restructuring a module)
  • Incident triage runbook with parallel log and metric scans (only matters when something is broken in production)

Same way you keep export PATH=... in your .bashrc but you keep your CLI tools in /usr/local/bin and only call them when the task asks for them. Universal stays at the entry point. Specific moves into discrete, callable units.

Here is what that ends up looking like on disk, once you have done a few rounds of moving things out:

~/.claude/
├── CLAUDE.md                       # the lean .bashrc - always loaded
└── skills/
    ├── verify-before-query/
    │   └── SKILL.md                # schema audit, fallback commands, gotchas
    ├── ship-readiness/
    │   ├── SKILL.md                # pre-merge checklist
    │   └── references/
    │       └── regression-patterns.md
    ├── refactor-plan/
    │   └── SKILL.md                # fans out call-site tracing
    └── incident-triage/
        ├── SKILL.md                # parallel log + metric scans
        └── references/
            └── known-fingerprints.md
Enter fullscreen mode Exit fullscreen mode

The shape is the point. CLAUDE.md sits at the top, lean and universal. Each skill is its own folder with its own SKILL.md and its own supporting references, isolated from every other skill. Same mental model as ~/.config/ or /usr/local/bin/. You can git track the whole tree, share it with a teammate, swap one skill out without touching the others.

The split clicked for me when I noticed a section in my CLAUDE.md had been reduced to a one-liner that pointed to a skill, saying in effect "the rule is X, see the skill for the full rationale and the audit machinery." That single line is the analogy made literal. The always-on rule lives at the entry point. The heavy machinery lives in the skill that gets invoked when the situation calls for it.

Then the analogy broke

A central glowing folder dispatching three small helper robots through separate portals to do parallel tasks, with a single report scroll returning to the center, flat illustration in soft pastel colors.

I sat with the dotfiles-for-Claude framing for a bit and felt pretty pleased with myself. Then I noticed a difference I could not ignore.

A .bashrc is passive. It defines an alias and waits. The alias runs in your shell, in your process, in your context. It does not spin up another shell, hand it a task, get back a summary, and let you move on. That is a different category of thing.

A skill can do exactly that. A well-shaped skill can fan out helpers for the parallelisable parts of a task. Tracing every call site of a function before approving a rename. Scanning a year of deploy logs against an error fingerprint during incident triage. Auditing a large diff against a long list of regression patterns before letting the merge go through. The grunt work runs on its own lane and comes back as a single report, while your main thread stays clean and ready to make the actual decision. That is not something a dotfile has ever done in the history of dotfiles.

A dotfile is a snapshot of preferences. A skill is a snapshot of preferences plus a workflow. The workflow is yours to shape, and when the work is bigger than one prompt, it can call for backup.

Why this matters in practice

Three things shifted in how I think about my AI setup once this clicked.

One. I stopped putting per-task rules into CLAUDE.md. Whenever I am about to add a section, I ask myself, is this rule something I want Claude to know every time, or only when I am doing a specific kind of task? If it is the second, it goes into a skill. CLAUDE.md stays close to what .bashrc should be. Tight. Universal. Mostly stable.

Two. I started thinking about skill-internal delegation as a first-class design choice. When tuning a skill, I now decide which steps should fan out and which should stay single-threaded. The research-heavy steps (call-site tracing, regression-pattern auditing, log scanning, dependency-tree walking) get dispatched to subagents. The judgement-heavy steps (choosing the migration strategy, picking which regressions are real, deciding what to ship) stay in the main thread. A skill is not just a prompt. It is a workflow, and a workflow can dispatch.

Three. Sharing got more interesting. When you share a skill with a teammate, you are not just sharing your preferences. You are sharing a small workflow that knows how to recruit help when the task is bigger than itself. That changes the conversation. "Use my skill" becomes closer to "use my whole approach, including how it scales when the work is heavy."

Where the analogy gets uncomfortable

I do not want to oversell this. The dotfiles framing is useful as an entry point, but it bends in a few places. Worth saying out loud.

First, the always-on versus on-demand split is not as clean as I made it sound. Some sections still in my CLAUDE.md are arguably skill-shaped too. Stack-specific coding conventions. Framework patterns. API contracts. They only matter when I am working in that particular stack. They are not truly universal. A purist would extract them. I have not yet, partly because the boundary is fuzzy, partly because moving them out means trusting that the right skill activates at the right moment, and that trust takes time to build. Honest answer: this is a work in progress.

Second, dotfiles are passive. They define. Skills are active. They can do. That is not a difference of degree, it is a difference of category. When you copy someone else's .bashrc, the worst case is your shell behaves slightly weird until you remove the offending line. When you install someone else's skill, the worst case is much more interesting, because the skill might delegate to a subagent that runs code, opens PRs, or talks to your APIs. Skills come with more power, and therefore more responsibility for whoever is curating the list.

Third, sharing skills across machines and teams is not yet a solved problem the way dotfiles are. There is no stow for skills. No chezmoi equivalent. No widely-adopted "here is my skill repo, symlink-mount it into ~/.claude/skills/ and you are done" pattern. The ecosystem is still young. People are figuring it out as we go.

So the right framing is closer to this. Dotfiles is the entry-point analogy. Once you internalise the analogy, you can start to see that skills are a strict superset. They borrow the dotfiles vibe and then add agency on top.

The mental model I landed on

Two cartoon vertical stacks side by side: a terminal-styled stack on the left with a config scroll on top and small toolbox icons below, mirrored by a robot-styled stack on the right with the same shape but glowing module folders, connected by a thin dotted arrow showing the parallel architecture, flat illustration in soft pastel colors.

Here is how I now think about the whole stack.

.bashrc and CLAUDE.md are the same kind of object. Both are "load this every time I start a session." Both should be lean, opinionated, and universal. Both should grow rarely and shrink often.

Skills and /usr/local/bin/<tool> are the same kind of object. Both are "invoke this when the task calls for it." Both can do heavy work that does not belong in the rc file. Both can be shared, versioned, swapped out.

The new piece, the part that makes skills not just dotfiles, is that skills can spawn subagents. Your tool in /usr/local/bin/ does not call another shell to delegate work back to itself. A skill can. That is the upgrade. That is why "dotfiles with agency" is a more accurate metaphor than "dotfiles for Claude."

If you are still piling rules into CLAUDE.md and have not yet started moving the per-task ones out into skills, give the exercise a try. Even just the act of asking "is this rule universal, or is this for a specific moment?" sharpens your sense of what each layer is for. You may end up with a leaner CLAUDE.md, a few well-tuned skills, and a setup that finally has the kind of layered shape your terminal config has had for years.

That is all I had on this one. If you made it till here, thank you, genuinely. See you in the next one, where I will probably be complaining about something else that broke.

Top comments (0)