Generate a graph JSON from a markdown repository with real-time file watching capabilities. This TypeScript library parses markdown files and creates a graph structure where each markdown file becomes a node, with wiki-style links between documents. This graph JSON can be used by the Graph Gizmo to provide a visualisation of the graph.
- 📝 Parse markdown files with frontmatter support
- 🔗 Generate graph JSON from markdown repositories
- 📊 Graph interface from
@adaptivekind/graph-schema - 🎯 CLI tool for generating graphs from directories
- 👀 File watching with real-time graph updates
- ⚡ Incremental updates for efficient performance
- 🛠️ TypeScript support with strict type checking
npm install @adaptivekind/markdown-graphThe package provides a CLI tool for generating graphs from markdown directories:
# Generate graph from current directory
npx markdown-graph
# Generate graph from specific directory
npx markdown-graph ./docs
# Generate graph with custom output file
npx markdown-graph ./docs -o ./output/graph.json
# Generate with verbose output
npx markdown-graph ./docs --verbose# Watch current directory for changes
npx markdown-graph watch
# Watch specific directory with verbose output
npx markdown-graph watch ./docs --verbose
# Watch with custom debounce delay
npx markdown-graph watch ./docs --debounce 500| Option | Description | Default |
|---|---|---|
--output, -o |
Output file path | .garden-graph.json |
--verbose, -v |
Enable verbose logging | false |
--quiet, -q |
Suppress all output except errors | false |
--exclude |
Patterns to exclude from scanning | ["node_modules", "dist", ".git"] |
--include-hidden |
Include hidden files and directories | false |
--debounce |
Debounce delay for file changes (ms) | 300 |
import { createGarden } from "@adaptivekind/markdown-graph";
const garden = await createGarden({
type: "inmemory",
content: {
"file1.md": "# Content\n\nThis links to [[file2]]",
"file2.md": "# More Content\n\nThis links back to [[file1]]",
},
});
console.log(garden.graph.nodes);
console.log(garden.graph.links);import { createGarden } from "@adaptivekind/markdown-graph";
const garden = await createGarden({
type: "file",
path: "./docs",
excludes: ["node_modules", "dist"],
includeHidden: false,
});
console.log(garden.graph.nodes);
console.log(garden.graph.links);import { GraphWatcher } from "@adaptivekind/markdown-graph";
const watcher = new GraphWatcher({
targetDirectory: "./docs",
outputFile: "./graph.json",
verbose: true,
debounceMs: 300,
});
// Listen for events
watcher.on("initialized", (stats) => {
console.log(`Graph initialized with ${stats.nodeCount} nodes`);
});
watcher.on("fileChanged", (data) => {
console.log(`File ${data.changeType}: ${data.filePath}`);
});
watcher.on("graphWritten", (data) => {
console.log(`Graph written to ${data.outputFile}`);
});
// Start watching
await watcher.start();The tool supports configuration via:
.markdown-graph.jsonmarkdown-graph.config.jsonpackage.json(in"markdown-graph"field)
Example configuration:
{
"targetDirectory": "./docs",
"outputFile": "./graph.json",
"verbose": false,
"quiet": false,
"excludes": ["node_modules", "dist", ".git"],
"includeHidden": false
}NODE_ENV=test- Disables CLI execution during testing
The library supports multiple link formats:
This is a [[wiki link]] to another document.This is a [relative link](./other-document.md) to another document.This links to a [[document#section]] in another document.The library supports YAML frontmatter in markdown files:
---
tags: [project, documentation]
author: John Doe
created: 2024-01-01
---
# Document Title
Your markdown content here with [[links]] to other documents.Frontmatter data is flattened and included in the graph nodes as metadata.
The generated graph follows the @adaptivekind/graph-schema format:
interface Graph {
nodes: {
[nodeId: string]: {
label: string;
meta?: { [key: string]: string };
};
};
links: Array<{
source: string;
target: string;
}>;
}- Root sections (h1 headings): Use document ID directly
- Subsections: Use format
documentId#section-title - Document IDs: Normalized from filename (lowercase, dashes for spaces/slashes)
- Node.js 22.x
- npm 10.x
git clone https://github.com/adaptivekind/markdown-graph.git
cd markdown-graph
npm install# Development
npm run build # Build the project
npm run build:watch # Build in watch mode
# Testing
npm test # Run tests once
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage report
# Code Quality
npm run lint # Run linting (prettier + eslint + sonarjs)
npm run lint:fix # Fix linting issues automatically
npm run knip # Check for unused dependencies
# Demo
npm run demo:setup # Set up demo environment
npm run demo:generate # Generate graph from demo docs
npm run demo:watch # Watch demo docs for changes
npm run demo:test # Test file changes in demo
npm run demo:clean # Clean up demo filesRun tests with:
npm test # Run all tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Generate coverage report- DirectoryNotFoundError: When target directory doesn't exist
- FileNotFoundError: When referenced files are missing
- MarkdownParsingError: When markdown parsing fails
- RepositoryConfigurationError: When configuration is invalid
All errors include helpful suggestions for resolution.
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Ensure all tests pass and linting is clean
- Submit a pull request
MIT © Ian Homer