If you're building workflows around AGENTS.md, SKILL.md, Codex-style agents, or team-specific AI playbooks, you've probably run into the same awkward gap:
we have a decent format for skills, but not a great way to distribute them.
Copy-pasting skill folders between repos does not scale. Git submodules are rarely the answer people hope they are. Internal prompts, references, templates, and checklists drift across repos until nobody is quite sure which version is the real one.
That is the problem npm-skills is solving.
It lets npm packages ship AI skills as normal package contents, version them with package.json, distribute them through ordinary registries, and extract them into the workspace where they are actually used.
In short: your AI skills start behaving more like code.
Why this matters
There is already strong momentum around filesystem-based AI conventions:
-
SKILL.md-based skill folders -
AGENTS.md-style repositories - ecosystems like
skills.sh
These conventions are powerful because they stay simple. A skill is just a directory. If it contains SKILL.md, it is a skill root. Support files live beside it. No database. No opaque platform.
But teams still need a clean answer to practical questions:
- How do we version skills?
- How do we share them between projects?
- How do we keep private skills inside normal engineering workflows?
- How do we pull only the skills we want into a repo-local
.agents/skillsdirectory?
npm-skills takes the conventions people already like and gives them a distribution model that fits naturally into the JavaScript ecosystem.
The core idea
Package authors can publish skills inside an npm package, usually under skills/.
Consumers can then run one command:
npm-skills extract
That command scans installed packages, finds directories containing SKILL.md, and copies them into the local project, usually under:
.agents/skills/
So instead of manually copying prompts and references around, teams can install a package and extract the skills that came with it.
What stands out
1. Discovery is predictable
Skill discovery stays intentionally boring:
- scan under a configured source folder
- treat any directory containing
SKILL.mdas a skill root - copy that directory recursively as-is
That is exactly the sort of rule you want in tooling like this. It is easy to explain, easy to debug, and easy to trust.
2. It fits existing npm workflows
Skills move through tools teams already use:
package.json- npm versions
- private registries
- monorepos
- install hooks
That means AI skills can travel with the codebases and release processes that already exist in your team.
3. It is conservative about overwrites
This part matters.
npm-skills tries to keep extracted content in sync without treating the whole output directory as disposable.
If an extracted skill destination already exists, it does not silently replace it. In interactive mode it can ask, in non-interactive mode it can skip and warn, and if you want a full replacement you opt into that with --override.
At the same time, full syncs can clean up stale folders left behind by earlier package extractions. That is the useful part: if a package stops shipping a skill, you do not want old extracted leftovers hanging around forever.
The important nuance is that this cleanup is scoped to extracted package content, not unrelated folders in the output directory. So your own local skills can still live alongside extracted ones without being treated as throwaway sync artifacts, but it's better to keep your extracted skills under .gitignore to avoid confusion.
4. It keeps authored and extracted skills easy to separate
Recommended pattern for dealing with local authored skills and extracted ones:
.agents/
skills/
my-local-skill/
SKILL.md
extracted/
.gitignore // Ignore the whole extracted folder
shared-skill/
Now in your package.json file just add:
{
"npmSkills": {
"consume": {
"output": ".agents/skills/extracted"
}
}
}
That gives imported skills their own lane and keeps local skills easier to curate.
Quick start
Install it:
npm install npm-skills
Extract skills from dependencies:
npm-skills extract
Or add a script:
{
"scripts": {
"skills:extract": "npm-skills extract"
}
}
If you want extraction to happen after installs:
{
"scripts": {
"postinstall": "npm-skills extract --skip-production --override"
}
}
That --skip-production will not trigger extraction when Node, Deno or Bun's env mode is production
A concrete example of the refs API
One of the more interesting parts of npm-skills is the refs workflow. This is for package authors who want to keep canonical docs in one place, but still expose them inside published skills.
Imagine your repo looks like this:
readmes/
release-process.md
oncall-guide.md
.agents/
skills/
runner/
release-notes/
SKILL.md
references/
During development, you may want release-notes to reference the shared docs from readmes/ instead of duplicating them.
Your package.json can define:
{
"scripts": {
"prepack": "npm-skills refs materialize",
"postpack": "npm-skills refs restore"
},
"npmSkills": {
"publish": {
"source": ".agents/skills",
"refs": [
{
"source": "readmes",
"destination": "skills/runner/release-notes/references/readmes"
}
]
}
}
}
Here is what that means:
- while developing,
npm-skills refs restoremakesskills/runner/release-notes/references/readmespoint back to the realreadmes/folder - right before packing or publishing,
npm-skills refs materializereplaces that reference with copied files - after packing,
npm-skills refs restoreputs the symlink-style setup back
Programmatically, the same flow looks like this:
import { syncSkillPublishRefs } from "npm-skills";
await syncSkillPublishRefs({
cwd: process.cwd(),
mode: "materialize",
});
// publish or pack here
await syncSkillPublishRefs({
cwd: process.cwd(),
mode: "restore",
});
That is a very practical pattern for repos that want one canonical docs source during development, but real files inside the published package tarball.
It is not just an extraction tool
npm-skills also supports authoring:
-
npm-skills new <skill-name>scaffolds a new skill -
npm-skills refs materializeprepares publishable reference files -
npm-skills refs restorerestores the development setup after packing
So the project is not only about consuming skills. It is also about making the authoring and publishing side more maintainable.
Who this is for
This feels especially useful for:
- platform teams sharing AI workflows across many repos
- companies maintaining internal agent or prompt libraries
- monorepos that want AI guidance close to specific packages
- open source packages that want to ship agent-friendly instructions beside their tooling
If your team already thinks in terms of reusable AI playbooks, packaging them as npm-distributed skills is a very natural next step.
What I like most about the approach
The best part of npm-skills is that it does not try to force a hosted platform or a special database into the workflow.
It leans on the boring, durable parts of the stack:
- directories
- package versions
- explicit config
- predictable copying
- local extraction
That makes it easier to adopt and easier to audit. Sometimes the best tooling is the tooling that makes a new workflow feel unsurprising.
npm-skills looks very much like that kind of tool.
Final thoughts
There is a real opportunity right now around standardizing how teams write, share, and maintain AI skills. But for that to work, skills need a dependable distribution story.
npm-skills is a strong answer to that problem.
It gives package authors a convention for publishing skills, and gives consuming teams a clean way to extract those skills into the projects that need them. No magic. Just skill folders, npm packages, and a CLI that does the obvious thing well.
If you're already working with SKILL.md and AGENTS.md conventions, this is worth a serious look.
Docs: https://npm-skills.com
Top comments (0)