Markdown documentation toolkit - Work with your documentation as a connected system, not scattered files.
mdite treats your markdown documentation as a cohesive whole. Map dependencies, validate structure, search across files, and pipe content—all while understanding how your docs connect together.
Most tools treat markdown files as isolated documents. mdite treats them as a connected system.
- 📄 Edit files one at a time
- 🔍 grep individual files, hope you find everything
- 🤷 No idea what's connected to what
- 💥 Break things when refactoring
- 🗑️ Afraid to delete anything
- 🕸️ See the whole system - Your docs are a graph, visualize it
- 🔍 Search the system - Query across all connected docs
- 📊 Understand dependencies - Know what links to what
- ✅ Validate structure - Catch broken links and orphans
- 🎯 Work confidently - Refactor and clean up without fear
mdite is a toolkit for working with markdown documentation as a unified system:
# See what connects to what
mdite deps docs/api.md --incoming
# Understand your doc structure
mdite deps README.md --format tree# Catch broken links and orphans
mdite lint
# CI/CD integration
mdite lint --format json# List all reachable files
mdite files
# Filter by depth
mdite files --depth 2
# Search with ripgrep (Unix composition)
mdite files | xargs rg "authentication"
# Filter by frontmatter and process
mdite files --frontmatter "status=='published'" | xargs prettier --write# Output entire doc system
mdite cat | less
# Pipe to shell tools
mdite cat docs/api/*.md | grep "function"
# Combine with other tools
mdite cat --order deps | pandoc -o book.pdfThe key: mdite understands how your docs connect, so it can treat them as a unified system.
Note: mdite will be published to npm with the first release. Once published, install via:
npm install -g mditeFor now, you can clone and build from source:
git clone https://github.com/radleta/mdite.git && cd mdite && npm install && npm run build && npm link
# Map the structure
mdite deps README.md
# What references this file?
mdite deps docs/api.md --incoming
# What does this file reference?
mdite deps docs/guide.md --outgoingUse case: Before changing anything, understand the impact.
# Check for issues
mdite lint
# Find orphaned files
mdite lint --verbose
# CI/CD integration
mdite lint --format jsonUse case: Catch broken links and structural issues.
# Create custom config
mdite init
# See merged config
mdite configUse case: Customize for your project's needs.
mdite builds a complete dependency graph of your documentation starting from an entrypoint (usually README.md), following all internal links.
Why this matters: You can see exactly how your docs connect. No more guessing about structure or dependencies.
mdite deps README.md
# Output:
# README.md
# ├── docs/getting-started.md
# │ ├── docs/installation.md
# │ └── docs/configuration.md
# ├── docs/api-reference.md
# └── docs/guides/This graph is the foundation for everything mdite does - validation, analysis, search, export.
Understand what connects to what before making changes:
# Impact analysis: What will break if I change this?
mdite deps docs/api.md --incoming
# Shows: README.md, guide.md, tutorial.md all reference it
# Scope analysis: What does this file depend on?
mdite deps docs/guide.md --outgoing
# Shows: Links to setup.md, api.md, troubleshooting.mdReal-world use cases:
- 🔧 Refactoring: Know the impact before renaming/moving files
- 🧹 Cleanup: Find files that nothing depends on (safe to delete)
- 📖 Documentation: Understand your doc structure
- 🎯 Navigation: Find central hub documents
Catch issues before they reach users:
Orphan Detection: Find markdown files that aren't linked from anywhere—dead weight in your repo.
mdite lint
# ✗ Found 3 orphaned files:
# - old-guide.md
# - deprecated-api.md
# - scratch-notes.mdLink Validation: Validates three types of links:
- File links:
[guide](./setup.md)→ validates file exists - Anchor links:
[intro](#getting-started)→ validates heading exists - Cross-file anchors:
[api](./api.md#methods)→ validates both
Benefit: Zero 404s in your documentation.
Because mdite understands your docs as a system, it can do things other tools can't:
Export the system:
# Output entire doc system in dependency order
mdite cat --order deps
# Output in alphabetical order
mdite cat --order alpha
# Pipe to shell tools
mdite cat | grep -n "TODO"
mdite cat | wc -l # Total lines in doc system
# Export as single file
mdite cat --order deps | pandoc -o documentation.pdf
# JSON format with metadata
mdite cat --format json | jq '.[] | {file, wordCount}'Coming Soon:
⚠️ Note: The following features are planned but not yet implemented. They are shown here to illustrate the project's vision.
Search across the system:
# FUTURE FEATURE - not yet available
# Find all docs mentioning "authentication"
mdite query "authentication" --content
# Find docs matching name pattern
mdite query "api-*" --names
# Search in a specific section of the graph
mdite query "config" --from docs/reference/Transform the system:
# FUTURE FEATURE - not yet available
# Generate table of contents from graph
mdite toc --depth 2
# Validate external links (HTTP/HTTPS)
mdite lint --externalYou have 50 markdown files that form a cohesive documentation site, but:
- ❌ You edit them one at a time (disconnected)
- ❌ You search them one at a time (
grep file1.md,grep file2.md...) - ❌ You have no idea how they connect
- ❌ Refactoring is terrifying (what will break?)
- ❌ You don't know what's safe to delete
mdite solves this by treating your docs as a connected graph.
| Capability | Traditional Tools | mdite |
|---|---|---|
| Link validation | ❌ Can't detect broken links | ✅ Validates all internal links |
| Orphan detection | ❌ No concept of reachability | ✅ Finds unreachable files |
| Dependency analysis | ❌ No understanding of structure | ✅ Maps entire graph |
| System-wide search | ❌ Search files individually | ✅ Query the whole system |
| Structural operations | ❌ File-by-file only | ✅ Operates on connected docs |
markdownlint / remark-lint:
- ✅ Check style (formatting, syntax)
- ❌ Don't understand document relationships
- ❌ Can't detect orphaned files
- ❌ Miss structural issues
- ❌ File-centric, not system-centric
mdite:
- ✅ Validates structure and relationships
- ✅ Detects orphaned files
- ✅ Maps dependencies
- ✅ System-centric operations
- ✅ Understands your docs as a connected whole
Use both: Traditional linters for style, mdite for structure and system operations.
# Step 1: Understand the impact
mdite deps docs/old-api.md --incoming
# Shows: README.md, tutorial.md, guide.md reference it
# Step 2: Rename the file
mv docs/old-api.md docs/api-reference.md
# Step 3: Update the 3 files that link to it
# Step 4: Validate
mdite lint
# ✅ All links validBenefit: Refactor with confidence, not fear.
# Find orphaned files
mdite lint
# ✗ Found 5 orphaned files
# Review each one
mdite deps old-guide.md --incoming
# Shows: nothing links to it
# Safe to delete!
rm old-guide.md deprecated-api.md scratch-notes.md
# Verify
mdite lint
# ✅ All clean, only connected docs remainBenefit: Clean repos, confident deletions.
# Validate structure
mdite lint
# Check for orphans (incomplete docs)
mdite lint --verbose | grep "orphan"
# Verify all API docs are reachable
mdite deps README.md --format list | grep "api"
# Green light to release
mdite lint --format json
# Exit code 0 = ship itBenefit: Never ship broken documentation.
# Start at the entry point
mdite deps README.md --depth 1
# Shows: Top-level structure
# Explore a section
mdite deps docs/architecture.md
# Shows: What it connects to
# Find all API docs
mdite deps README.md --format list | grep api
# Lists all API documentation filesBenefit: Quickly understand documentation structure.
# .github/workflows/docs.yml
name: Documentation Quality
on: [pull_request]
jobs:
validate-docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install -g mdite
- run: mdite lint --format json
# Fails if broken links or orphans detectedBenefit: Documentation quality is enforced, not hoped for.
# Find all files with broken links
mdite lint | grep "Dead link" | cut -d: -f1 | sort | uniq
# Count errors by type
mdite lint | grep -o "\\[.*\\]" | sort | uniq -c
# Get JSON summary with jq
mdite lint --format json | jq '[.[] | .severity] | group_by(.) | map({severity: .[0], count: length})'
# List all orphaned files
mdite lint --format json | jq -r '.[] | select(.rule=="orphan-files") | .file'
# Check if specific file has errors
mdite lint | grep "docs/api.md" && echo "API docs need fixing"
# Quiet mode for scripting (no progress messages)
ERRORS=$(mdite lint --quiet 2>/dev/null)
if [ -n "$ERRORS" ]; then
echo "$ERRORS" | mail -s "Doc errors" [email protected]
fi
# Analyze dependencies
mdite deps README.md --format json | jq '.stats.totalFiles'
# Find deeply nested docs
mdite deps README.md --format json | jq '.outgoing[] | select(.depth > 3) | .file'
# Export dependency graph as CSV
mdite deps README.md --format json | jq -r '.outgoing[] | [.file, .depth] | @csv'Benefit: Full integration with Unix ecosystem (grep, jq, awk, sed, mail, etc.)
# Find all dead links with literal paths (grep format)
mdite lint --format grep > dead-links.tsv
# Extract just the literal link text (field 7)
mdite lint --format grep | cut -d$'\t' -f7
# Extract file, line, and literal for manual fixing
mdite lint --format grep | awk -F'\t' '{print $1 ":" $2 " → " $7}'
# Automated fix workflow example
mdite lint --format grep | while IFS=$'\t' read file line col endCol severity rule literal resolved; do
if [ "$rule" = "dead-link" ]; then
echo "Fix: $file:$line - Replace '$literal' with correct path"
# Add your automated fix logic here (sed, etc.)
fi
done
# Extract broken links by file
mdite lint --format grep | awk -F'\t' '$6=="dead-link" {print $1, $7}' | sort
# Count broken links by type
mdite lint --format grep | cut -d$'\t' -f6 | sort | uniq -cBenefit: Automated fix scripts can locate and replace broken links using exact text from source files, no path reverse-engineering needed.
# Start with core docs only
mdite lint --depth 1
# Gradually expand validation
mdite lint --depth 2
mdite lint --depth 3
# Finally, full validation
mdite lintBenefit: Incremental adoption of mdite in large doc repos, validate core docs first.
These options work with all commands:
--config <path>- Path to custom config file--colors- Force colored output (even when piped)--no-colors- Disable colored output-q, --quiet- Quiet mode (suppress informational output, show only data/errors)--verbose- Enable verbose/debug output-V, --version- Output the version number-h, --help- Display help for command
Usage:
# Use verbose mode with any command
mdite lint --verbose
mdite deps README.md --verbose
# Quiet mode for scripting (only data/errors, no info messages)
mdite lint --quiet
mdite deps README.md --quiet --format json | jq '.stats'
# Use custom config with any command
mdite lint --config custom-config.js
mdite init --config .mditerc.json
# Control colors
mdite lint --no-colors # Disable colors
mdite lint --colors | less -R # Force colors even when pipedColor Detection:
mdite automatically detects whether colors should be used:
- Auto-enabled when output is a terminal (TTY)
- Auto-disabled when piped to other tools
- Force with
--colorsto override detection - Disable with
--no-colorsorNO_COLOR=1env var
Environment Variables:
NO_COLOR- Disable colors (respects no-color.org standard)FORCE_COLOR- Force colors even when not a TTYCI=true- Disables colors in CI environments (unlessFORCE_COLORis set)
Visualize and analyze documentation structure.
# Tree view of dependencies
mdite deps README.md
# What references this file? (incoming)
mdite deps docs/api.md --incoming
# What does this file reference? (outgoing)
mdite deps docs/guide.md --outgoing
# Limit depth
mdite deps README.md --depth 2
# JSON output for tooling
mdite deps docs/api.md --format json
# List format
mdite deps README.md --format listOptions:
--incoming- Show what references this file--outgoing- Show what this file references--depth <n>- Limit traversal depth--format <type>- Output:tree(default),list, orjson
Use cases:
- 🔍 Impact analysis before refactoring
- 🧹 Finding safe-to-delete files
- 📊 Understanding documentation structure
- 🎯 Identifying central hub documents
Check documentation for structural issues.
# Lint from current directory
mdite lint
# Lint specific directory
mdite lint ./docs
# JSON output for CI/CD (auto-disables colors)
mdite lint --format json
# Grep format for automated fixes (tab-delimited)
mdite lint --format grep
# Extract all literal paths
mdite lint --format grep | cut -d$'\t' -f7
# Extract file and literal for processing
mdite lint --format grep | awk -F'\t' '{print $1, $7}'
# Pipe JSON to jq for analysis
mdite lint --format json | jq '.[] | select(.severity=="error")'
# Quiet mode for scripting (only errors shown)
mdite lint --quiet
# Verbose output (shows debug info to stderr)
mdite lint --verbose
# NEW: Lint multiple files as entry points
mdite lint README.md docs/api.md docs/guide.md --depth 1
# Perfect for pre-commit hooks (lint only changed files)
CHANGED=$(git diff --cached --name-only --diff-filter=ACM | grep '\.md$')
mdite lint $CHANGED --depth 1Lint multiple specific files as independent entry points:
# Lint multiple entry points
mdite lint core/api.md core/cli.md core/config.md
# Each file starts at depth 0
# Results are merged and deduplicated
# Orphans = files not reachable from ANY entry pointUse Cases:
- Pre-commit hooks: Lint only changed markdown files
- Selective validation: Check specific docs without full traversal
- CI/CD: Parallel validation of independent sections
- Author workflow: Work on multiple related docs
Example:
# Pre-commit: validate changed files and their immediate links
mdite lint $(git diff --cached --name-only | grep '\.md$') --depth 1Options:
--format <type>- Output:text(default),json, orgrep--entrypoint <file>- Entrypoint file (overrides config, cannot be used with multiple files)--depth <n>- Maximum depth of traversal (default: unlimited, applies to all files)-q, --quiet- Suppress informational output (only show errors)
Global options (apply to all commands):
--config <path>- Custom config file--no-colors- Disable colored output--verbose- Detailed output
Output Streams:
- stdout - Validation results (errors, warnings)
- stderr - Informational messages (progress, summaries)
This separation makes mdite pipe-friendly:
# Grep for specific errors
mdite lint | grep "Dead link"
# Count errors
mdite lint | wc -l
# Process JSON with jq
mdite lint --format json | jq '.[] | .file' | sort | uniq
# Suppress progress messages, keep only errors
mdite lint 2>/dev/nullWhat it validates:
- ✅ All files reachable from entrypoint
- ✅ No orphaned files
- ✅ All file links are valid
- ✅ All anchor references exist
- ✅ No broken cross-file anchor links
Output documentation content in various formats and orderings.
# Output all files in dependency order (default)
mdite cat
# Output in alphabetical order
mdite cat --order alpha
# Use custom separator between files
mdite cat --separator "\\n---\\n"
# Output as JSON with metadata
mdite cat --format json
# Pipe to other tools
mdite cat | grep "TODO"
mdite cat | wc -l
# Export as single file
mdite cat --order deps | pandoc -o docs.pdf
# Combine with jq for analysis
mdite cat --format json | jq '.[] | {file, wordCount}'Options:
[files...]- Specific files to output (optional, defaults to all files in graph)--order <type>- Output order:deps(dependency order, default) oralpha(alphabetical)--separator <text>- Text between files (default:\n\n). Supports escape sequences like\n,\t--format <type>- Output format:markdown(default) orjson--exclude <pattern...>- Exclude file patterns (gitignore-style)--respect-gitignore- Respect .gitignore patterns--no-exclude-hidden- Don't exclude hidden directories
Output Formats:
Markdown (default):
- Outputs raw file content concatenated with separators
- Perfect for piping to other tools
- Streams to stdout for efficiency
JSON:
- Structured output with metadata for each file
- Includes: file path, depth, content, word count, line count
- Ideal for programmatic processing
Use cases:
- 📤 Export: Create single-file documentation artifacts
- 🔄 Transform: Pipe to pandoc, markdown processors, or custom tools
- 📊 Analyze: Extract statistics, search patterns, or validate content
- 🎯 Integration: Build documentation pipelines and workflows
Examples:
# Generate PDF documentation
mdite cat --order deps | pandoc --toc -o documentation.pdf
# Count total words in documentation
mdite cat | wc -w
# Find all TODOs across documentation
mdite cat | grep -n "TODO"
# Get statistics from JSON
mdite cat --format json | jq '[.[] | .wordCount] | add'
# Extract code blocks
mdite cat | awk '/```/,/```/'Unix Philosophy Approach: mdite provides graph-filtered file lists that compose with the Unix ecosystem.
# List all reachable files
mdite files
# Filter by depth
mdite files --depth 2
# List orphaned files only
mdite files --orphans
# Output absolute paths
mdite files --absolute
# Filter by frontmatter metadata (JMESPath query)
mdite files --frontmatter "status=='published'"
mdite files --frontmatter "contains(tags, 'api')"
# JSON output with metadata
mdite files --format json
# Annotate with depth information
mdite files --with-depth
# Null-separated for xargs -0
mdite files --print0 | xargs -0 ls -l
# Sort by depth, incoming, outgoing links, or alphabetically
mdite files --sort depth
mdite files --sort incoming
mdite files --sort outgoing
mdite files --sort alpha # defaultUnix Composition (The Power of Files):
The files command is designed to compose with standard Unix tools via pipes:
# Search with ripgrep (graph-filtered search)
mdite files --depth 2 | xargs rg "authentication" -C 2
# Update published docs only
mdite files --frontmatter "status=='published'" | xargs sed -i 's/v1/v2/g'
# Lint reachable docs
mdite files | xargs markdownlint
mdite files | xargs prettier --write
# Generate stats
mdite files | xargs wc -w | tail -1 # Total words
# Archive orphaned files
mdite files --orphans | xargs -I {} mv {} archive/
# Complex pipeline: find API docs, extract code blocks, count languages
mdite files --frontmatter "contains(tags, 'api')" | \
xargs rg '```(\w+)' -o -r '$1' | \
sort | uniq -c | sort -rn
# Custom processing
mdite files | xargs ./my-script.shOptions:
--depth <n>- Limit to files at depth N or less (default: unlimited)--orphans- List only orphaned files--no-orphans- Exclude orphaned files (default)--absolute- Output absolute paths (default: relative)--frontmatter <query>- Filter by frontmatter metadata (JMESPath query)--format <type>- Output format:list(default) orjson--with-depth- Annotate output with depth information (list format only)--print0- Use null character as separator (forxargs -0)--sort <type>- Sort by:alpha(default),depth,incoming,outgoing--exclude <pattern...>- Exclude file patterns (gitignore-style)--respect-gitignore- Respect .gitignore patterns--no-exclude-hidden- Don't exclude hidden directories
Why files instead of query?
Following Unix philosophy, mdite focuses on what it does best: graph operations. Instead of reimplementing search (ripgrep is better), mdite provides graph-filtered file lists that compose with ANY tool:
- ✅ Use ripgrep for search - It's faster and more feature-rich
- ✅ Use sed/awk for transformation - They're mature and powerful
- ✅ Use custom scripts - Unlimited flexibility
- ✅ Infinite combinations - Not locked into mdite's features
Use cases:
- 🔍 Graph-aware search - Filter files by graph/metadata, search with ripgrep
- 🔄 Bulk operations - Process graph-filtered files with any tool
- 📊 Metadata filtering - JMESPath queries on frontmatter combined with graph
- 🧹 Cleanup - Find and archive orphaned files
- 🎯 Targeted operations - Work on specific subsets of your documentation
Create a configuration file.
# Create default config file (mdite.config.js)
mdite init
# Create config file with custom path
mdite init --config .mditerc.jsonOptions:
--config <path>- Config file path (default:mdite.config.js)
Display or explore mdite configuration.
# View current merged configuration
mdite config
# View all available options
mdite config --schema
# Learn about specific option
mdite config --explain maxConcurrency
# Generate comprehensive template
mdite config --template > mdite.config.js
# See where each value comes from (Phase 2 - not yet implemented)
mdite config --sourcesOptions:
--schema- Display all configuration options with descriptions, types, defaults--explain <key>- Show detailed explanation of a specific option--template- Generate comprehensive config template--sources- Show which layer provides each value (planned for Phase 2)--format <type>- Output format:text(default),json,js,yaml,md
Use cases:
- 🔍 Discover options: See what's configurable without leaving terminal
- 📖 Learn about options: Get detailed help for specific configuration keys
- 🎯 Generate templates: Create well-documented config files quickly
- 🐛 Debug config: Understand where values come from (planned)
⚠️ Note: These commands are planned for future releases and are not yet available.
Coming soon as mdite expands:
# FUTURE FEATURE - not yet available
# Generate TOC from graph
mdite toc --depth 2# FUTURE FEATURE - not yet available
# Analyze documentation metrics
mdite stats --depth 2mdite works out of the box:
mdite lint # Just works
mdite deps README.md # Just worksDefaults:
- Entrypoint:
README.md - All rules:
error - Output: colored text
mdite provides built-in help for configuration:
# See all available options
mdite config --schema
# Learn about specific option
mdite config --explain maxConcurrency
# Generate comprehensive template
mdite config --template > mdite.config.jsAll configuration options are self-documented - no need to search docs!
Create mdite.config.js for project-specific settings:
module.exports = {
// Start traversal from a different file
entrypoint: 'docs/index.md',
// Customize rule severity
rules: {
'orphan-files': 'error', // Block build on orphans
'dead-link': 'error', // Block build on broken links
'dead-anchor': 'warn', // Warn but don't block
},
};| Format | File | Use Case |
|---|---|---|
| JavaScript | mdite.config.js |
Comments, computed values |
| JSON | .mditerc |
Simple, no comments |
| YAML | .mditerc.yaml |
Human-readable, comments |
| package.json | "mdite": {} |
Keep config in one place |
Priority: CLI flags > Project config > Defaults
See examples/06-config-variations for working examples.
| Rule | What It Detects | Default |
|---|---|---|
orphan-files |
Files unreachable from entrypoint | error |
dead-link |
Broken relative file links | error |
dead-anchor |
Broken #heading references |
error |
Severity levels:
error- Fail (exit code 1)warn- Show warning, don't failoff- Disable rule
mdite follows Unix conventions for exit codes:
| Code | Meaning | When |
|---|---|---|
0 |
Success | No validation errors found |
1 |
Validation Error | Orphaned files, broken links, or validation failures |
2 |
Usage Error | Invalid arguments, unknown options, or configuration errors |
130 |
Interrupted | Process interrupted (Ctrl+C, SIGINT, SIGTERM) |
Usage in scripts:
# Check exit code
if mdite lint; then
echo "Documentation is valid"
else
echo "Documentation has errors"
exit 1
fi
# CI/CD pipeline
mdite lint --format json || exit 1
# Conditional logic
mdite lint && npm run deploy
# Capture exit code
mdite lint
EXIT_CODE=$?
if [ $EXIT_CODE -eq 1 ]; then
echo "Validation errors found"
elif [ $EXIT_CODE -eq 2 ]; then
echo "Usage error - check your command"
fiSignal Handling:
mdite gracefully handles Unix signals:
- SIGINT (Ctrl+C) - Clean exit with code 130
- SIGTERM - Clean exit with code 130
- SIGPIPE - Gracefully exits when pipe is closed (e.g.,
mdite lint | head)
mdite
──────────────────────────────────────────────────
ℹ Linting: ./docs
ℹ Entrypoint: README.md
ℹ Building dependency graph...
✓ Found 24 reachable files
ℹ Checking for orphaned files...
✗ Found 3 orphaned files
ℹ Validating links...
✗ Found 2 link errors
Found 5 issue(s)
──────────────────────────────────────────────────
docs/old-guide.md
- error Orphaned file: not reachable from entrypoint [orphan-files]
docs/setup.md
7:3 error Dead link: installation.md [dead-link]
✗ 5 error(s), 0 warning(s)
$ mdite deps README.md --depth 2
Dependencies for README.md
──────────────────────────────────────────────────
Outgoing (what this file references):
├── docs/getting-started.md
│ ├── docs/installation.md
│ └── docs/configuration.md
├── docs/api-reference.md
│ ├── docs/api/methods.md
│ └── docs/api/types.md
└── CONTRIBUTING.md
Incoming (what references this file):
(none - this is the entrypoint)
Cycles detected: 0The examples/ directory contains 12 runnable demonstrations (68 files) showing mdite in action:
# Valid documentation
cd examples/01-valid-docs && mdite lint
# Orphan detection
cd examples/02-orphan-files && mdite lint
# Broken links
cd examples/03-broken-links && mdite lint
# Dependency analysis
cd examples/01-valid-docs && mdite deps README.mdRun all examples:
cd examples && ./run-all-examples.shSee examples/README.md for complete documentation.
mdite treats your documentation as a directed graph:
- Nodes: Markdown files
- Edges: Links between files
- Root: Entrypoint file (default:
README.md)
README.md (root)
├─→ docs/guide.md
│ ├─→ docs/setup.md
│ └─→ docs/api.md
└─→ CONTRIBUTING.md
└─→ docs/development.md
- Start at entrypoint (
README.md) - Parse markdown to extract links
- Follow each relative
.mdlink - Recursively build graph (with cycle detection)
- Result: Complete map of connected documentation
What gets included:
- ✅ Relative links:
[guide](./setup.md) - ✅ Links with anchors:
[api](./api.md#methods) - ✅ Anchor-only:
[intro](#getting-started)
What gets skipped:
- ❌ External URLs:
https://example.com - ❌ Absolute paths outside project
- ❌ Non-markdown files
Once the graph is built, mdite can:
- Detect orphans: Files NOT in the graph
- Validate links: Check edges point to existing nodes
- Analyze dependencies: Traverse graph in any direction
- Future: Query, search, export the graph
This graph foundation enables all current and future mdite features.
mdite is evolving from a linter into a complete documentation toolkit.
- Graph-based dependency analysis (
deps) - Structural validation (
lint) - Orphan detection
- Link validation (file + anchor)
- Configuration system
- Content output (
cat) - Export documentation content- Dependency-order and alphabetical output
- JSON format with metadata
- Pipe-friendly for Unix workflows
⚠️ Note: These features are planned for future releases and are not yet implemented.
mdite query- Search across documentation system- Content search
- Filename pattern matching
- Scope to graph sections
mdite toc- Generate table of contents from graphmdite stats- Documentation metrics and analysis- External link validation - Check HTTP/HTTPS URLs
- Watch mode - Auto-validate on file changes
- LSP server - Editor integration
- Custom rule API - Write your own validation rules
- Export formats - PDF, HTML, etc. with graph awareness
The vision: A complete toolkit for working with markdown documentation as a unified, connected system.
{
"husky": {
"hooks": {
"pre-commit": "mdite lint"
}
}
}name: Documentation
on:
pull_request:
paths:
- 'docs/**'
- '*.md'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install -g mdite
- run: mdite lint --format json{
"scripts": {
"docs:lint": "mdite lint",
"docs:deps": "mdite deps README.md",
"docs:check": "mdite lint && echo '✓ Documentation valid'",
"predeploy": "mdite lint"
}
}mdite is evolving rapidly. Contributions welcome!
See CONTRIBUTING.md for:
- Development setup
- Testing guidelines
- Pull request process
- Roadmap and feature ideas
MIT © 2025 Richard Adleta
mdite (markdown documentation toolkit) is built for developers and teams who work with interconnected markdown documentation.
Born from the frustration of broken docs and the realization that documentation is a system, not a collection of files, mdite provides the tools to work with that system effectively.
Built with:
Issues & Ideas: GitHub Issues
Work with your documentation as a system, not scattered files.
npm install -g mdite
mdite deps README.md # Understand structure
mdite lint # Validate integrity