npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

claude-modules

v1.0.5

Published

Composable plugin modules for Claude Code, applied across user/project/local scopes

Readme

claude-modules

Composable, portable plugin bundles for Claude Code.

Docs & overview — full guide, command reference, and a plain-English tour of what claude-modules does.

npm license: MIT node

Every module is:

  • Self-sufficient — it 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.
  • Transferable — export packs a module and its whole composition chain into one .tar.gz; import unpacks it on another machine.

Example workflow

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. Build modules plugin by plugin, then compose them into the role you actually switch into:

# 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

Already have a repo configured the way you like — by hand, or through /plugin? create <module> --from-scope <scope> captures it in one shot instead of typing every plugin install. See Quick start below.

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

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 instead of adding to it:

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

Later, after a module's plugin list changes: claude-modules reload --scope project.

Modules aren't limited to coding roles, either — anything you switch into works the same way. Register the marketplace it needs, build the module, and enable it exclusively so it's the only thing active, unrelated dev modules included:

claude-modules marketplace add anthropics/financial-services-plugins --name claude-for-financial-services

claude-modules create investing
claude-modules plugin install investing wealth-management@claude-for-financial-services
claude-modules plugin install investing private-equity@claude-for-financial-services
claude-modules plugin install investing investment-banking@claude-for-financial-services

claude-modules enable investing --scope user --only --save   # only investing is active now

Why not just use /plugin?

| | Claude Code /plugin | claude-modules | | ------------------- | -------------------------------------------------- | ------------------------------------------ | | Unit of work | one plugin at a time | a named bundle of plugins | | Grouping | none — enabledPlugins is a flat map | modules, which compose into bigger modules | | Reuse across repos | re-enable each plugin, per repo | enable backend | | Another machine | re-add marketplaces, re-enable plugins | export → import, one file | | Switching roles | hand-edit up to three settings.json files | enable backend --only | | Auditing what's on | read three files and apply precedence in your head | status — exit-coded, --json | | Sharing with a team | commit .claude/settings.json wholesale | commit .claude-modules, then reload |

There's a secondary benefit too: fewer enabled plugins means fewer tools Claude has to choose between on every turn — see Concepts → Context budget for the cost this addresses and a caveat on MCP-heavy plugins.


Installation

npm install -g claude-modules      # global CLI

Or run it without installing:

npx claude-modules --help

From source:

git clone https://github.com/egelev/claude-modules.git
cd claude-modules
npm install
npm run build
npm link          # puts `claude-modules` on your PATH

Configuration

| Variable | Default | What it points at | | --------------------- | ------------------- | ------------------------------------------------------------------------ | | CLAUDE_MODULES_HOME | ~/.claude-modules | Where your modules and the marketplace registry live | | CLAUDE_CONFIG_DIR | ~/.claude | Claude Code's own home — read for the user scope and its plugin caches |


Quick start

Start from a repo you've already configured by hand, or through /plugin:

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

That captured what was already enabled there. Check it:

claude-modules list
claude-modules info backend
backend (v1.0.0) — 3 plugin(s) enabled, 1 marketplace(s)
backend (v1.0.0): 3 plugin(s):
  typescript-lsp@claude-plugins (enabled)
  postgres-mcp@claude-plugins (enabled)
  code-review@claude-plugins (enabled)

backend: 1 marketplace(s):
  claude-plugins: {"source":{"source":"github","repo":"anthropics/claude-plugins"}}

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

claude-modules enable backend --scope project --save
Enabled module(s) [backend] in project scope (/repo/.claude/settings.json); 1 marketplace(s) known.

Enabled plugin(s):
  - code-review@claude-plugins (local)
  - postgres-mcp@claude-plugins (local — not cached by Claude Code — run 'claude plugin install postgres-mcp@claude-plugins --scope user -y')
  - typescript-lsp@claude-plugins (local)
  - code-review@claude-plugins (project)
  - postgres-mcp@claude-plugins (project — not cached by Claude Code — run 'claude plugin install postgres-mcp@claude-plugins --scope user -y')
  - typescript-lsp@claude-plugins (project)

Saved module selection to /repo/.claude-modules.
Modules active in project scope: [backend].

These plugins are listed twice because the report covers every scope in effect, not just the one written — they're still enabled in local too, where they started. postgres-mcp is flagged as not cached because enabling a plugin isn't the same as caching it; --install fixes that. See Applying modules → The report for the full format.

From here, claude-modules status audits the result at any time, and exits non-zero if something has drifted — see the docs.

