Building a Custom Claude Code Output Style From Scratch: Frontmatter Fields and the Three Folders It Checks

Close-up photograph of a laptop keyboard
Close-up photograph of a laptop keyboard
Photo: Carissa Rogers, licensed CC BY 2.0, via Wikimedia Commons.

A custom Claude Code output style is a Markdown file with YAML frontmatter that you save in one of three folders, and it changes how Claude talks and works for an entire session once you switch to it with /output-style. It is different from CLAUDE.md, which tells Claude facts about your project, and different from a hook, which runs no matter what Claude decides. This walkthrough builds one from an empty file to a working style, then covers the two mistakes that most often make a new style appear to do nothing.

What an output style changes, and what it leaves alone

An output style is an instruction set, not a guarantee. Claude Code sends the active style’s text to Claude with every request in that session, and Claude follows it the way it follows any other instruction — which means a style can shape tone, format, and role, but it cannot force something to happen on every single action without exception. Anthropic’s own documentation on output styles is explicit about this distinction, and it is the single most useful thing to internalize before writing one: if you want Claude to sound terser or explain its reasoning, a style is the right tool; if you want a command blocked every time regardless of what Claude decides, you want a PreToolUse hook instead, the same mechanism covered in our walkthrough of a SessionStart hook.

Four built-in styles ship alongside the Default style: Proactive, which starts implementing immediately and only checks in before anything destructive; Concise, which strips the lead-in and the closing recap from every response; Explanatory, which adds short “Insight” blocks explaining why Claude made a choice; and Learning, which does the same but also leaves a marked TODO(human) section for you to fill in yourself. None of them touch what Claude knows about your codebase — that is still CLAUDE.md’s job — and none of them replace a skill, which only loads when a task actually calls for it instead of shaping every response in the session.

The three folders Claude Code checks, in the order that matters

Claude Code looks for output style files in three places, and which one wins depends on how specific it is. A user-level style lives in ~/.claude/output-styles and applies to every project you open. A project-level style lives in .claude/output-styles inside the repository, and a managed-policy style lives in the same relative path inside whatever directory your organization designates for managed settings. The file name becomes the style’s name unless you set name in its frontmatter.

LevelFile locationScope
User~/.claude/output-stylesEvery project on your machine
Project.claude/output-stylesOne repository (loads from every matching folder between the working directory and the repo root)
Managed policy.claude/output-styles under the managed settings directorySet by your organization

One detail in the official docs is easy to miss: project output styles load from every .claude/output-styles/ folder between your current working directory and the repository root, not just the one at the top. If two of those nested folders define a style with the same name, Claude Code uses whichever one sits closest to the working directory you launched from. That is a reasonable default, but it means a style you thought you deleted at the repo root can keep winning over a newer one you just added two folders down, and vice versa — worth checking both locations before assuming your edit was ignored.

Frontmatter fields, and what happens if you get one wrong

Every field in an output style’s frontmatter is optional, which is unusual for a configuration format and worth knowing before you go hunting for a required field that does not exist. All four fields use lowercase words separated by hyphens, and a misspelled field name is silently ignored rather than rejected.

FieldRequiredWhat it does
nameNoName shown in the /config picker; defaults to the file name
descriptionNoDescription shown next to the name in the picker
keep-coding-instructionsNoSet true to keep Claude Code’s built-in software-engineering instructions alongside your style; defaults to false
force-for-pluginNoPlugin styles only — applies the style automatically whenever the plugin is enabled, overriding the user’s own outputStyle setting

keep-coding-instructions is the field that causes the most confusion, because leaving it out does not mean “keep everything and add my instructions on top.” A custom style without it set to true replaces Claude Code’s built-in software-engineering instructions entirely — how it scopes changes, how it comments code, how it verifies its own work — and runs on your instructions alone. That is the right choice if you are turning Claude into something other than a coding assistant, such as a writing partner or a data analyst. It is the wrong choice if you still want Claude to code the way Claude Code normally codes, just with a different tone layered on, in which case you need that field set explicitly.

A complete style you can copy, explained line by line

The style below leads every explanation with a Mermaid diagram before any prose, which is a genuinely useful habit when you are exploring a codebase you did not write. Save it as .claude/output-styles/diagrams-first.md for one project, or ~/.claude/output-styles/diagrams-first.md to use it everywhere.

---
name: Diagrams first
description: Lead every explanation with a diagram
keep-coding-instructions: true
---

When explaining code, architecture, or data flow, start with a Mermaid diagram showing the structure, then explain in prose.

## Diagram conventions
Use `flowchart TD` for control flow and `sequenceDiagram` for request paths. Keep diagrams under 15 nodes.

  • The frontmatter block exists only for the picker UI and the engine flags — name and description never reach Claude as instructions, so renaming them doesn’t change behavior, only what you see in /config.
  • keep-coding-instructions: true is set here on purpose: the style is meant to change how Claude explains things, not to turn Claude Code into a general chat assistant that forgets how to scope a diff or run tests.
  • The one-sentence instruction (“start with a Mermaid diagram… then explain in prose”) is deliberately short. Output style instructions are sent with every request in the session, so a long style costs more input tokens on every single turn — prompt caching reduces this after the first request, but it never becomes free.
  • The “Diagram conventions” section narrows the instruction before Claude can improvise a 40-node diagram that takes longer to read than the code it describes. Naming the two diagram types you actually want (flowchart TD, sequenceDiagram) stops Claude from reaching for whatever Mermaid syntax it half-remembers.

Switching to it, and the two things that still trip people up

Run /output-style diagrams-first in the terminal, or run /output-style with no argument to see every style you can pick, including your custom ones, with the current one marked. Two behaviors catch people off guard immediately afterward.

  • The terminal doesn’t notice a file you just created or edited. Claude Code reads style files when it starts. If you add or change a style file mid-session, restart Claude Code before it shows up in the picker. The VS Code extension doesn’t have this limitation for the version of the style file’s content once the style is selected, but a brand-new file still needs a reload of the style list.
  • Built-in style names are case-sensitive in the settings file, not in the command. If you set "outputStyle": "explanatory" directly in .claude/settings.local.json instead of running /output-style explanatory, you silently get the Default style, because the field expects Explanatory with a capital E. The slash command itself ignores case, which is exactly why the bug only shows up for people who skip the command and hand-edit the settings file.

Both the command and the two menus write your choice to .claude/settings.local.json at the project level by default. To make a style your default everywhere, set outputStyle in ~/.claude/settings.json instead — just remember a project’s own settings file still takes precedence over that global default when the two disagree.

FAQ

Does switching output styles mid-session cost extra tokens right away?
Yes, on the next message. The new style’s instructions go out with your very next request, and because that request’s system prompt differs from the one Claude Code had cached, that first turn after a switch loses whatever caching benefit the previous style’s prompt had built up.

Can a plugin force everyone onto one output style?
Yes, with force-for-plugin: true in the style’s frontmatter, and it overrides whatever the user already set in their own outputStyle field. If two enabled plugins both set this, Claude Code uses whichever one loaded first.

Do custom styles work from the mobile app or Remote Control?
No. Remote Control and the mobile app can list and select only the four built-in styles, not a custom one you wrote yourself — useful to know before you build a workflow that assumes your diagrams-first style is available everywhere you can reach Claude Code.

For the broader menu of what to reach for instead of a style — a hook when something has to happen without exception, a subagent when a task needs its own tools and context, CLAUDE.md for what Claude should simply know — the MCP permissions review and the Gitleaks pre-commit hook posts cover two of the adjacent mechanisms in more depth.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top