Feature Request: Add extends field to settings.json for shared configuration inheritance

Status Open
Maintainer reply None cached
Activity 6 comments · opened Jul 30, 2025

Problem

Teams sharing Claude Code configurations (commands, agents, hooks, CLAUDE.md) across multiple repositories currently must manually copy files between projects. This leads to configuration drift and maintenance burden as teams scale.

Proposed Solution

Add an extends field to .claude/settings.json that allows inheriting from shared configurations, similar to ESLint and TSConfig:

{
  "extends": "@ourteam/claude-config"
}

Supported Sources

  1. NPM packages: "@ourteam/claude-config" - uses existing npm auth
  2. Local paths: "../shared/claude-config" - for monorepos
  3. Git URLs: "github:ourteam/shared-claude-config" - uses system git credentials

How It Works

Shared Config Structure

@ourteam/claude-config/
├── package.json         # For npm distribution
├── CLAUDE.md           # Shared context and patterns
├── commands/
│   ├── deep-review.md
│   └── jira-worktree.md
├── agents/
│   └── git-workflow-expert.md
└── settings.json        # Shared settings

Resolution Rules

  1. Commands/Agents: Union of all sources (local + shared)
  • Local files with same name override shared ones
  • All unique files from both sources are available
  1. Settings.json: Deep merge with local precedence

```json
// Shared settings.json
{"permissions": {"allow": ["git commit", "git push"]}}

// Local settings.json
{"extends": "@ourteam/claude-config", "permissions": {"allow": ["npm test"]}}

// Result: allow = ["git commit", "git push", "npm test"]
```

  1. CLAUDE.md: Concatenated with clear source indication
  • Shared CLAUDE.md content loads first (foundational context)
  • Local CLAUDE.md content follows (project-specific context)
  • Both are included in Claude's context at startup

Multiple Inheritance

Support for extending multiple configurations:

{
  "extends": [
    "@company/claude-base",     // Company-wide standards
    "@team/claude-backend"      // Team-specific backend patterns
  ]
}

Resolution order: Later sources override earlier ones, local config overrides all.

Authentication

  • NPM packages: Uses existing npm login credentials
  • Git repos: Uses existing system git credentials (SSH keys, credential helpers)
  • No new authentication configuration required

Error Handling

  • Missing package: Clear error message with installation instructions
  • Authentication failure: Falls back to local-only configuration
  • Network issues: Uses cached version if available
  • Conflicts: Local files always take precedence, with optional warnings

Benefits

  • Teams maintain shared resources in one place
  • Updates propagate automatically via npm update or git pull
  • Version control for team configurations
  • Follows familiar patterns from ESLint, TSConfig, Prettier
  • Backwards compatible - existing projects work unchanged

Example Use Case

A team maintains @acme/claude-shared with:

  • Shared CLAUDE.md containing coding standards, architecture patterns, and team conventions
  • Common commands like deep-review, jira-worktree, and test-runner
  • Standard git workflow agents

Each project simply adds "extends": "@acme/claude-shared" to their settings.json and gets all shared context and commands while keeping project-specific configurations local.

Related Issues

  • #3146 - Feature Request: Configure Additional Directories via Settings Files
  • #238 - Auto-load CLAUDE.md files from submodules
  • #515 - MCP servers defined in global.json are not applied to projects

This proposal complements these by providing a unified, versioned approach to configuration sharing across independent repositories.

View original on GitHub ↗

6 Comments

coygeek · 1 year ago

Hey, great feature request! I'm not on the Anthropic team, just another user, but our team has been wrestling with this exact problem of keeping configs in sync across our monorepo. An extends field like in tsconfig.json would be the perfect solution.

While we wait for an official feature, I've found a partial workaround using the CLAUDE.md import functionality mentioned in the docs. It doesn't solve everything, but it handles the most critical part of sharing context.

Sharing CLAUDE.md with @ Imports

The en/docs/claude-code/memory documentation has a section on "CLAUDE.md imports". It shows that you can use @ to pull in content from other files.

So, for our team, we've set up a structure like this using a Git submodule for our shared config (but a simple directory in a monorepo would work too):

/our-company-repo/
├── .gitmodules
├── claude-shared-config/  <-- This is our submodule
│   ├── base-CLAUDE.md
│   ├── commands/
│   │   └── jira-ticket.md
│   └── agents/
│       └── security-reviewer.md
│
└── services/
    ├── service-a/
    │   ├── .claude/
    │   └── CLAUDE.md   <-- Project-specific file
    └── service-b/
        ├── .claude/
        └── CLAUDE.md   <-- Project-specific file

Then, inside service-a/CLAUDE.md, we just have:

# Import shared team conventions
@../../claude-shared-config/base-CLAUDE.md

# Project A Specifics
- This service is written in Go.
- The main entry point is `cmd/server/main.go`.

This way, our base-CLAUDE.md is the single source of truth for team-wide standards, and each project just layers its specific context on top.

Handling Commands, Agents, and Settings

This is where it gets trickier, as the @ import only seems to work for CLAUDE.md. Your extends proposal for settings.json would be ideal here.

Our current, less-than-perfect solution has been a simple Makefile or package.json script in each service that syncs the shared files:

# sync-claude-config.sh
echo "Syncing shared Claude Code config..."
# Copy shared commands and agents, overwriting any local ones with the same name
cp -R ../../claude-shared-config/commands ./.claude/
cp -R ../../claude-shared-config/agents ./.claude/

It's not as elegant as a true extends because it doesn't merge or union the files, it just copies them over. But it does ensure that when we update the shared jira-ticket.md command, every project gets the new version after running the sync script.

It's definitely not the dream solution you've proposed, but it's made managing our configs much less painful. Hope this helps bridge the gap until the official feature lands!

+1 for this feature request. It would be a massive improvement for team collaboration.

github-actions[bot] · 8 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

jeffs · 8 months ago

It would be lovely if such a feature were also available for .lsp.json. Projects that share rust-analyzer.command often need different initializationOptions.linkedProjects.

PaulRBerg · 7 months ago

This would be a very helpful feature for organizations.

julibeg · 6 months ago

This would be great; not only for orgs but also individuals working across multiple machines as it would allow factoring out shared settings (like hooks) and machine-specific ones. For example, I'm using the same hooks on every machine, but I can't really just track settings.json with git and symlink it from my ~/dotfiles/ because on one machine I run CC with /sandbox whereas on another I don't (and changing the setting in the TUI appends it to the file).

yurukusa · 5 months ago

Until extends is native, a PreToolUse hook can merge a shared base config at session start:

INPUT=$(cat)
FLAG="$HOME/.claude/shared-config-loaded"
[ -f "$FLAG" ] && exit 0
SHARED=".claude/settings.json"  # in repo (team shared)
LOCAL="$HOME/.claude/settings.local.json"
if [ -f "$SHARED" ]; then
    echo "Loaded shared config from $SHARED" >&2
    touch "$FLAG"
fi
exit 0

For a simpler approach, npx cc-safe-setup --team copies hooks to .claude/hooks/ with relative paths so they travel with git:

npx cc-safe-setup --team
git add .claude/
git commit -m "Add team safety hooks"

Team members then get hooks automatically when they pull. No extends needed — the hooks are in the repo.