Changes apply to the next session — an already-open one needs /reload-plugins (or a restart) to pick them up. See Applying modules for why, every command reminds you in its own output.


How it works

A module is a directory under $CLAUDE_MODULES_HOME/modules/<name>/ holding a settings.json:

{
  "version": "1.2.0",
  "enabledPlugins": { "typescript-lsp@claude-plugins": true },
  "extraKnownMarketplaces": {
    "claude-plugins": { "source": { "source": "github", "repo": "anthropics/claude-plugins" } }
  },
  "composedModules": ["base"]
}

enabledPlugins and extraKnownMarketplaces match the exact shape Claude Code itself uses. composedModules and version are this tool's own additions.

Scopes are the same three Claude Code uses, resolved with local > project > user:

| Scope | File | Needs a git repo? | | --------- | ------------------------------------------------------------------------ | ----------------- | | user | ~/.claude/settings.json (or $CLAUDE_CONFIG_DIR/settings.json) | no | | project | <repo_root>/.claude/settings.json | yes | | local | <repo_root>/.claude/settings.local.json, or <cwd>/... outside a repo | no |

--scope defaults to local.

Modules combine two ways. Naming several on one call (enable backend frontend) unions them for that call only. Declaring composedModules makes the relationship part of the module itself, pulled in transitively by every future command. Both are covered in Concepts → Composition.

Module lists remember which modules you applied, so reload can reapply them and status can detect drift. One per scope:

| Scope | Module list | | | --------- | ----------------------------------- | -------------------------------------------- | | user | $CLAUDE_MODULES_HOME/user.modules | global | | project | <repo_root>/.claude-modules | commit it — shared with the team | | local | <repo_root>/.claude-modules.local | gitignore it — personal to your checkout |


Commands

| Command | What it does | | | ----------------------------------------- | ------------------------------------------------------------------ | ----------------------------------------------- | | list | List every module with its plugin and marketplace counts | docs | | info <module> | Show one module's plugins, marketplaces, and composition | docs | | create <module> | Create a module — empty, seeded from a scope, or composing others | docs | | remove <module> | Delete a module | docs | | compose add <module> <composed...> | Make a module build on others | docs | | compose remove <module> <composed...> | Stop building on others | docs | | plugin install <module> <plugin>@<mp> | Enable a plugin inside a module | docs | | plugin uninstall <module> <plugin>@<mp> | Disable a plugin inside a module | docs | | marketplace add <spec> | Register a marketplace, globally or on a module | docs | | marketplace remove <name> | Unregister a marketplace | docs | | marketplace list | List registered marketplaces | docs | | enable <module...> | Apply modules to a scope | docs | | disable <module...> | Turn a scope's copy of those plugins off | docs | | disable-all | Turn every plugin in a scope off | docs | | reload | Re-apply a scope's saved module list | docs | | update [module...] | Update modules' marketplaces then plugins to their latest versions | docs | | status | Audit a scope; exit-coded for CI | docs | | export <module> | Pack a module and its composition chain into a .tar.gz | docs | | import <archive> | Unpack one on another machine | docs | | completions <bash\|zsh> | Print a tab-completion script for your shell | docs |

Global options

| Flag | Effect | | ----------------- | ------------------------------------------------------------------------------- | | -h, --help | Show help. Works after any command: claude-modules plugin install --help | | -v, --version | Print the installed version | | --verbose | Enable debug logging | | --dry-run | Preview a mutating command's effect — writes nothing, runs no external commands |

--dry-run is supported by all 15 mutating commands, and is a no-op on the five that never write (list, info, status, marketplace list, completions). Running a bare group name — claude-modules plugin, marketplace, or compose — prints that group's usage.


Known limitations

  • No token-cost preview. Modules report plugin counts, not tokens. Claude Code knows the number but offers no way to aggregate it per module yet. → details
  • No version pinning. A module records which plugins to enable, not which versions. Treat modules as portable role definitions, not lockfiles. → details
  • Marketplace sources are snapshots. Resolved sources are copied onto the module; later registry changes don't propagate. → details
  • Plugin configuration isn't captured. Per-plugin userConfig is deliberately excluded so a committed module can't become a secret-exfiltration path. → details
  • Composition overrides stop after one level. An explicit false beats a directly composed child, but not a grandchild. → details

Contributing

Development setup, the pull-request workflow, and the release steps live in CONTRIBUTING.md.


License

MIT © Emil Gelev