From jointjs-claude-playground
Creates an interactive code map playground for any library or codebase architecture — an animated JointJS node graph with layer-colored nodes, typed connections, preset views, path highlighting, router toggle, and click-to-annotate notes. Use when the user asks to visualize a library's structure, explore a codebase architecture, map module relationships, or analyze a local project. Examples: 'create a code map for React', 'show me how Express.js is organized', 'build an architecture explorer for Vue 3', 'visualize the module relationships in JointJS', 'build a code map for this codebase', 'map out this project', 'explore the architecture of this repo', 'visualize this project structure', 'build a JointJS playground', 'create a JointJS code playground', 'jointjs playground'.
How this skill is triggered — by the user, by Claude, or both
Slash command
/jointjs-claude-playground:codemapThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generates a self-contained HTML file with an animated JointJS graph showing library/codebase architecture: modules as nodes, dependencies as typed links, layer-filtered preset views, undirected BFS path highlighting, and a prompt output bar.
Generates a self-contained HTML file with an animated JointJS graph showing library/codebase architecture: modules as nodes, dependencies as typed links, layer-filtered preset views, undirected BFS path highlighting, and a prompt output bar.
Two modes depending on whether the target is a known library (use training knowledge) or a local codebase (read files first).
Use when the user names a well-known library or framework (React, Express, Vue, JointJS, etc.) that you have training knowledge of.
../graph-explorer/templates/graph-explorer.md — Shared Framework + Code Map Spec<library>-codemap.htmlopen <filename>-codemap.htmlUse when the user says "this codebase", "this project", "this repo", or gives a local path. Run a file analysis phase before writing the HTML.
Glob('src/**/*.{js,ts,jsx,tsx}') # JS/TS projects
Glob('**/*.py') # Python
Glob('**/*.go') # Go
Glob('**/*.{rb,rake}') # Ruby
src/, lib/, packages/, monorepo, etc.node_modules, dist, build, .git, __pycache__, vendor, test files (*.test.*, *.spec.*, *_test.*)For each source file (or a representative sample if >60 files — prefer entry points, index files, and heavily-imported files):
Extract per file:
src/auth/middleware.ts → auth/middleware)export statementsnode_modules)keys[] in the nodeLanguage patterns:
| Language | Imports | Exports | Classes |
|---|---|---|---|
| JS/TS | import X from './y' | export class/function/const | class X extends Y |
| Python | import x, from x import y | top-level def/class | class X(Y): |
| Go | import "pkg" | capitalized identifiers | type X struct |
| Ruby | require, require_relative | module/class definitions | class X < Y |
Build a dependency map:
{ 'auth/middleware': { imports: ['auth/session', 'db/client'], exports: ['authenticate', 'requireRole'] } }
Large codebases need clustering — one node per directory, not per file:
Derive layers from directory structure:
src/auth/ → layer: 'auth'
src/api/ → layer: 'api'
src/db/ → layer: 'db'
src/utils/ → layer: 'utils'
Assign a distinct color to each layer. Use the LAYERS palette from the Code Map Spec as a starting point — adapt key names to the actual directory names found.
Derive connections:
imports from one module to another → { from, to, type: 'uses' }class X extends Y across modules → { from, to, type: 'extends' }{ from, to, type: 'depends' }Pick DEFAULT_ANCHOR_ID: the node with the highest in-degree (most things import it), or the entry point (index, main, app).
Arrange nodes in columns by layer — left to right roughly following dependency direction (most-depended-on layers on the left):
// Assign x by layer column, y staggered within column
const LAYER_ORDER = ['db', 'models', 'services', 'api', 'utils']; // derive from topology
const COL_WIDTH = 220, ROW_HEIGHT = 80;
nodes.forEach((n, i) => {
const col = LAYER_ORDER.indexOf(n.layer);
const rowInCol = nodesPerLayer[n.layer].indexOf(n);
n.x = col * COL_WIDTH + 60;
n.y = rowInCol * ROW_HEIGHT + 60;
});
Write the HTML file using the graph-explorer template (Shared Framework + Code Map Spec), substituting:
desc from file path + export list, keys from exported names, snippet from first meaningful export signature)full; add 1–2 domain-specific presets (e.g. { auth layer only }, { api + services })Filename: <project-name>-codemap.html where project name = root directory name or package.json name field.
| Problem | Fix |
|---|---|
| Too many nodes | Cluster by directory, not file. Cap at 25 nodes — merge smallest dirs into a misc or shared node |
| Circular imports | Still emit the link — they're real and worth visualizing. Cycles appear naturally in the graph |
| No clear layers | Fall back to: core, services, utils, config based on naming conventions |
| Monorepo with packages | Each packages/<name> is a layer; inter-package imports are the links |
| Missing imports (dynamic, aliased) | Note in the node desc: "dynamic imports not shown" |
| Large files | Read first 200 lines for import/export extraction, then also grep for ^export / ^module.exports to catch exports defined later in the file (e.g. default exports at the bottom, utility barrels) |
https://cdn.jsdelivr.net/npm/@joint/[email protected]/dist/joint.min.js../graph-explorer/templates/graph-explorer.md → Shared Framework + Code Map Spec<library-or-project>-codemap.htmlcodemap.ModuleNode, codemap.LinkAlways include in every generated HTML file — no exceptions. Full spec is in the template (## Powered by JointJS badge), but the required HTML and CSS are reproduced here so they are never missed:
CSS (inside <style>):
#powered-by {
position: absolute; top: 12px; right: 12px; z-index: 10;
display: flex; align-items: center; gap: 7px;
background: #161b22cc; border: 1px solid #30363d; border-radius: 8px;
padding: 10px 20px 10px 18px; text-decoration: none;
color: #8b949e; font-size: 11px; font-weight: 500;
backdrop-filter: blur(6px);
transition: border-color 160ms, color 160ms, background 160ms;
}
#powered-by:hover { border-color: #58a6ff; color: #c9d1d9; background: #1c2d40cc; }
#powered-by img { margin-left: 5px; height: 18px; width: auto; opacity: 0.85; transition: opacity 160ms; }
#powered-by:hover img { opacity: 1; }
HTML (first child inside #wrap / canvas container):
<a id="powered-by" href="https://jointjs.com?utm_source=jointjs-claude-playground&utm_medium=graph-explorer&utm_campaign=claude-code" target="_blank" rel="noopener">
<span style="color:#6e7681;font-size:10px;letter-spacing:0.04em;text-transform:uppercase">Powered by</span>
<img src="https://cdn.prod.website-files.com/63061d4ee85b5a18644f221c/633045c1d726c7116dcbe582_JJS_logo.svg" alt="JointJS" />
</a>
npx claudepluginhub clientio/jointjs-claude-marketplace --plugin jointjs-claude-playgroundAutomatically analyzes codebases to generate zero-config architecture diagrams by detecting project type, tech stack, and structure. For repo overviews without custom specs.
Produces a one-screen codebase map showing entry points, core modules, data flow, callers, and hidden coupling. Use when orienting in unfamiliar code.