A high-performance, feature-rich markdown linter written in Go
gomdlint is a fast, extensible markdown linter that provides compatibility with markdownlint while offering superior performance through Go's concurrency model and modern features like plugin extensibility.
- Blazing Fast: Up to 10x faster than Node.js alternatives through Go's efficient concurrency
- Memory Efficient: Optimized memory usage with intelligent caching
- Concurrent Processing: Parallel file processing for large document sets
- Smart Caching: Built-in result caching to avoid redundant processing
- 59 Built-in Rules: Full implementation of all markdownlint rules (MD001-MD059)
- CommonMark Compliant: Supports CommonMark specification and GitHub Flavored Markdown (GFM)
- Extensible: Plugin architecture for custom rules
- Configurable: Flexible rule configuration with JSON, YAML, and TOML support
- Plugin System: Extensible architecture for custom rules and functionality
- Multiple Output Formats: Support for default, JSON, JUnit, and Checkstyle formats
- Auto-fixing: Automatically fix violations where possible
- Rich Error Context: Detailed violation information with fix suggestions
- Library Mode: Use as a Go library in your applications
- CLI Integration: Perfect for CI/CD pipelines and pre-commit hooks
- Configuration Management: Advanced configuration with inheritance and environment-specific settings
- Comprehensive API: Full-featured programmatic interface
# Coming soon
brew install jamesainslie/gomdlint/gomdlintgo install github.com/jamesainslie/gomdlint/cmd/gomdlint@latestDownload the latest release from GitHub Releases.
git clone https://github.com/jamesainslie/gomdlint.git
cd gomdlint
make build# Lint a single file
gomdlint lint README.md
# Lint multiple files with glob patterns
gomdlint lint docs/*.md
# Use configuration file
gomdlint lint --config .markdownlint.json *.md
# Auto-fix violations
gomdlint fix README.md
# Check files (CI-friendly, exits with code 1 if violations found)
gomdlint check docs/
# Manage plugins and styles
gomdlint plugin list
gomdlint style apply relaxedpackage main
import (
"context"
"fmt"
"log"
"github.com/jamesainslie/gomdlint/pkg/gomdlint"
)
func main() {
ctx := context.Background()
// Lint a string
result, err := gomdlint.LintString(ctx, "# Hello\n\nThis is a test.", gomdlint.LintOptions{
Config: map[string]interface{}{
"MD013": map[string]interface{}{
"line_length": 120,
},
},
})
if err != nil {
log.Fatal(err)
}
// Print results
if result.TotalViolations > 0 {
fmt.Println(result.String())
} else {
fmt.Println("No violations found!")
}
}gomdlint supports multiple configuration formats and locations:
.markdownlint.json.markdownlint.yaml/.markdownlint.ymlmarkdownlint.jsonmarkdownlint.yaml/markdownlint.yml
{
"default": true,
"MD013": {
"line_length": 120,
"heading_line_length": 120,
"code_block_line_length": 120
},
"MD033": false,
"MD041": false,
"whitespace": {
"MD009": {
"br_spaces": 2
},
"MD010": {
"code_blocks": true
}
}
}# Create a default configuration file
gomdlint config init
# Validate existing configuration
gomdlint config validate
# Show effective configuration
gomdlint config showgomdlint implements all 59 markdownlint rules with full compatibility:
- Headings: MD001, MD003, MD018-MD026, MD036, MD041, MD043
- Lists: MD004, MD005, MD007, MD029-MD032
- Code: MD014, MD031, MD038, MD040, MD046, MD048
- Links: MD011, MD034, MD039, MD042, MD051-MD054, MD059
- Whitespace: MD009, MD010, MD012, MD027, MD028, MD030, MD037-MD039
- And more: Line length, HTML, tables, emphasis, etc.
# List all rules
gomdlint rules list
# Show rule details
gomdlint rules info MD013
# List rules by tag
gomdlint rules list --tag headingsExtend gomdlint with custom rules and functionality:
# List available plugins
gomdlint plugin list
# Install a plugin
gomdlint plugin install my-custom-rules.so
# Build plugin from source
gomdlint plugin build ./my-plugin-source/
# Check plugin health
gomdlint plugin healthFeatures:
- Extensible Rules: Add custom linting rules via plugins
- Go Native: Write plugins in Go for maximum performance
- Hot Loading: Install and manage plugins dynamically
- Health Monitoring: Built-in plugin health checks
- Source Building: Build plugins directly from source
Use predefined configurations for different scenarios:
# List available styles
gomdlint style list
# Apply a style configuration
gomdlint style apply strict
# Show style details
gomdlint style show relaxed
# Create custom style
gomdlint style create my-style config.jsonAvailable styles:
- relaxed: Lenient rules for casual documentation (120 char lines, allows HTML)
- strict: Professional documentation standards (80 char lines, strict formatting)
- minimal: Essential rules only (headings, basic formatting)
- all: All rules enabled with default settings
gomdlint is designed for speed with native Go performance:
- Parallel Processing: Process multiple files concurrently
- Smart Caching: Cache parsing results and rule execution
- Memory Pooling: Reuse allocated memory to reduce GC pressure
- Lazy Loading: Load rules and configuration only when needed
- Go 1.23+
- Make (optional, but recommended)
git clone https://github.com/jamesainslie/gomdlint.git
cd gomdlint
make dev-setupmake help # Show available targets
make build # Build the binary
make test # Run tests
make test-cover # Run tests with coverage
make performance # Run performance tests
make lint # Run linters
make security # Run security checks
make check # Run all quality checks
make release # Build release binariesgomdlint follows clean architecture principles with functional programming patterns:
├── cmd/gomdlint/ # CLI application entry point
├── pkg/gomdlint/ # Public API for library usage
├── internal/
│ ├── app/service/ # Application services (linter, parser, rule engine)
│ ├── domain/
│ │ ├── entity/ # Core business entities (Rule)
│ │ └── value/ # Value objects (Token, Violation, Config)
│ ├── infrastructure/ # External integrations
│ ├── interfaces/cli/ # CLI commands and interface
│ └── shared/functional/ # Functional programming utilities
We welcome contributions! Please see CONTRIBUTING.md for guidelines.
gomdlint maintains full compatibility with markdownlint:
- ✅ Same Rule Set: All 59 rules implemented with identical behavior
- ✅ Configuration Format: Compatible configuration files
- ✅ Output Format: Same violation reporting format
- ✅ Exit Codes: Identical CLI behavior for CI/CD integration
- ✅ Rule Aliases: Support for both MD### and descriptive names
Replace your existing markdownlint commands:
# Before (Node.js markdownlint)
markdownlint docs/*.md
# After (gomdlint)
gomdlint lint docs/*.md
# Or use as drop-in replacement
alias markdownlint="gomdlint lint"Performance on a typical documentation repository (100 markdown files, ~500KB total):
| Tool | Time | Memory | CPU Usage |
|---|---|---|---|
| gomdlint | 47ms | 12MB | 15% |
| markdownlint | 523ms | 127MB | 45% |
| markdownlint-cli2 | 401ms | 95MB | 38% |
Results from MacBook Pro M2, Go 1.23, Node.js 20.x
MIT License - see LICENSE for details.
- markdownlint by David Anson - Original inspiration and rule definitions
- CommonMark - Markdown specification
- Cobra - Excellent CLI framework
- Go community - For the amazing ecosystem and tools
This project follows Semantic Versioning (SemVer) principles:
- MAJOR version for incompatible API changes
- MINOR version for backwards-compatible functionality additions
- PATCH version for backwards-compatible bug fixes
See CHANGELOG.md for detailed release history.
gomdlint - Because markdown deserves better linting.