linkrot
v0.1.0
Published
Find broken links and orphan pages in a folder of markdown — for docs sites, ADRs, and Obsidian-style vaults.
Maintainers
Readme
linkrot
Find broken links and orphan pages in a folder of markdown — docs sites, ADR directories, wikis, or an Obsidian vault. One command, no config, no network, zero runtime dependencies.
$ npx linkrot ./docs
linkrot — 42 markdown files scanned
links: 118 total, 115 resolved, 3 broken
orphans (nothing links to them): 4
Broken links (3):
✗ guides/setup.md:12 → ./instal.md [missing file]
✗ api/index.md:30 → ../reference/v2.md [missing file]
✗ notes/ideas.md:5 → Old Roadmap [no note matches]
Orphans (4):
• drafts/scratch.md (isolated)
• archive/2019.md
...It exits non-zero when it finds a problem, so it drops straight into CI to keep a docs folder honest as it grows.
Why
Docs rot. Files get renamed, notes get deleted, and the links pointing at them go quietly stale. linkrot is the smallest possible tool that catches that: point it at a directory, get the broken links and the pages nothing connects to.
Install
npm install -g linkrot
# or run without installing:
npx linkrot ./your-docs
bunx linkrot ./your-docsRequires Node.js 18+ (or Bun).
Usage
linkrot [dir] [options]
dir directory to scan (default: current directory)
--json print the full link graph as JSON
--html <file> write a self-contained interactive graph viewer
--images treat image links as edges (also checks image paths)
--no-orphans report/fail on broken links only, ignore orphans
--quiet no output on success (for CI)
-h, --help show helpWhat it understands
| Link form | Example | Resolution |
|-----------|---------|------------|
| Inline | [text](./other.md) | relative to the file; .md is inferred if omitted |
| Image |  | only with --images |
| Wikilink | [[Other Note]] / [[Note\|alias]] | by note name, Obsidian-style |
| Directory | [logs](./logs/) | valid if the folder exists |
It deliberately ignores: external URLs (http, mailto, //cdn…), in-page
anchors (#section), and anything inside fenced or inline code spans.
Interactive graph
npx linkrot ./docs --html graph.htmlwrites a single self-contained HTML file — a force-directed map of your documents with broken links and orphans listed alongside. No build step, no CDN, open it in any browser.
Use in CI
- run: npx linkrot ./docs --quiet --no-orphansFails the job the moment a doc link points at nothing.
Programmatic API
import { loadDir, listDirs, buildGraph, formatReport } from 'linkrot';
const files = loadDir('./docs');
const graph = buildGraph(files, { knownDirs: listDirs('./docs') });
console.log(formatReport(graph));
console.log(graph.broken); // [{ from, target, line, kind, reason }]
console.log(graph.orphans); // GraphNode[]The parse and graph layers are pure functions with no filesystem access, so they are easy to test and embed.
License
MIT.
