DEV Community

Cover image for Super Fast Markdown Linting for Go Developers: Meet gomarklint
Kazu
Kazu

Posted on

Super Fast Markdown Linting for Go Developers: Meet gomarklint

The "Why" (The Motivation)

Documentation is the heart of any project, but keeping it consistent is a nightmare.

While working on various Go projects, I realized a few things about my workflow:

  1. Context Switching Costs: I love Go's speed and simplicity. Having to install Node.js or Ruby just to run a Markdown linter in a Go project felt "heavy."

  2. CI Fatigue: In large repositories, documentation checks shouldn't take seconds—they should take milliseconds. Every second saved in CI is a win for developer experience.

  3. The "Broken Link" Problem: There’s nothing more embarrassing than shipping a README with dead links. I needed a tool that catches these issues instantly.

I couldn't find a tool that was Go-native, ultra-fast, and zero-config by default, so I decided to build one.

The goal for gomarklint was simple: Make Markdown linting so fast and easy that you never have an excuse to skip it.

Speed Performance

When I say "fast," I mean Go-fast.

In many CI/CD pipelines, linting documentation is often the bottleneck that adds unnecessary seconds (or even minutes) to every PR. gomarklint changes that. By leveraging Go's concurrency and efficient string handling, it delivers near-instant feedback.

The Benchmark: I tested gomarklint against a large documentation set:

  • Total Files: 180 Markdown files
  • Total Volume: 100,000+ lines of text
  • Execution Time: < 50ms

To put that in perspective, 50ms is literally faster than the blink of a human eye. You can run this on every single file save without ever noticing a stutter in your workflow.

By removing the overhead of a virtual machine or a heavy runtime, gomarklint ensures that your documentation quality stays high without sacrificing your velocity.

Key Features

gomarklint doesn't just check syntax; it enforces a logical structure for your documentation. Here are the core rules it handles out of the box:

  • Heading Hierarchy Enforcement: Ever seen a document jump from an H2 directly to an H4? It breaks the visual flow and accessibility. gomarklint ensures your heading levels follow a strict, logical sequence.

  • Duplicate Heading Detection: Identical headings in the same file can break anchor links (e.g., #features vs #features-1). We catch these early so your internal navigation never breaks.

  • Broken Link Checker (Internal & External): This is my favorite. It scans your Markdown for links and validates them. No more 404s for your users when they click on a "Getting Started" guide or an external API reference.

  • Configuration via JSON: While it works great with zero config, you can easily tweak rules or ignore specific paths using a simple .gomarklint.json file.

Quick Start

# install (choose one)
go install github.com/shinagawa-web/gomarklint@latest

# or clone and build manually
git clone https://github.com/shinagawa-web/gomarklint
cd gomarklint
make build   # or: go build ./cmd/gomarklint
Enter fullscreen mode Exit fullscreen mode

1) Initialize config (optional but recommended)

gomarklint init
Enter fullscreen mode Exit fullscreen mode

This creates .gomarklint.json with sensible defaults:

{
  "include": ["."],
  "ignore": ["node_modules", "vendor"],
  "minHeadingLevel": 2,
  "enableHeadingLevelCheck": true,
  "enableDuplicateHeadingCheck": true,
  "enableLinkCheck": false,
  "skipLinkPatterns": [],
  "outputFormat": "text"
}
Enter fullscreen mode Exit fullscreen mode

You can edit it anytime — CLI flags override config values.

2) Run it

# lint current directory recursively
gomarklint ./...

# lint specific targets
gomarklint docs README.md internal/handbook
Enter fullscreen mode Exit fullscreen mode

What's Next? (Roadmap)

gomarklint is already stable and fast, but I have a clear vision for where it’s headed. I’m actively working on expanding its rule set to cover even more edge cases and best practices.

Here’s what you can expect in the coming updates:

  • max-line-length Enforcement: To keep your Markdown source files readable in any editor or GitHub's UI.

  • Image Alt-Text Validation: Improving accessibility by ensuring every image has a descriptive alt attribute.

  • Custom Rules via JSON: Giving you the power to define your own project-specific rules in .gomarklint.json.

  • Auto-fixing (The Dream): While currently focused on linting, I’m exploring ways to automatically fix simple issues like heading level skips.

We are Open for Contributions! If you have a rule in mind that would make your documentation better, or if you find a bug, please open an Issue or a Pull Request on GitHub. I’d love to build the future of this tool together with the community.

Wrap Up

Building gomarklint has been an incredible journey into the world of Go performance and static analysis. It started as a small tool for my own workflow, but I realized that many other developers are likely facing the same "slow linting" frustration.

If you're looking for a way to keep your documentation spotless without adding bloat to your CI/CD, I’d be honored if you gave gomarklint a try.

  • Check it out on GitHub: shinagawa-web/gomarklint

  • Give it a ⭐: If you find the project useful, a Star would mean the world to me and helps others discover the tool!

I’m really curious to hear from you: What’s the most annoying thing you’ve encountered with Markdown formatting? Let’s chat in the comments below!

Happy hacking! 🚀

Top comments (0)