Compose and version skills like code

Tutorial · 8 min read

Most skill collections are folders of Markdown files with no relationship to each other. If typescript-testing and rust-testing both start from the same base testing philosophy, that philosophy is duplicated in both files — and when it changes, you're editing it twice, or three times, or however many skills happen to share it.

Skilnu treats a skill more like a package: it can declare a dependency on another skill, pin a version constraint, and get updated content automatically when that dependency publishes a new version. Here's how to actually use that.

1. Publish the base skill

Write the shared part first — the thing more than one skill will build on. Publish it normally, with a real semantic version:

name: testing-philosophy
description: Shared testing principles: what to test, what not to, naming conventions.
version: 1.0.0

2. Declare a dependency from the composed skill

When you publish the skill that builds on it, add the base skill under Dependencies instead of pasting its content in:

- type: skill
  id: yourhandle/testing-philosophy
  version_constraint: ">=1.0.0"
  optional: false

Skilnu resolves the dependency, checks that you (or whoever loads the composed skill) have access to it, and keeps the reference live — the composed skill always reads the dependency's current content within your version constraint, not a snapshot taken at publish time.

3. Update the base skill

Publish a new version of testing-philosophy — say 1.1.0, adding a section on flaky-test triage. Every skill that depends on it with a compatible constraint (>=1.0.0 matches 1.1.0) picks up the change the next time it's loaded. You edited one file; every dependent updated itself.

If a change is breaking, publish it as a new major version and leave the constraint decision to whoever owns the dependent skill — the same convention you'd use for a package with semantic versioning.

4. Retire old versions without breaking dependents

When a version is no longer the one you want people building on, mark it deprecated. Anything still pinned to it keeps working; anything with a looser constraint moves off it naturally the next time it resolves.

5. Fork instead of copy

Starting from someone else's skill but need to diverge rather than depend on it live? Use Derived from and Lineage mode: fork when you publish. Skilnu records where the fork came from and a changelog summary of what you changed — so the relationship is traceable even after the two skills stop tracking each other's updates.

derived_from: origin-publisher/base-skill@1.4.2
lineage_mode: fork
lineage_changelog: Added stricter validation and examples

Where this matters most

Composition pays off fastest for skills that are really "the same skill, N times" — language-specific variants of one testing or linting philosophy, team-specific overlays on a shared incident runbook, or house style guides that a dozen more specific skills all build on. Anywhere you'd reach for a shared library in code, reach for a dependency here instead of another copy-paste.

Try it with a skill you already have.

Sign up free Browse the catalog