An interactive knowledge graph visualizer for Obsidian vaults (and any directory of interlinked Markdown files).
Scrymap parses wikilinks from .md files, builds a graph of nodes and relationships, and renders it as an interactive graph in the browser.
The repo includes examples/sample-vault, a small interlinked vault that demonstrates tagged wikilinks, vault views, and frontmatter metadata rendering.
Visit it here.
Or, to run locally:
npm run dev -- examples/sample-vaultPIDA is an example of a larger project using Scrymap.
- Force-directed graph — nodes repel and links attract, producing a natural layout
- Inline note viewer — click a node to read its Markdown content rendered in a side panel, with clickable wikilinks for in-graph navigation
- Navigation history — back/forward buttons and
Alt+←/Alt+→keyboard shortcuts powered by the browser History API - Filtering — hide node types, link types, or individual nodes; right-click a node to hide it instantly
- Depth filter — restrict the graph to N hops from the selected node
- Search/highlight — fuzzy-highlight nodes by name
- Views — save and restore named snapshots of all settings (filters, colors, physics)
- Vault views — define view presets in
.scrymap.config.jsinside the vault; they appear as built-in options - Color customization — per-type node colors and per-tag link colors
- Physics controls — charge strength, link distance, link width, node size, label threshold, link particles
- PNG export — snapshot the current canvas
- Dev mode live reload — the dev server watches the vault for
.mdchanges and pushes updates to the browser over WebSocket without a full page reload
- Node.js 18+
- npm
git clone https://github.com/your-username/scrymap.git
cd scrymap
npm installnpm run dev -- /path/to/your/vaultOpens Vite's dev server at http://localhost:5173. Any .md change in the vault triggers automatic graph regeneration and a hot update in the browser.
npm run build -- /path/to/your/vault
# Artifacts land in dist/This command first regenerates public/graph.json from the vault you pass in, then builds the frontend into dist/.
Serve the dist/ directory with any static file server.
npm run generate -- /path/to/your/vault
# Writes public/graph.jsonScrymap reads an optional .scrymap.config.js file at the root of the vault. It can export:
| Export | Type | Description |
|---|---|---|
resolveNode(filePath) |
(filePath: string) => NodeOverrides | false | null | undefined |
Include a node and optionally override its type, display name, or color |
views |
VaultView[] |
Named view presets baked into the UI |
If a vault view is named "Default", it replaces the built-in Default view, letting you set vault-specific defaults for physics, colors, and filters that apply on first load.
Example .scrymap.config.js:
export function resolveNode(filePath) {
if (filePath === 'Home.md') return { type: 'root', color: '#f59e0b' };
if (filePath.startsWith('References/')) return { type: 'source' };
return { type: 'category' };
}
export const views = [
{
// Overrides the built-in Default view for this vault.
name: 'Default',
settings: {
chargeStrength: -300,
linkParticles: 3,
hiddenNodeTypes: ['source'],
},
},
{
name: 'Sources only',
settings: {
hiddenNodeTypes: ['root', 'category'],
chargeStrength: -180,
},
},
];Wikilinks are extracted from the body of each file (frontmatter is skipped). A tag:: [[Target]] prefix assigns a named relationship type to the link; bare [[Target]] links receive the tag link.
down:: [[Child Note]]
cite:: [[Sources/@smith2023]]
[[Related Concept]]scrymap/
├── examples/
│ └── sample-vault/ # Small demo vault you can run locally
├── scripts/
│ ├── generate-data.ts # Vault walker & graph.json generator
│ └── dev-server.ts # Vite dev server + chokidar watcher + WebSocket broadcaster
├── src/
│ ├── main.ts # Application entry point, wires all modules together
│ ├── graph.ts # ForceGraph wrapper (rendering, filters, selection)
│ ├── viewer.ts # Inline Markdown note viewer
│ ├── ui.ts # Controls panel, views list, color chips
│ ├── settings.ts # LocalStorage persistence for settings and views
│ ├── types.ts # Shared TypeScript types (GraphNode, GraphLink, GraphData, …)
│ └── style.css # All styles
├── public/ # Static assets (graph.json written here at build/dev time)
├── index.html
├── vite.config.ts
└── package.json
MIT
