You want to lint Markdown in CI.
You add markdownlint-cli2. Then you realize your CI job needs a Node.js
setup step. Then you need to pin a Node version. Then someone on your team
asks why the docs pipeline is touching Node at all.
There's another option.
Quick comparison
| markdownlint-cli2 | gomarklint | |
|---|---|---|
| Runtime | Node.js required | None (single binary) |
| Install in CI | npm install -g markdownlint-cli2 |
curl one-liner or GitHub Action |
| Rules | 50+ | 14 structural + link validation |
| HTTP link validation | Needs a separate tool | Built in |
| Config format |
.markdownlint.json / .markdownlint.yaml
|
.gomarklint.yaml |
| Speed | Fast | ~170ms per 100k lines |
| Ecosystem | npm | Homebrew, binary download, go install |
Installation
markdownlint-cli2 requires Node.js:
npm install -g markdownlint-cli2
markdownlint-cli2 "**/*.md"
gomarklint is a single binary:
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/shinagawa-web/gomarklint/main/install.sh | sh
# macOS via Homebrew
brew install shinagawa-web/tap/gomarklint
No runtime. No package manager. Download it and it runs.
CI integration
This is where the difference is most visible.
markdownlint-cli2 in GitHub Actions
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install markdownlint-cli2
run: npm install -g markdownlint-cli2
- name: Lint Markdown
run: markdownlint-cli2 "**/*.md"
4 steps. Node.js setup adds ~15–20 seconds to the job.
gomarklint in GitHub Actions
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Lint Markdown
uses: shinagawa-web/gomarklint-action@v1
2 steps. No runtime to set up.
Or if you prefer the binary directly:
- name: Install gomarklint
run: curl -fsSL https://raw.githubusercontent.com/shinagawa-web/gomarklint/main/install.sh | sh
- name: Lint Markdown
run: gomarklint .
Rules
markdownlint-cli2 has 50+ rules covering nearly every Markdown style
decision — list markers, emphasis style, line length, and more. If you
need fine-grained control over every aspect of your Markdown style, it's
the more comprehensive option.
gomarklint covers the rules that tend to matter most in practice:
- Heading level progression (no jumping from H2 to H4)
- Duplicate headings within a file
- Single H1 per file
- Blank lines around headings, lists, and code blocks
- Fenced code blocks without a language identifier
- Missing image alt text
- Bare URLs
- Empty links
- Setext headings
All rules are on by default and configurable via .gomarklint.yaml.
If you need all 50+ markdownlint rules, gomarklint won't replace it today.
If the rules above cover your needs, you avoid the Node.js dependency.
Link validation
This is gomarklint's biggest differentiator.
markdownlint-cli2 checks Markdown syntax. It won't tell you whether
[docs](https://example.com/old-page) returns a 404. You need a separate
tool for that — lychee, markdown-link-check, or similar.
gomarklint validates external HTTP links as part of the lint pass:
# .gomarklint.yaml
rules:
external-link:
enabled: true
timeoutSeconds: 5
skipPatterns:
- "localhost"
- "example\\.com"
One tool, one CI step.
Configuration
Both tools use YAML (or JSON for markdownlint). Here's a .gomarklint.yaml
that mirrors a typical markdownlint setup:
rules:
heading-level:
enabled: true
minLevel: 2
fenced-code-language:
enabled: true
external-link:
enabled: true
timeoutSeconds: 10
Which one should you use?
Use markdownlint-cli2 if:
- You already have Node.js in your pipeline
- You need granular style rules (line length, list marker style, etc.)
- You're in a JavaScript / frontend project where npm is already present
Use gomarklint if:
- You want a single binary with no runtime dependencies
- You want HTTP link validation without adding a second tool
- Your CI environment doesn't have Node.js, or you'd rather not add it
- You're in a Go, Rust, or other non-Node.js stack
pre-commit
Both tools support pre-commit.
# markdownlint-cli2
repos:
- repo: https://github.com/DavidAnson/markdownlint-cli2-action
rev: v17
hooks:
- id: markdownlint-cli2
# gomarklint
repos:
- repo: https://github.com/shinagawa-web/gomarklint
rev: v2.8.0
hooks:
- id: gomarklint
Summary
markdownlint-cli2 is the mature, feature-rich choice with broad community
support. gomarklint trades rule count for zero runtime dependencies and
built-in link validation.
If you've ever added Node.js to a CI pipeline just to lint Markdown, it's
worth a look.
Top comments (0)