knack
← all posts

Claude Skills vs System Prompt: Where Reusable Guidance Should Actually Live

A skill loads on demand through progressive disclosure; a system prompt is always in context. How skills compare to system prompts, custom instructions, Projects, and Cursor rules, and when to reach for each.

You wrote a 600-word block of coding conventions and pasted it into your system prompt. It works fine. The catch is that it rides along on every single request, including the ones where you just ask Claude to rename a variable. That tax is the whole argument for Claude skills vs system prompt placement, and I think most people get the call wrong because the two options look interchangeable from the outside. They aren't.

A skill and a system prompt both hold instructions. What separates them is when those instructions actually reach the model.

Claude skills vs system prompt: the mechanical difference that decides everything

A system prompt is always loaded. Whatever you put there sits in context for every turn of every conversation, relevant or not. Custom instructions behave the same way: in Claude Code, the CLAUDE.md files at and above your working directory are read at session start and delivered to Claude immediately after the system prompt, per Anthropic's Claude Code docs. Persistent, predictable, and paid for on every request.

A skill loads in stages. Anthropic calls this progressive disclosure, and the Agent Skills overview spells out three levels. At startup, only the skill's name and description load into the system prompt, roughly 100 tokens. That metadata is just enough for Claude to know the skill exists and when it might apply. The body of SKILL.md, under 5k tokens of actual instructions, loads only when your request matches the description. Bundled files and scripts load after that, as needed, with effectively no limit, because they sit on the filesystem until something reads them.

So skills vs system prompt comes down to this. The system prompt pays for its guidance on every request, while a skill only pays when the work in front of you calls for it.

That changes how much you can install. You can have fifty skills sitting in a project and carry only fifty short descriptions in context, then load the one that matters for whatever you happen to be doing. Try fitting fifty domains of guidance into a system prompt and you end up with a 12,000-token preamble that degrades every answer and pushes your real context out the window.

How the other containers compare

System prompts and CLAUDE.md aren't your only always-on options, and a skill isn't your only on-demand one either. Four containers, two loading behaviors.

Container When it loads Good for
System prompt Every request, always Identity and rules that apply to literally everything
Custom instructions (CLAUDE.md) Session start, always present Project facts Claude needs on every turn here
Claude Projects Every chat in that project Reference shared across one initiative
Cursor rules (Always) Every chat session Editor-wide conventions you never want skipped
Cursor rules (Agent Requested) When the agent judges relevance Domain rules for some tasks
Claude skill When the request matches its description Reusable procedures with a trigger

Claude skills vs custom instructions is the cleanest contrast. Custom instructions answer "what does Claude always need to know in this repo," and per the docs above they are not re-read or summarized, they just sit there after the system prompt. A skill answers a different question: what procedure should fire when a specific kind of task shows up. So put your stack, your conventions, and your no-go list in CLAUDE.md, and put your release-notes workflow in a skill.

Claude skills vs projects splits along scope and freshness. A Claude Project makes everything in its knowledge base available across all chats in that project, always loaded within that workspace, which suits a fixed body of reference like a product spec, a brand guide, or a research corpus. A skill is portable and on-demand, and it travels across surfaces, since the same SKILL.md folder runs in Claude Code, the Claude apps, and the API. Think of a Project as a place you work, and a skill as a capability you carry into whatever room you walk into.

Claude skills vs Cursor rules is the interesting one, because Cursor already split the difference inside its own product. Cursor's rules docs define four types. An "Always" rule applies to every chat session, the same always-on cost as a system prompt. An "Apply Intelligently" (Agent Requested) rule includes its content only when the agent decides it is relevant based on the rule's description. That second type runs on the same idea as a skill's progressive disclosure: a short description in context, the full body pulled in on demand. Where they part ways is reach. Cursor rules live in Cursor, and that's it. A skill follows the Anthropic Skills standard, so the container you build once runs in more than one tool.

My default, and when to break it

Default to a skill for anything procedural and reusable.

If the guidance describes a task with a name (write the changelog, audit accessibility, format the SQL, draft the support reply), it has a trigger, and a trigger is exactly what progressive disclosure keys off. Skills keep that knowledge out of context until the moment it earns its place, which means you can accumulate dozens of them without watching quality slide on unrelated work. That is the whole point of the architecture, and it's why I reach for a skill first.

Reach for the system prompt or CLAUDE.md instead when the guidance is identity rather than procedure. Something like "you are reviewing a Rust codebase, never suggest unsafe blocks, prefer iterators" applies to every turn, so paying for it every turn is correct. Forcing always-true rules through a skill just adds a load step for no reason. Reach for a Project when the thing is a body of reference shared across many chats and you want it present without a trigger, and for an Always Cursor rule when the convention is editor-wide and skipping it would cost more than the tokens it burns.

One caution before you commit. A skill only fires if Claude matches the request to its description, so a vague description gives you a skill that silently never loads. Write the description like a trigger: what it does and when to use it. The skill authoring best practices treat this as the part of the file that pays off most, and that matches what I've seen in practice. A great skill body behind a weak description is just dead weight.

For the primitive-by-primitive breakdown of skills against subagents, slash commands, and plugins, see skills vs subagents vs slash commands vs plugins. For when a skill should be an MCP server instead, see SKILL.md vs MCP server. And if you want the plain definition first, what is a Claude skill.

Once you've decided a skill is the right container, the writing is the real work: a description that triggers reliably, a body that stays under budget, the right files split out. Knack handles that from a short interview and hands you a valid SKILL.md folder, so you can test the decision instead of fighting YAML. The mechanics above tell you whether to build one. If the answer is yes, Knack gets you to a shippable skill without hand-authoring the frontmatter.