An unofficial community directory of Claude Code mods and extensions: mods, plugins, skills, agents, hooks, MCP servers and slash commands.
Live site: claudecodemods.com
Not affiliated with or endorsed by Anthropic.
A mod is a Claude Code plugin whose behaviour lives in a hooks module. Anthropic publishes four in anthropics/claude-code: sec-default, diff, telemetry and agents-md. They ship inside Claude Code, they are early access, and the API they are written against may change between releases without notice. Each has its own page here with what it does, how to run it from source and where to download it.
Every entry in the directory has public source.
- Source verified: the entry's source URL returned HTTP 200 on the catalog date. This means the source exists. It does not mean the code was reviewed or security scanned, and nothing here claims it was.
- Availability: an entry is installable (it has documented install commands), built in (it ships inside Claude Code) or source only.
- Ideas: the marketplace spec describes more mods that nobody has published. They live on the Ideas page and in
src/data/ideas.json, apart from the directory, its counts and its search. They cannot be installed.
The specification's security tiers (A, B, C, revoked) are a design, not a running scanner. No listing has a tier today.
Community listings are added by pull request. In short:
- Fork this repository and clone your fork.
- Add one file,
src/data/community/<slug>.json, holding one entry. - Run
npm test, thennpm run catalog:verify -- --only <file>andnpm run catalog:structure -- --only <file>. - Open a pull request. CI runs the same checks.
- A maintainer reads the entry and merges it, and the site rebuilds.
CI checks the shape of the entry, that its URLs respond and that its manifest files exist. It cannot prove that a command or a package is safe. A maintainer reads the text of each submission, not the code it points to. Listed means the source exists. It does not mean reviewed. Community entries carry a visible "Community listing" label.
Read CONTRIBUTING.md for the rules (including which commands an entry may contain), the field list and an example entry.
Open item: this repository has no LICENSE file yet, and the maintainer will decide the license that applies to submitted data.
Next.js 16 (App Router, static export), React 19, Tailwind CSS v4, strict TypeScript, Zod, Motion, Phosphor icons, Vitest and Testing Library.
Requires Node 22 or newer.
npm ci
npm run dev # http://localhost:3000
npm run typecheck
npm run lint
npm test
npm run build # static export to ./outMaintainer entries live in src/data/catalog.json and community entries in src/data/community/<slug>.json. Both are validated at load time against the Zod schema in src/lib/types.ts. Ideas live in src/data/ideas.json.
npm run catalog:verify # re-checks every URL, exits non-zero on any non-200
npm run catalog:structure # checks that plugin and mod entries have their manifest filesAdd -- --only <file> to either command to check just one data file. Pages read the catalog only through src/lib/catalog.ts, src/lib/ideas.ts and src/lib/search.ts. Nothing in the UI hardcodes entry names, counts or star numbers.
Hook event names live in src/data/events.json, read through src/lib/events.ts. Anthropic publishes the type declarations they come from under "All rights reserved" terms, so the file keeps only event names, their family and the line each is declared on, pinned to an upstream commit. Regenerate it with:
npm run sync:events # print what would change, write nothing
npm run sync:events -- --write # update src/data/events.json, then review the diff
npm run sync:events -- --sha <commit> --write # pin a specific upstream commitCI (.github/workflows/validate.yml) runs typecheck, lint, tests and a build on every pull request, runs the two catalog checks on the community files a pull request adds or changes, and asks a submission to touch only src/data/community/. That last check is advisory, because a pull request runs its own workflow; the real protection is .github/CODEOWNERS plus a branch ruleset that requires code owner review. .github/workflows/reverify.yml re-runs both catalog checks on every entry each week, so link rot or a rewritten repository shows up as a failed run.
/learn/ and /learn/getting-started/ teach Claude Mods. Their copy is typed data in src/components/docs/learnContent.ts, and each claim in it comes from a linked source or from a command run on the Claude Code version named on the page (TESTED_WITH). Nothing is copied from Anthropic's type declarations, which are published under "All rights reserved" terms.
templates/mod-starter/ is a complete mod that refuses a Bash call which force pushes with git. The Getting started page reads its files at build time through src/lib/starter-mod.ts, and a test fails if the folder holds a file the page does not show. To check it:
npm run test:starter # CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude plugin test templates/mod-starter
claude plugin validate templates/mod-starterclaude plugin test does not exist unless CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 is set, which the script does for that one command. CI does not run it, because the Claude Code CLI is not installed there, so the page dates its claim ("passed on Claude Code X on DATE") and this script is how a maintainer re-checks it.
Testing a mod runs its code, so read a folder before you run it. The variable is set on the command, not exported, so it is not left on for later sessions.
templates/migration-example/ moves three classic hooks to the classic.<Name> events for the Migration page. The test kit cannot fire a classic event, so it has no tests. Check both templates against Anthropic's declarations with:
npm run typecheck:templates # fetches the declarations at the pinned commit into a temp folder; needs the networkThat script also compiles scripts/fixtures/*.negative.ts, whose @ts-expect-error lines must keep failing: they hold the result-shape claims on the Migration page. It compiles TypeScript and never runs it, refuses a symbolic link under templates/ and scripts/fixtures/, and stops tsc after three minutes. The declarations it fetches are the ones at the commit in src/data/events.json, so treat a change to that commit in a pull request as something to review.
The folders are excluded from tsconfig.json: they import claude-code types that Claude Code writes with /plugin-types, and the site's own tests do not run them. Re-run the tests above when Claude Code updates, and update TESTED_WITH when you do.
/learn/tutorials/ plays the 9 official videos from the announcement issue, from data in src/components/docs/tutorialsContent.ts. The titles, captions and asset ids there are copied exactly from the issue's own body; nothing is paraphrased. The clips are not re-hosted: <video> points at GitHub's own stable attachment URL (github.com/user-attachments/assets/<id>), the same one the issue embeds, which GitHub keeps redirecting to a fresh short-lived link on every request. That needs media-src and img-src allowances in vercel.json's CSP for github.com and the one GitHub attachment CDN host the videos resolve to, added by exact hostname, not a wildcard. If GitHub ever serves attachments from a different host, the videos and the poster images will stop loading and the CSP entry needs updating; src/lib/vercel-config.test.ts checks the policy still names the hosts tutorialsContent.ts's VIDEO_HOSTS constant uses, so the two cannot silently drift apart.
Everything below is generated at build time from the catalog, so nothing lists an entry by hand. Code lives in src/lib/seo/ (pure and unit tested) and src/components/seo/.
| File | What it is |
|---|---|
src/lib/seo/metadata.ts |
One typed helper that builds Metadata for every page: title, description, absolute canonical URL, Open Graph, Twitter card, robots, author and the Atom feed link. |
src/lib/seo/pages.ts |
Title and description of each static page. Edit copy there. |
src/app/opengraph-image.tsx, twitter-image.tsx |
The 1200 by 630 site banner. Pages without their own image use it. |
src/app/extensions/[slug]/opengraph-image.tsx, src/app/ideas/opengraph-image.tsx |
Per-page link preview images. Catalog text is clamped and rendered only as text. |
src/app/icon.tsx, apple-icon.tsx, favicon.ico, manifest.ts, icons/ |
The brand mark as favicon, touch icon and web app icons (192, 512 and maskable). |
src/app/llms.txt/, llms-full.txt/ |
Index and full text of the directory for AI search, following llmstxt.org. |
src/app/feed.xml/ |
Atom feed, newest source check first. |
src/app/catalog.json/ |
The whole catalog as one read-only JSON document for tools that would otherwise scrape pages. It is data, not a Claude Code plugin marketplace: it has no install semantics. Community entries are reduced to an allowlisted index record, like in llms-full.txt. Built by src/lib/seo/catalogJson.ts. |
src/app/hooks/, src/lib/event-reference.ts, src/lib/event-names.ts |
The /hooks/ page: every event in src/data/events.json grouped by family and noun, with a filter, a link to its declaring line at the pinned upstream commit, and the entries that list it. Which entries use an event is derived from each entry's hooks field (an exact name, a wildcard such as classic.*, or a classic event written bare such as PreToolUse), so no event name is written by hand. Names an entry lists that select no event, such as telemetry.*, are listed apart. Extension pages link a hook that names exactly one event to its row. |
src/app/robots.ts, sitemap.ts |
Crawler rules (search and AI crawlers are allowed by name) and every indexable page with its own last modified date. |
src/lib/seo/jsonLd.ts |
JSON-LD graphs and serializeJsonLd, the only place catalog text is serialised into a <script>. |
src/assets/fonts/ |
Geist and Geist Mono for the generated images, under the SIL Open Font License (OFL.txt beside them). |
Environment variables, all optional:
| Variable | Effect |
|---|---|
NEXT_PUBLIC_SITE_URL |
Production origin used in canonical URLs, Open Graph URLs, the sitemap and the feed. Defaults to https://claudecodemods.com in production builds and http://localhost:3000 otherwise. |
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION |
Value of the Google Search Console google-site-verification tag. No tag is rendered when unset. |
NEXT_PUBLIC_BING_SITE_VERIFICATION |
Value of the Bing Webmaster msvalidate.01 tag. No tag is rendered when unset. |
To regenerate src/app/favicon.ico after changing the mark in src/lib/seo/brandMark.ts, run the dependency-free script and commit the result:
node --disable-warning=MODULE_TYPELESS_PACKAGE_JSON scripts/make-favicon.mjsThe share images are checked by eye: after npm run build, open the files named opengraph-image under out/ (they have no extension, but they are PNGs). Real previews on Slack, Discord, X and LinkedIn can only be checked after deployment, with each platform's own debugger.
The site is a static export deployed on Vercel.
- Import the repository in Vercel.
vercel.jsonalready sets the install command, the build command and the output directoryout, so the framework preset in the dashboard does not matter. - Set
NEXT_PUBLIC_SITE_URL=https://claudecodemods.comin the project's environment variables. - Enable Web Analytics in the Vercel dashboard for the project, then redeploy. The
@vercel/analyticscomponent is already in the layout and records nothing until it is enabled. - Security headers (Content-Security-Policy, HSTS and others) come from
vercel.json.
npm run build writes a fully static site to out/, so any static host also works. Set NEXT_PUBLIC_SITE_URL to that host's origin.