From claude-rudder
Canonical reference for where Claude Code plugins should persist user data. Defines the CLAUDE_USER_DATA convention, resolution order, and forbidden locations. Use this skill whenever designing or updating a plugin's onboarding flow, preferences storage, or persistent-state handling — and whenever Claude is tempted to write under ~/.claude/.
npx claudepluginhub danielrosehill/claude-code-plugins --plugin claude-rudderThis skill uses the workspace's default tool permissions.
This skill is the authoritative rule for where Daniel-authored Claude Code plugins persist user data. Every plugin's onboarding, preferences, and state-storage logic should follow the convention defined here.
Mandates invoking relevant skills via tools before any response in coding sessions. Covers access, priorities, and adaptations for Claude Code, Copilot CLI, Gemini CLI.
Share bugs, ideas, or general feedback.
This skill is the authoritative rule for where Daniel-authored Claude Code plugins persist user data. Every plugin's onboarding, preferences, and state-storage logic should follow the convention defined here.
Never write plugin data under ~/.claude/. That directory is Claude Code's own config surface; ~/.claude/plugins/<plugin>/ in particular is the plugin install directory and is overwritten on every plugin update.
Resolve the base data directory like this:
${CLAUDE_USER_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/claude-plugins}/<plugin-name>/
CLAUDE_USER_DATA conventionCLAUDE_USER_DATA is the single env var that controls where plugin-owned persistent data lives. If the user sets it, everything relocates there (useful for backups, Dropbox sync, external drives). If unset, the resolution falls through to XDG, then to ~/.local/share/claude-plugins/.
Resolution order, in the exact form plugins should use:
$CLAUDE_USER_DATA if set → $CLAUDE_USER_DATA/<plugin-name>/$XDG_DATA_HOME if set → $XDG_DATA_HOME/claude-plugins/<plugin-name>/$HOME/.local/share/claude-plugins/<plugin-name>/On macOS and Windows, the XDG fallback is conventional (most tools honour it on macOS; on Windows, %APPDATA%\claude-plugins\<plugin>\ is acceptable if XDG isn't set).
PLUGIN_NAME="<plugin-name>"
PLUGIN_DATA_DIR="${CLAUDE_USER_DATA:-${XDG_DATA_HOME:-$HOME/.local/share}/claude-plugins}/$PLUGIN_NAME"
mkdir -p "$PLUGIN_DATA_DIR"
Resolve the plugin's data directory as
$CLAUDE_USER_DATA/<plugin-name>/ifCLAUDE_USER_DATAis set; otherwise$XDG_DATA_HOME/claude-plugins/<plugin-name>/ifXDG_DATA_HOMEis set; otherwise~/.local/share/claude-plugins/<plugin-name>/. Create the directory if it doesn't exist.
Inside <plugin-data-dir>/:
| Subpath | Purpose |
|---|---|
config.json | Small pointers and settings (e.g., path to user-owned data repo) |
data/ | Plugin-owned user data, if the plugin is the owner |
cache/ | Regenerable — safe to delete |
state/ | Runtime state that should persist across sessions |
Not every plugin needs all four — use only what applies.
Many plugins (Resume-Typesetter, Budgeting, Purchasing workspaces) operate on data that lives in a user-chosen location — a GitHub repo, ~/Documents/..., or ~/repos/.... The rule:
~/Documents/ or ~/repos/ — never under ~/.claude/ and never under the plugin's data dir.config.json (in the plugin data dir) stores the pointer to the user's chosen path.~/.claude/ (allowed)Plugins MAY read (never write) from:
~/.claude/CLAUDE.md — user's global context, useful for personalising generated workspaces.~/.claude/settings.json — Claude Code settings, for MCP config inspection.~/.claude/context/ — chunked global context files.The user-claude-md plugin is the only exception that writes to ~/.claude/CLAUDE.md — that's its entire purpose.
| Pattern | Why forbidden |
|---|---|
~/.claude/plugins/<plugin>/config.json | Install directory — overwritten on plugin update. Data loss. |
~/.claude/plugins/<plugin>/data/... | Same as above. |
~/.claude/<plugin>-preferences.md | Clutters Claude Code config surface; inconsistent; hard to back up. |
~/.claude/<plugin>/... | Same as above. |
~/.claude/data/... | Same as above. |
Plugins previously wrote to forbidden locations. Onboarding flows should include a migration block:
~/.claude/plugins/<plugin>/config.json, ~/.claude/<plugin>-preferences.md, etc.).Because all plugin data lives under one root ($CLAUDE_USER_DATA or ~/.local/share/claude-plugins/), users can back up every plugin's state with a single directory target. Documentation should mention this when relevant.
This convention exists to work around Anthropic bug #51342 — Claude Code itself suggests inconsistent paths under ~/.claude/ for plugin data, creating update-clobber risk. If Anthropic later blesses an official env var or path, this reference is the single place to update.