For Claude Code

Composable, portable plugin bundles for Claude Code.

Claude Code enables plugins one at a time, per scope, across three separate settings.json files. claude-modules lets you bundle them into named modules and switch between them with a single command.

npm version license: MIT node >= 20
terminal
# A base layer every stack builds on
claude-modules create base-dev
claude-modules plugin install base-dev context7@claude-plugins

# A frontend-specific module
claude-modules create fe
claude-modules plugin install fe playwright@claude-plugins

# Compose them into one role, declared once
claude-modules create full-dev --compose base-dev --compose fe
claude-modules enable full-dev --scope project --save
What it is

A module is a named bundle of plugins — the way to manage Claude Code plugins as a set, with everything they need to work anywhere.

Instead of enabling plugins one by one, you group them into a module once. Every module is:

Self-sufficient

Carries its plugins and the marketplaces they come from, so it works on a machine that's never seen them.

Composable

fullstack = backend + frontend, declared once and resolved every time, not retyped.

Reusable

The same module applies to any repo, at any scope — write it once, enable it everywhere.

Transferable

export packs a module and its whole composition chain into one .tar.gz; import unpacks it elsewhere.

Why not just /plugin?

/plugin manages one plugin at a time. This lets you switch Claude Code plugin sets in one command.

  Claude Code /plugin manages one plugin at a time claude-modules manages bundles you compose into roles
Unit of workone plugin at a timea named bundle of plugins
Groupingnone — enabledPlugins is a flat mapmodules, which compose into bigger modules
Reuse across reposre-enable each plugin, per repoenable backend
Another machinere-add marketplaces, re-enable pluginsexport → import, one file
Switching roleshand-edit up to three settings.json filesenable backend --only
Auditing what's onread three files and apply precedence in your headstatus — exit-coded, --json
Sharing with a teamcommit .claude/settings.json wholesalecommit .claude-modules, then reload

There's a secondary benefit too: every enabled plugin adds tools Claude has to choose between on every turn, and Claude's own docs note that tool-selection accuracy degrades past 30–50 loaded tools. Scoping your tools to the role you're currently performing helps — see the caveat for MCP-heavy plugins in the docs.

Setup

Install it, then capture what you already have.

Node 20+ is the only requirement.

install
npm install -g claude-modules      # global CLI

Or run it without installing: npx claude-modules --help

See Installation in the docs for building from source, and Configuration for CLAUDE_MODULES_HOME.

Recommended workflow

Build modules plugin by plugin, then compose them into the role you switch into.

This is the way to build a module: one plugin install at a time, one concern per module, composed together deliberately. Starting from an empty module keeps each one scoped to a single concern and easy to compose later — if you'd rather capture a scope you've already configured by hand instead, that's a fallback, covered below.

terminal
# A base layer every stack builds on
claude-modules create base-dev
claude-modules plugin install base-dev context7@claude-plugins
claude-modules plugin install base-dev code-simplifier@claude-plugins

# A Quarkus-specific module
claude-modules create quarkus
claude-modules plugin install quarkus jdtls-lsp@claude-plugins
claude-modules plugin install quarkus quarkus-agent@claude-plugins

# A frontend-specific module
claude-modules create fe
claude-modules plugin install fe modern-web-guidance@claude-plugins
claude-modules plugin install fe playwright@claude-plugins
claude-modules plugin install fe typescript-lsp@claude-plugins
claude-modules plugin install fe frontend-design@claude-plugins

# Compose them into one role, declared once
claude-modules create full-dev --compose base-dev --compose quarkus --compose fe
claude-modules enable full-dev --scope project --save   # transitively pulls in all three, every time

Don't need full-dev as a permanent unit? Name the modules directly on one enable call instead — an ad-hoc union, good for one-off combinations you won't reuse:

terminal
claude-modules enable base-dev quarkus fe --save

And when you're switching roles rather than layering on top of what's active, add --only to make the scope exactly the given modules:

terminal
claude-modules enable full-dev --scope user --only --save
claude-modules enable base-dev --scope user --only          # Monday: quarkus/fe plugins go quiet
Fallback path

Already configured a repo by hand, or through /plugin? Capture it instead.

create --from-scope captures what's already enabled in one shot, without retyping every plugin install. It's a shortcut, not the recommended way to build a module — a scope tends to accumulate plugins for whatever you were doing at the time, so it can just as easily capture a bundle mixing unrelated concerns as a clean one. Reach for the recommended workflow above when you're starting fresh.

Capture what's already enabled

terminal
cd ~/projects/api-service
claude-modules create api-svc --from-scope local
output
Created module 'api-svc' from local scope (/repo/.claude/settings.local.json) with 3 plugin(s), 1 marketplace(s), and 0 composed module(s).

Check what it captured

terminal
claude-modules list
claude-modules info api-svc
output
api-svc (v1.0.0): 3 plugin(s):
  typescript-lsp@claude-plugins (enabled)
  postgres-mcp@claude-plugins (enabled)
  code-review@claude-plugins (enabled)

Apply it — shared with the team

Here to project scope, so it's shared with the team, and --save so you don't have to retype it:

terminal
claude-modules enable api-svc --scope project --save

Changes apply to the next session. Claude Code reads enabledPlugins at session start. Run /reload-plugins in an already-open session, or start a new one.

Audit it any time

claude-modules status checks the scope against Claude Code's own plugin cache and the saved module list, and exits non-zero if something has drifted — see the docs.

Every command

Twenty commands cover building, applying, auditing, and moving modules.

Full option tables and every caveat live in the docs — this is the map.

CommandWhat it does
listList every module with its plugin and marketplace counts
info <module>Show one module's plugins, marketplaces, and composition
create <module>Create a module — empty, seeded from a scope, or composing others
remove <module>Delete a module
compose addMake a module build on others
compose removeStop building on others
plugin installEnable a plugin inside a module
plugin uninstallDisable a plugin inside a module
marketplace addRegister a marketplace, globally or on a module
marketplace removeUnregister a marketplace
marketplace listList registered marketplaces
enable <module...>Apply modules to a scope
disable <module...>Turn a scope's copy of those plugins off
disable-allTurn every plugin in a scope off
reloadRe-apply a scope's saved module list
update [module...]Update modules' marketplaces then plugins to latest
statusAudit a scope; exit-coded for CI
export <module>Pack a module and its composition chain into a .tar.gz
import <archive>Unpack one on another machine
completions bash|zshPrint a tab-completion script for your shell
Known limitations

Stated honestly, not buried.

No token-cost preview. Modules report plugin counts, not tokens — Claude Code has no way to aggregate that per module yet.

No version pinning. A module records which plugins to enable, not which versions. Treat modules as portable role definitions, not lockfiles.

Marketplace sources are snapshots. Resolved sources are copied onto the module; later registry changes don't propagate.

Plugin configuration isn't captured. Per-plugin userConfig is deliberately excluded so a committed module can't become a secret-exfiltration path.

Composition overrides stop after one level. An explicit false beats a directly composed child, but not a grandchild.

See the docs for the full explanation of each.