Your AI skills need version control
Blog · 6 min read
Before package managers, "using someone else's code" meant copying a file into your project. It worked, right up until the original file got a bug fix and yours didn't, or your copy diverged just enough that merging the fix back in wasn't a copy-paste anymore. We solved this decades ago for code. Skills are living through the exact same problem now, and mostly without the solution.
Ask around and you'll find the same pattern everywhere: a good prompt for reviewing pull requests gets pasted into project A, then again into project B because it worked well there too, then a third time with two lines changed for a different language. That's not one skill anymore. That's three prompts with a shared ancestor and no way to tell, six months later, which one is "the real one" or whether any of the fixes made to A ever made it to C.
What copy-paste actually costs you
- Fixes don't propagate. Find a mistake in the shared logic and you have to remember every place you pasted it, then go fix each one by hand.
- There's no diff. When two copies disagree, you can't tell what changed on purpose versus what someone forgot to update.
- There's no rollback. A change that turns out to be wrong has already overwritten the version that worked.
None of this is a reason to stop composing skills from other skills — sharing a testing philosophy across five language-specific skills, or a house style guide across a dozen more specific ones, is exactly the kind of reuse worth doing. It's a reason those shared pieces need the same discipline code dependencies get: a real version, a declared constraint, and a place where "current" means something.
The package-manager model, applied to instructions
Treat a skill like a package instead of a text block, and the whole class of problem goes away the same way it did for code:
- A skill has a version. Change it, and the version changes with it.
- Another skill can depend on it with a constraint (
>=1.0.0), instead of embedding its content. - Publishing an update to the dependency updates every dependent that resolves it — no hunting down copies.
- A version can be deprecated without breaking whatever is still pinned to it.
- Diverging on purpose is a fork, recorded as one, not an untracked copy-paste.
This is the same shape as npm, pip, or cargo — not because skills are code, but because "many things depend on a shared thing that changes over time" is the same problem regardless of what's in the file.
A skill that only exists as pasted text has no lineage. A skill that's versioned and composable has a history you can actually reason about.
Try it
The tutorial Compose and version skills like code walks through declaring a dependency, publishing an update that every dependent picks up, and forking a skill without losing track of where it came from.
Give your skills a version history.