Welcome

What skl is, a 60-second quick start, and how to install the CLI.

An Agent Skill is a folder of instructions (a SKILL.md file) that teaches an AI coding agent — Claude Code, Copilot, Cursor, Gemini, Junie, Kiro, plus every agent on the shared .agents/skills/ standard (Codex, Zed, Goose, Amp, OpenCode, Roo, …) — how to do a specific task, like reviewing a diff or writing a changelog.

skl manages them. You save a skill once, install it into any of those agents, and a checked-in skl.json file lets you rebuild the exact same set of skills on another machine with one command.

Quick start

Get a skill into your agent in under a minute — no account needed for public skills:

# 1 — install the CLI (macOS / Linux)
curl -fsSL https://useskl.com/install.sh | sh

# 2 — add a skill to your project
skl install alice/test-writer

The first install in a project asks which agents you use (the popular agents — Claude Code, Codex, Cursor, Gemini, Copilot — are always listed, anything else it detects is added, and Claude Code is pre-checked) — pick them and you're done. alice/test-writer is now copied into .claude/skills/ (and every other agent you picked) and recorded in a skl.json you can commit. Open your coding agent and the skill is there.

Prefer Homebrew or npm? See Install the CLI just below. Ready to save your own skill? See Saving & publishing.

Install the CLI

skl is a single command named skl, for macOS and Linux (arm64 and x64). Pick any one channel below — they all install the same skl.

curl (quickest):

curl -fsSL https://useskl.com/install.sh | sh

Homebrew:

brew install loopdoop/tap/skl

npm:

npm install -g useskl

The npm package is named useskl, but the command it installs is skl — use skl everywhere.

Direct download / Debian: grab a binary or .deb from the releases page.

