DEV Community

Haider Ali
Haider Ali

Posted on

Broken links in docs are silent. This Python CLI names the broken kind.

You update a docs page, move a file, rename a heading. Nothing breaks loudly. A reader clicks a link weeks later and lands on a 404 — or worse, on the right page with the wrong anchor, staring at the top while the section they wanted is three screens down.

Most link checkers give you one word: broken. This one tells you which kind of broken, because the fix is different.

broken-link-checker-cli is a Python CLI. Standard library only. It scans .md, .markdown and .html files, checks every link for real, and reports each link as one of three things:

  • OK — the page exists, and the anchor on it exists too.
  • BROKEN (page) — the page itself is missing.
  • BROKEN (anchor) — the page exists, the anchor on it does not.

A link is never reported OK unless its check actually ran. If an anchor cannot be checked (a PDF, for example), the link is reported SKIPPED with the reason — never silently OK. Links inside fenced code blocks and inline code are ignored, so code samples never produce false failures. mailto: and tel: links are skipped, not flagged.

Try it

pip install broken-link-checker-cli
Enter fullscreen mode Exit fullscreen mode

Point it at your docs folder:

broken-link-checker docs/
Enter fullscreen mode Exit fullscreen mode

The repo ships with an examples/ folder you can try first — one link in there is deliberately broken:

git clone https://github.com/haiderstudio/broken-link-checker-cli.git
cd broken-link-checker-cli
broken-link-checker examples/
Enter fullscreen mode Exit fullscreen mode

Real output:

examples/sample-docs.md:3: other-page.md -> OK
examples/sample-docs.md:5: #sample-docs -> OK
examples/sample-docs.md:8: missing-page.md -> BROKEN (page) (file does not exist)
2 ok, 1 broken, 0 skipped
Enter fullscreen mode Exit fullscreen mode

Remote links are checked with HEAD, falling back to GET where a server refuses HEAD. If a remote link has an anchor, the fetched page must carry that id or name.

Useful flags

# Local files only — works fully offline
broken-link-checker --local-only docs/

# Machine-readable output for CI
broken-link-checker --format json docs/

# Skip URLs matching a pattern (repeatable)
broken-link-checker --exclude 'example\.com' docs/
Enter fullscreen mode Exit fullscreen mode

Exit code 0 means no broken links, 1 means at least one broken link, 2 means a usage error such as a missing path — so it drops straight into CI as a gate.

What it does not do

It does not rewrite any file, follow JavaScript-rendered pages, or log in anywhere. It only reads and reports. It does not send your docs anywhere — remote checks are plain requests to the linked URL itself.

I built it because every docs check I tried either needed a service, a Node install, or reported "broken" without saying which part was broken. This one is one file, stdlib only, and the output tells you exactly what to fix.

The repo is MIT licensed: https://github.com/haiderstudio/broken-link-checker-cli

If it catches a broken link in your docs, a star helps other people find it.

Top comments (0)