Skip to content

jjdoor/linkbust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

linkbust

Find broken local links in your Markdown β€” relative file paths that don't exist and #anchors that don't resolve to a heading. No network, zero dependencies, fast enough to drop in a pre-commit hook.

npx linkbust
docs/setup.md:14   βœ—  ./install.md           (file not found)
README.md:8        βœ—  #quick-start           (no anchor "#quick-start" in this file)
guide.md:23        βœ—  ./api.md#missing       (no anchor "#missing" in ./api.md)

βœ— 3 broken Β· 142 links checked in 26 file(s)  (38 external skipped)

Why

Reorganize your docs, rename a file, tweak a heading β€” and quietly leave a trail of dead links behind. The checkers that catch this come with baggage:

  • markdown-link-check works, but it pulls in ~9 dependencies and its main job is hitting external URLs over HTTP β€” slow, flaky in CI, and rate-limited.
  • lychee is fast and thorough, but it's a Rust binary to install.
  • The old Python option (mlc) has been unmaintained since 2021.

linkbust does the part that breaks most often and is fully deterministic: local links. It never makes a network request β€” so it's instant, works offline, and won't flake your CI because someone's blog was down. That makes it ideal for a pre-commit hook or a fast docs lint.

What it checks

  • Relative file links β€” [x](../docs/api.md), image sources β€” resolve on disk.
  • Anchors β€” [x](#section) and [x](other.md#section) match a real heading (GitHub-style slug) or an explicit <a id="..."> / id="...".
  • Reference links β€” [text][ref] has a matching [ref]: … definition.
  • Links inside fenced/inline code are ignored, so examples don't trip it up.

It skips (never fetches) http(s), mailto:, protocol-relative //…, and /absolute paths β€” checking those is a different, networked job.

Usage

linkbust                  # every .md under the current directory
linkbust README.md        # a single file
linkbust docs/ CHANGELOG.md   # files and/or directories (recursive)
Option
--json machine-readable results
-q, --quiet print nothing when everything's fine (great for hooks)
--no-color
exit 0   all local links resolve
exit 1   one or more broken links
exit 2   usage / read error

As a pre-commit hook

# .pre-commit-config.yaml
- repo: local
  hooks:
    - id: linkbust
      name: linkbust
      entry: npx linkbust
      language: system
      pass_filenames: false

Install

npx linkbust              # Node >= 18
pip install linkbust      # Python >= 3.8 (byte-for-byte port)

License

MIT

About

Find broken LOCAL links in Markdown β€” relative paths + #anchors. No network, zero dependencies, pre-commit friendly.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors