northlint.

Documentation

One command, a handful of flags. Everything below reflects the current release; older behaviour is listed in the changelog.

Usage

$ northlint [flags] <directory>

The directory is the build output — the folder you would upload. northlint reads it recursively, keeps an index of every document and every id it declares, then resolves references against that index.

Flags

FlagEffect
--ignore <glob>Skip paths matching the pattern. Repeatable.
--base <path>Treat root-relative links as rooted here, for sites served under a subdirectory.
--index <name>Directory index filename. Defaults to index.html.
--strict-caseReport references whose case differs from the file on disk.
--format jsonMachine readable output instead of the default text.
--quietPrint nothing; rely on the exit code.

Rules

RuleMeaning
dead linkTarget document does not exist in the tree.
dead anchorDocument exists, fragment does not match any id.
missing fileReferenced asset is absent.
duplicate idTwo elements share an id; links to it are ambiguous.
case driftReference and file differ only in letter case.
empty hrefAn anchor with no destination, usually a templating slip.

Ignoring paths

Generated sites often carry directories that are not worth checking — vendored API references, archived versions, coverage reports. Skip them:

$ northlint ./public \
    --ignore 'api/**' \
    --ignore 'v1/**' \
    --ignore '**/coverage/**'
Ignore patterns apply to the file being scanned, not to the link target. A page outside the ignore set that links into an ignored directory is still checked, so removing a directory from the build cannot hide a broken reference to it.

Continuous integration

northlint exits non-zero when it finds problems, so no wrapper is needed:

- name: Check documentation links
  run: |
    go install northlint.com/cmd/northlint@latest
    northlint ./public --ignore 'api/**'

Exit codes

CodeMeaning
0No problems found.
1At least one problem reported.
2Bad invocation — unreadable directory, unknown flag.