Understanding skillOverrides in Claude Code
What skillOverrides controls, its four visibility states, and why it touches your own skills but not plugin skills
skillOverrides is the block in your Claude Code settings.json that tunes how visible each of your skills is to you, to Claude, and to the / menu. It is not an on/off switch bolted onto skills as an afterthought; it exists to solve a specific cost problem, and understanding that problem explains its four states.
What the setting looks like
The setting is a JSON object mapping a skill name to a visibility state:
"skillOverrides": {
"web-design-expert": "off",
"systematic-debugging": "off",
"typography-expert": "off"
}
The key is the bare skill name — no marketplace, no plugin:skill prefix. That plainness is a deliberate boundary, covered below.
Why visibility is the thing being controlled
Every skill Claude can see costs context. Claude Code loads its name and description so Claude knows the skill exists and when to reach for it. A dozen skills you never use still consume that budget on every turn, and they clutter the / menu you scroll through.
Instead of forcing you to delete a skill, skillOverrides lets you dial its presence down. That is why the value is a visibility level, not a boolean:
"on"— full visibility. Name and description are available to Claude and the skill appears in the/menu. This is the default."name-only"— Claude sees the name but not the description. Cheaper in context; Claude knows the skill exists but loses the description that tells it when to reach for it."user-invocable-only"— hidden from Claude’s automatic selection, but you can still invoke it yourself with/. Use this for skills you want to trigger deliberately, never automatically."off"— fully hidden: from Claude, from the/menu, from Remote Control clients, and from Agent SDK callers. Try to invoke an"off"skill by name and Claude Code returns askillOverrideserror instead of running it.
A skill you never list counts as "on". As with plugins, absent means default, and here the default is full visibility.
The boundary: your skills, not plugin skills
This is the rule people trip over most. skillOverrides only governs plain skills — the ones living in ~/.claude/skills/ (your personal skills) or a project’s .claude/skills/. It does not extend to skills that come from a plugin.
The entries in the example above work because they are personal skills. Want to quiet a skill a plugin provides? skillOverrides ignores it — you manage plugin skills through the plugin itself, via /plugin.
The two settings therefore divide cleanly:
enabledPluginsdecides which plugins, and by extension which plugin skills, exist at all.skillOverridestunes the visibility of the plain skills you author or install directly.
They do not overlap, and they do not fight. One consequence follows directly: if you disable a plugin, all of its skills disappear, and skillOverrides cannot bring any of them back.
Where the setting is written
Like the rest of settings.json, skillOverrides obeys the four-scope layering: managed > local > project > user, and a stronger scope wins. Worth knowing: when you toggle a skill’s visibility from the interactive /skills menu, Claude Code writes the change to .claude/settings.local.json, the gitignored per-machine layer. Your menu tweaks stay personal by default.
Changes take effect immediately in the current session.
Takeaways and action points
skillOverridesmaps a bare skill name to"on","name-only","user-invocable-only", or"off".- It controls visibility and context cost, not merely existence — that is why there are four states, not two.
- It applies only to plain skills in
~/.claude/skills/or.claude/skills/; plugin skills are out of its reach. - An unlisted skill defaults to
"on"; the/skillsmenu writes your changes to.claude/settings.local.json.
Dear fellow developer, thank you for reading this article about how skillOverrides works in Claude Code. Until next time, TheJavaGuy salutes you 👋!