Check it worked with skl --version. Update any time with skl upgrade. (Windows and Alpine/musl Linux aren't supported yet.)

What's next

The whole loop is install → rebuild → save. You've done install; here's where the rest lives:

  • Installing skills — add and manage skills, rebuild on another machine with skl install, pin or float versions, and the skl.json file.
  • Saving & publishing — sign in, save your own skills (private), set versions and visibility, and publish publicly.
  • Reference — every command, the seven agent targets, the SKILL.md format, and troubleshooting.

Commit skl.json to your repo and teammates rebuild the same skills with one skl install.

Installing skills

Add and rebuild skills, pin or float versions, and manage your skl.json.

Two commands install skills — and neither needs an account when the skills are public. Log in only to install a private skill.

skl install <skill> — add one skill

skl install <name> installs a skill into the current project and records it in skl.json. It downloads the skill once and copies it into every agent you target. If there's no skl.json yet, it creates one for you (asking which agents to target). (skl add is the same command — install <name> routes to it.)

$ skl install alice/test-writer
✓ Installed alice/test-writer at latest (version 2)

  alice/test-writer@2 → ./.claude/skills/test-writer/

↻ Restart your code agent or reload skills to take effect

skl install — rebuild everything

skl install re-installs all skills from skl.json — the command to run on a fresh checkout or a new machine. Pinned entries re-land the exact recorded version; floating entries re-resolve to the newest version, and GitHub URL entries are re-fetched from GitHub (see Pin or float a version below). A skill that is already installed and unchanged is left as-is (no re-download); a skill you've edited locally is protected — it's skipped with a warning rather than overwritten (re-run with --force to overwrite).

$ skl install
Rebuilding 2 skills from ./skl.json …

  ✓ alice/test-writer@2 → ./.claude/skills/test-writer/
  ✓ bob/changelog@1 → ./.claude/skills/changelog/  (up to date)

↻ Restart your code agent or reload skills to take effect

✓ Rebuilt ./skl.json — 1 installed, 1 up to date.

Coming from npm? npm install <pkg> adds one package; npm install rebuilds everything. skl works the same way: skl install alice/test-writer adds a single skill (it just routes to skl add), while bare skl install rebuilds the whole project. See the npm cheat sheet.

Install straight from a GitHub URL

Found a skill on GitHub? Install it without cloning — just give skl install the repo URL:

skl install https://github.com/owner/repo
skl install https://github.com/owner/repo/tree/main/skills/my-skill

skl finds the SKILL.md in the repo (or the subfolder you point at) and asks what to do:

$ skl install https://github.com/owner/repo
? Save https://github.com/owner/repo to your registry as a private skill? (No = install locally only) › No
✓ Installed my-skill from GitHub (version 1.0)

  my-skill@1.0 → ./.claude/skills/my-skill/

Tracked in skl.json as https://github.com/owner/repo

↻ Restart your code agent or reload skills to take effect

You get two choices:

  • Install locally only (the default) — skl copies the skill straight from GitHub into your agents and records the URL in skl.json. No account needed. On a skl install rebuild, skl re-fetches it from GitHub each time.
  • Save to your registry as a private skill — skl imports the repo to useskl.com as a private skill (under your namespace), then installs it like any other saved skill. This needs an account with a verified email. Use it to keep your own copy you can version and share.

Skip the prompt with a flag:

skl install https://github.com/owner/repo --local     # local only, record the URL
skl install https://github.com/owner/repo --private   # save to your registry, then install

In a script or CI (no terminal to prompt), skl install <url> defaults to local. If you choose to save but aren't logged in, skl tells you to run skl login first (or install locally without an account).

If you choose to save but already have a skill with that name in your registry, skl won't make you rename it — it asks what you actually meant:

You already own you/my-skill in your registry. What would you like to do?
> Install your registry skill (you/my-skill)
  Download this skill from GitHub directly (local only, not saved)

Pick the first to install the copy you already have, or the second to grab this GitHub version locally.

A locally-installed GitHub skill is untracked — it has no saved version, so skl always re-fetches it on rebuild and can't tell if you've edited it locally. If you want versioning, drift detection, and sharing, use --private (or save it with skl save).

If the URL points at a repo with more than one skill, skl asks you to be more specific — point the URL at the skill's folder with …/tree/<branch>/<path-to-the-skill>.

Install for yourself, everywhere (-g)

Everything above installs into one project. To make a skill available in every project, install it globally with -g/--global — it lands in the agent's personal skills folder under your home directory (e.g. ~/.claude/skills/) instead of the project:

$ skl install alice/test-writer -g
✓ Installed alice/test-writer globally (version 2)

  alice/test-writer@2 → ~/.claude/skills/test-writer/

Global installs aren't tracked in skl.json — delete the folder to remove.
↻ Restart your code agent or reload skills to take effect
  • skl asks which agents to target (same picker as skl init: the popular agents always listed plus any it detects on your machine, claude pre-checked); pass --targets claude,cursor to skip the prompt. In a script (no terminal), it defaults to claude.
  • Global installs are untracked — no skl.json is read or written, so there's nothing to rebuild (skl install -g with no name is an error) and nothing to commit. To remove a global skill, delete its folder.
  • Installing a GitHub URL with -g isn't supported yet — install it into a project instead, or save it to your registry first.

Re-installing is safe

Running skl install again (single skill or the whole project) does the least work needed:

  • Already up to date — if the exact version is already installed and unchanged, it's a no-op: skl reports already up to date and doesn't re-download or re-copy anything.
  • Locally edited — if you've hand-edited a skill's files after installing, skl won't silently overwrite them. A single skl install <name> asks what to do (abort and save your edits first, or discard them); a project-wide skl install skips that skill with a warning and leaves your edits in place. Re-run with --force (-f) to overwrite.
✓ skl/skl is already up to date (version 2)

  skl/skl@2 → ./.claude/skills/skl/

Already installed — nothing to do (use --force to reinstall).

Public vs. private skills

Public skills install with no login. Sharing a project is as simple as committing skl.json — anyone can skl install it.

Private skills need a login, and you must be the owner (or someone it's shared with):

  • skl install <skill> of a private skill while logged out tells you to log in:

    ✗ Can't install "acme/secret" — it's private or doesn't exist.
      If it's private, run `skl login` to install skills you have access to.
    
  • skl install on a mix of public and private skills while logged out installs the public ones, skips the private ones with a warning, and still succeeds:

    Rebuilding 2 skills from ./skl.json …
    
      ✓ alice/test-writer@2 → ./.claude/skills/test-writer/
      ⚠ acme/secret@1 — private, skipped (run `skl login`)
    
    ↻ Restart your code agent or reload skills to take effect
    
    ✓ Rebuilt ./skl.json — 1 installed.
    ⚠ 1 skill requires permission — run `skl login` to install private skills you have access to.
    

    Log in and re-run skl install to pick up the private ones.

Pin or float a version

Each skill in skl.json is either pinned to an exact version or floating on the latest:

  • Pin = always install this exact version (e.g. 2). Every machine gets identical results. skl install alice/test-writer@2 pins 2, and --lock-version (-l) pins whatever the current version resolves to.
  • Float = always grab the newest version. Handy, but it can differ between machines and over time. A bare skl install alice/test-writer floats — this is the default.

A bare skl install alice/test-writer floats to latest (no prompt); add --lock-version/-l to pin instead. To move a pinned skill to a newer version, skl install it again at the new version (e.g. @3).

The skl.json file

skl.json lives in your project root and records what the project installs — commit it so teammates and other machines rebuild the same set. It looks like this:

{
  "schemaVersion": 1,
  "targets": ["claude", "agents"],
  "skills": [
    "alice/test-writer@2",
    "bob/changelog",
    "https://github.com/owner/repo"
  ]
}
  • targets — which agents every skill is copied into (see Reference → Targets).
  • skills — each entry is either a "username/skill-name" (with an optional @version to pin; no @version floats to the latest) or a GitHub URL (added by skl install <url> --local, re-fetched from GitHub on every rebuild).

Other commands

  • skl list — list the skills installed in this project.

  • skl uninstall <name> — remove a skill (its files and its skl.json entry). skl remove is an alias. If you hand-edited the installed copy and haven't saved the change, uninstall won't silently delete it — it warns and asks first (or stops in a script); pass --force/-f to delete anyway.

  • skl scan (alias skl outdated) — check the project's skills for drift (edited-since-save, updates available, missing or extra folders). Read-only; it changes nothing. It's broader than npm outdated — it reports local edits and missing folders too, not just newer versions.

Saving & publishing

Sign in, save a skill to your own registry, set version numbers and visibility, publish publicly, and delete a skill.

Saving puts your own skill into your registry on useskl.com — private by default, yours to install anywhere. Publishing is the same thing made public so others can find it. Both need an account; installing public skills does not.

Sign in

  1. Create an account at useskl.com: pick a username (it becomes the prefix for everything you save — so acme saves acme/code-review) and a password.

  2. Verify your email by clicking the link in the sign-up email. This is required before you can save or publish.

  3. Log in:

    $ skl login acme
    ? Password for "acme": ▪▪▪▪▪▪▪▪▪▪
    ✓ Logged in as acme → https://useskl.com
    • `skl publish` will use this server ("default").
    

skl login signs you in and sets this machine up automatically — there's nothing to copy or paste. (The password is masked as you type.) Run skl logout to sign out of this machine.

Signed up with GitHub or Google? Your account has no password, so log in with a pairing code instead: on useskl.com go to Settings → Devices → Link a new device to get a single-use code (valid 10 minutes), then run:

skl login --code

and paste the code when prompted. A bare skl login (no username) also works — it asks which way you want to log in (password or pairing code).

Save a skill

A skill is a folder with a SKILL.md at its root. The top section (the part between the --- lines) sets a name and a version:

$ cat my-skill/SKILL.md
---
name: code-review
description: Reviews a diff for correctness and style.
metadata:
  version: "1"
---
# Code Review
...

$ skl save ./my-skill
✓ Yay! Skill acme/code-review@1 is published successfully.  (8 files, 3.4 KB)  [private]

The saved name comes from name: in SKILL.md — with username acme, it lands as acme/code-review. A saved skill is private: yours alone until you choose to publish it.

Preview without uploading with --dry-run (no account needed):

$ skl save ./my-skill --dry-run
Dry run — nothing uploaded.
  Would publish:  code-review@1
  Visibility:     private
  Full name (your-username/code-review) is set from your token at publish.
  Files: 8        Size: 3.4 KB
  Digest: sha256:9f2c…
  Tokens: 812 (cl100k)
  (.skl tracking file is generated on a real publish, not a dry run)
  ✓ frontmatter valid    ✓ no symlinks    ✓ name ok

Version numbers

Version numbers are yours to choose. The simplest convention is to start at 1 and bump by one each release — 1, 2, 3, 4. If a skill already uses semantic versions like 0.1.2, keep that style. The newest version you save is the "latest" that floating installs pick up.

Always quote the version (version: "1", version: "1.10"). Unquoted, 1.10 is read as the number 1.1.

Versions can't be changed once saved. Re-saving the same version with different content fails — bump the version instead:

✗ acme/code-review@1 already exists — versions are immutable.
  Bump metadata.version in SKILL.md and publish again.

skl never bumps the version silently — in a terminal it offers the next number ("Bump metadata.version to "2" and publish?") and only writes it when you say yes; in a script it just fails with the error above. Likewise, if your SKILL.md has no metadata.version yet, save/publish offers to add "1" for you. Re-saving a version whose content hasn't changed is a friendly no-op, not an error.

Public or private

A skill you skl save is private — visible only to you, hidden from others' catalogs, and installable only by you or people you share it with.

To share a skill with the world, publish it public — either flip the visibility on the skill's page on useskl.com, or pass the explicit flag:

$ skl publish ./my-skill --public
✓ Yay! Skill acme/code-review@1 is published successfully.  (8 files, 3.4 KB)

How the visibility of a skill is decided:

  • First publish of a brand-new skill: skl save makes it private; skl publish with no flag makes it public.
  • Re-publishing an existing skill: skl publish with no flag keeps the current visibility — so publishing a new version of a private skill does not make it public. To change visibility from the CLI, pass --public or --private explicitly (an explicit flag always wins).
  • skl save is always explicitly private — re-saving a skill you've since made public flips it back to private. Once a skill is public, publish new versions with skl publish.
  • You can also change visibility any time from the skill's page on useskl.com.

Delete a skill

Delete a skill from its page on useskl.com → ManageDanger zone. As a guard, you retype the full name to confirm.

  • The skill becomes unavailable to everyone, including you — it leaves the catalog and can no longer be installed. Copies already on machines keep working.
  • The name is freed; you can save a new skill under it later.
  • There is no undo — treat deletion as permanent. To just hide a public skill, make it private instead.

Reference

Command reference, the seven agent targets, the SKILL.md format, and troubleshooting.

This page covers the everyday surface. Every command documents its full flag set — run skl <command> --help.

Commands

CommandWhat it doesAliases
skl install <name|github-url>Install one skill (from useskl.com or a GitHub URL) and record iti, in, a, add
skl installRe-install all skills from skl.jsoni, in, a, add
skl uninstall <name>Remove a skill (files + skl.json entry); guards unsaved local edits — --force/-f to overrideremove, rm, un, r
skl listList the skills in this projectls, la, ll
skl scanCheck the project's skills for drift (read-only)outdated
skl info <name>Show a skill's detailsview, show
skl save <folder>Save a skill folder to your registry as private (the privacy-first default)
skl publish <folder>Publish a skill folder to useskl.com — public on first publish; re-publish keeps the current visibility (--public/--private to change it)pub
skl login [username]Sign in with your password, or --code with a website pairing code (GitHub/Google accounts)adduser, add-user
skl logoutSign out on this machine
skl configManage backend serversc
skl initCreate a skl.json (choose which agents to target)
skl upgradeUpdate the skl CLI itselfup

The aliases mirror npm's own shortcuts so npm habits carry over — see the npm cheat sheet. install is the one install verb (add/a are aliases of it): skl install <name> adds one skill (like npm install <pkg>) while bare skl install rebuilds everything from skl.json (like npm ci) — and so skl add foo/bar installs one while bare skl add rebuilds. There is no skl updateupgrade alias, because skl upgrade updates the CLI itself, not your skills.

Common flags: --help on any command, --json for machine-readable output, --quiet, --verbose. skl install --prune deletes skill folders left behind by an agent you no longer target.

Install flags (skl install <name> / skl add <name>, also passed through by skl install):

  • --lock-version / -l — pin the resolved version in skl.json instead of floating to latest (the default). Equivalent to writing @<version> yourself.
  • --latest — explicitly float to latest (the default; kept for clarity in scripts).
  • --force / -f — overwrite a locally-edited skill folder instead of skipping/prompting.
  • --private / --localonly for a GitHub URL. --private saves the repo to your registry as a private skill, then installs it; --local installs it locally only and records the URL. Without a flag, skl prompts (and defaults to local in a script). See Installing → Install straight from a GitHub URL.
  • -g / --global — install into the agents' personal skills folders under your home directory (e.g. ~/.claude/skills/) instead of the project. Untracked (no skl.json). See Installing → Install for yourself, everywhere.
  • --targets <ids> — pick the agent targets non-interactively (comma-separated target ids) when skl would otherwise prompt: bootstrapping a new skl.json, or a -g install.

A re-install does the least work: a skill already installed at the target version and unchanged is reported up to date and not re-downloaded; a skill you've edited locally is protected (skipped/prompted, not silently overwritten) unless you pass --force.

Coming from npm

If you know npm, skl's verbs map almost one-to-one:

You'd type in npmIn sklNotes
npm installskl installRebuild everything from the manifest (npm ci equivalent).
npm install <pkg>skl install <name> or skl add <name>Both add one skill; install is canonical, add is an alias.
npm uninstall <pkg>skl uninstall <name>remove is an alias.
npm lsskl list
npm view <pkg>skl info <name>
npm outdatedskl scan (skl outdated)skl's check is broader (drift + missing + updates).
npm publishskl publish <folder>Versions are immutable; bump by hand.
npm loginskl loginMints a device-bound key.
npm configskl configskl config manages backend servers.
npm install -g npm (self-update)skl upgradeNote: not skl update.

skl has no analog for npm run, npm test, npm version, or npx. Forking a skill into your namespace is a website feature (there is no skl fork CLI command).

Targets (the seven canonical targets)

A target is which agent a skill is copied into. Targets are set once per project (in skl.json), and every skill is copied into each one. Each maps to a folder in your project:

TargetFolderAgent
claude.claude/skills/Claude Code (also read by Goose, Amp, OpenCode)
copilot.github/skills/GitHub Copilot
cursor.cursor/skills/Cursor (2.4+)
gemini.gemini/skills/Gemini CLI
junie.junie/skills/JetBrains Junie
kiro.kiro/skills/Kiro (Amazon Q successor)
agents.agents/skills/The cross-agent standard — Codex, Zed, Goose, Amp, OpenCode, Roo, pi, grok

Legacy codex / grok target ids are still accepted as input (in skl.json or --targets) and canonicalize to agents — they are no longer separate canonical targets.

A skill named acme/code-review lands as code-review/ inside each target's folder. Skills are copied, never symlinked, so each agent reads its own copy.

skl init sets a project's targets up front (and re-running it reconfigures them):

The SKILL.md format

A skill folder must contain a SKILL.md at its root. The block between the --- lines (the frontmatter) sets these fields:

---
name: code-review
description: Reviews a diff for correctness and style.
metadata:
  version: "1"
---

# Code Review

Instructions the agent reads…
FieldRequiredNotes
nameyesThe skill's short name; the full name is username/name once saved
descriptionyesOne-line summary shown in catalogs and skl info
metadata.versionyesYour version number. Quote it ("1", "1.10")

The folder may contain any files the skill needs, but no symlinks, and nothing oversized.

Troubleshooting

SymptomCauseFix
Can't install "…" — it's private or doesn't existInstalling a private skill while logged out (public skills need no login)Run skl login — you must own the skill or have it shared with you
… — private, skipped (run skl login) during installA private entry in the manifest, and you're logged outinstall lands the public skills anyway; skl login and re-run to add the private ones
… — modified locally, skipped (use --force …) during installA landed skill folder was edited after install; skl won't silently overwrite itSave your edits, or re-run with --force to discard them and reinstall
Your email address is not verifiedSaving and publishing need a verified emailClick the link in your sign-up email (or re-send it from useskl.com), then try again
… already exists — versions are immutableRe-saving a version with changed content (versions can't change)Bump the version in SKILL.md and try again (in a terminal, skl offers the bump for you)
Incorrect username or passwordWrong sign-in detailsCheck them, or reset your password on useskl.com
No skl.json in this directoryinstall / uninstall / list need a project manifestRun skl init (or skl add) first, or cd to the project root
A skill folder is left behind after dropping a targetinstall never deletes silentlyRun skl install --prune
That location contains more than one skill (GitHub URL)The repo URL points at a folder with several skillsPoint the URL at the skill's folder: …/tree/<branch>/<path-to-the-skill>
No SKILL.md was found at that GitHub locationThe repo (or subfolder) has no SKILL.mdCheck the URL points at a skill folder; add /tree/<branch>/<path> if it's nested
GitHub repository not found (or private)Bad URL, or a private reposkl installs only from public GitHub repos; check the URL
You already own … when saving a GitHub URL (--private)The repo's skill name matches a skill you already haveNot an error to fix — skl asks whether to install your existing skill or fetch this one from GitHub directly. Non-interactively (--json): run skl install <you>/<name>, or re-run with --local

Always quote the version in SKILL.md. Unquoted, 1.10 is read as the number 1.1.