TL;DR: YARD-Lint catches documentation issues, just like RuboCop for code. Star it and use it now.
I am happy to announce the release of YARD-Lint, a comprehensive linter designed for YARD documentation in Ruby and Rails projects. This gem is now available as open-source.
# In your Gemfile
gem 'yard-lint'
For those who are not familiar, YARD (Yet Another Ruby Documentation) is a documentation tool for Ruby that employs structured tags like @param, @return, @raise, and @example to describe methods with precision that machines can read.
Here's an example of linting in practice:
# Reverses the contents of a String or IO object.
#
# @param content [String, #read] the contents to reverse
# @return [String] the contents reversed lexically
# @example
# reverse("testing" #=> "gnitset"
def reverse(contents)
contents = contents.read if contents.respond_to? :read
contents.reverse
end
Inspecting with 21 validators
Found 2 offense(s):
[W] /home/mencio/Software/Mensfeld/demo/test.rb:7
ExampleSyntax: Object `#reverse` has syntax error in @example '<compiled>:1: syntax error found': > 1 | reverse("testing"
| ^ unexpected end-of-input; expected a `)` to close the arguments
[E] /home/mencio/Software/Mensfeld/demo/test.rb:7
UnknownParameterName: @param tag has unknown parameter name: content
I have been using YARD-Lint privately for a few years across all my open-source projects. It has been extensively tested across multiple production codebases and has identified thousands of documentation issues before they were merged. Until now, I haven't had the time to package it properly for public release - life got in the way, as it does.
Documentation Drift
Often I'd refactor method signatures without updating @param tags, return types changed while @return tags stayed stale, new exceptions got raised without @raise tags, and parameters got renamed while docs lagged behind. When I returned to code months later, I'd waste time figuring out what methods actually did versus what the docs claimed.
Since LLM-enhanced coding became part of my workflows, I've also noticed documentation quality directly affects how useful AI assistants are. Well-documented modules? Claude Code nails it quickly. Poor docs? I spend twice as long prompting and fixing. Research confirms this - bad docs cut LLM success rates in half. Even without AI, keeping docs synced matters, but tools like YARD-Lint became way more valuable once AI entered my workflows.
What YARD-Lint Does
A lot. Among other things, it catches:
- Documentation drift - Undocumented classes, modules, methods, and parameters that should have docs.
- Type accuracy - Invalid type definitions in
@param,@return, and@optiontags that don't match valid Ruby classes. - Missing context - Methods with
optionsparameters that lack@optiontags, question mark methods without return type documentation. - Broken examples - Invalid Ruby syntax in
@exampletags. - Semantic issues -
@abstractmethods with actual implementations, inconsistent tag ordering. - YARD parser errors - Unknown tags, invalid directives, duplicate parameters, malformed syntax.
It is RuboCop for your documentation - automated validation that runs in CI and catches problems before they ship (with auto-fixing under development!).
How To Use It
Below, you'll find a step-by-step procedure for installing and configuring YARD-Lint in your Ruby projects.
-
Add YARD-Lint to your Gemfile
# In your Gemfile gem 'yard-lint' -
Install YARD-Lint
bundle exec yard-lint --init -
Run YARD-Lint on your project
bundle exec yard-lint app/ -
Configure YARD-Lint using .yard-lint.yml
AllValidators: YardOptions: - --private Exclude: - 'vendor/**/*' - 'spec/**/*' Documentation/UndocumentedObjects: Enabled: true Severity: warning Tags/InvalidTypes: Enabled: true Severity: warning
It follows RuboCop's configuration style - hierarchical validators, inheritance support, per-validator controls. You can enable/disable specific checks, adjust severity levels, add custom type definitions, and exclude files per-validator.
Gradual Adoption
It also supports diff linting only, so you can introduce it slowly to your codebase:
Use diff mode to only lint changed files:
# Only check files you modified (perfect for legacy codebases)
yard-lint app/ --diff main
# Or just staged files for pre-commit hooks
yard-lint lib/ --staged
Start small with minimal config:
# Enable just one validator on your newest code
Documentation/UndocumentedObjects:
Enabled: true
Include:
- 'lib/features/new_module/**/*'
Or exclude legacy code:
AllValidators:
Exclude:
- 'lib/legacy/**/*'
Start with diff mode on pull requests, gradually expand coverage, then tackle older code during refactoring.
Why Open Source (and why now)
I've kept YARD-Lint private for years while continuously refining it. Although it reached a stable, production-ready state some time ago, life intervened - as it does.
I work extensively with open source projects, many of which rely heavily on YARD for documentation. It's been painful watching documentation quality decline in these projects. Good documentation practices have faded partly because there's no modern, actively maintained validation tool for YARD users.
I've finally carved out the time to properly package this for release. If you're maintaining a serious Ruby codebase, you deserve automated documentation quality checks - just like the automated code quality checks you already have.
References & Further Reading
- Testing the Effect of Code Documentation on Large Language Model Code Understanding – 2024 NAACL study on documentation impact
- Experience with GitHub Copilot for Developer Productivity at Zoominfo – Enterprise deployment study with 400+ developers
- Type-Constrained Code Generation with Large Language Models – Research on type hints and generation accuracy
- Five Best Practices for Using AI Coding Assistants – Google Cloud's documentation-first approach
- How to Use GitHub Copilot in Your IDE: Tips, Tricks, and Best Practices – GitHub's official guidance
- Effective Context Engineering for AI Agents – Anthropic's recommendations for Claude