The project is in a healthy, maintained state
RuboCop spelling checks for Ruby comments, strings, identifiers, and documentation, using offline dictionaries.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Runtime

~> 1.0.8
~> 1.72, >= 1.72.1
~> 8.1
 Project Readme

rubocop-spellcheck

Tests Lint Package Gem Version

Spellcheck Ruby comments, strings, identifiers, and documentation with RuboCop and Kotoshu.

Table of Contents

  • Installation
  • Usage
  • Other languages
  • Supported files
    • Ruby comments
    • Ruby strings and identifiers
    • RDoc
    • Markdown
    • YAML front matter
    • AsciiDoc
    • Plain text
  • Autocorrection
  • Configuration
    • Front matter paths
    • Dictionary files
    • Adding project vocabulary
    • Generating project vocabulary
    • Replacing dictionaries and adding languages
    • Exclusions and suppression
  • Scope and limitations
  • Contributing
  • Copyright and License

Installation

Requires Ruby 3.2 or newer and RuboCop 1.72.1 or newer (1.x).

Add to your Gemfile:

group :development do
  gem 'rubocop-spellcheck', require: false
end

Enable the plugin in .rubocop.yml:

plugins:
  - rubocop-spellcheck

Install and run; the default American English dictionary is included in the gem:

bundle install
bundle exec rubocop

No dictionary setup or network access is needed.

Usage

Spellcheck/Spelling is enabled by default and checks Ruby comments, strings, Markdown, RDoc, AsciiDoc, and plain text. Identifier checking is opt-in:

bundle exec rubocop
bundle exec rubocop --only Spellcheck/Spelling

For example, given example.rb:

# The red brown fox jumsp over the lazy dog.

Running bundle exec rubocop --only Spellcheck/Spelling example.rb reports:

example.rb:1:21: C: Spellcheck/Spelling: Misspelled word: jumsp. Did you mean jumps, jump, jumpy?
# The red brown fox jumsp over the lazy dog.
                    ^^^^^

Each offense highlights the misspelled word and includes up to three suggestions when available.

Fix typos, then generate an initial .spellcheck.txt for remaining project-specific words:

bundle exec rubocop --auto-gen-config --only Spellcheck/Spelling

The command adds both the bundled English dictionary and .spellcheck.txt to your configuration when no dictionaries are configured. Review the generated vocabulary: remaining typos are accepted too. See Generating project vocabulary for regeneration behavior.

Other languages

For another language, download a Hunspell dictionary and its license into your project. For example, download the latest German resources:

mkdir -p dictionaries/de
curl -fL https://raw.githubusercontent.com/kotoshu/dictionaries/v1/de/spelling/index.dic -o dictionaries/de/de.dic
curl -fL https://raw.githubusercontent.com/kotoshu/dictionaries/v1/de/spelling/index.aff -o dictionaries/de/de.aff
curl -fL https://raw.githubusercontent.com/kotoshu/dictionaries/v1/de/spelling/license -o dictionaries/de/LICENSE

Then configure the locations explicitly:

Spellcheck:
  DictionaryFiles:
    de:
      - dictionaries/de/de.dic

The matching .aff file is required. Commit both files and their license, or provision them in CI. Review each dictionary's license before redistributing it; linting never downloads dictionaries.

Supported files

Ruby comments

Ruby comments, including trailing and block comments, are checked. Shebangs, magic comments, RuboCop/Standard directives, and Sorbet typed: declarations are skipped. URLs and email addresses are ignored.

Comments are parsed as RDoc, excluding indented examples and inline code.

Ruby strings and identifiers

Strings include ordinary and percent literals, string arrays, heredocs, and literal text inside interpolation. Contents are checked literally, not as markup. Paths passed to require, require_relative, load, and autoload, plus gem names and version requirements, are excluded. Symbols, regular expression text, and shell-command text are also excluded; Ruby expressions inside interpolation are still checked. Ruby code is never evaluated.

Identifier checking is disabled by default. When enabled, every occurrence is checked, including method calls, definitions, constants, arguments, and variables. Names such as hello_world, helloWorld, and HTTPClient are split at underscores, numbers, and case boundaries. Add intentional API names and abbreviations to your project vocabulary.

Enable identifiers or disable strings independently:

Spellcheck/Spelling:
  Ruby:
    Strings: false
    Identifiers: true

Standard Ruby suppression directives apply to all three scopes. Identifier errors are report-only: renaming one occurrence could break references or external APIs. Strings support rubocop -A, but changing a string can change program behavior; review these edits carefully.

Explicitly tagged ruby Markdown fences use the same string and identifier settings, including inside lists and blockquotes. Untagged or indented code, other languages, comments inside fences, and invalid Ruby snippets remain excluded.

RDoc

.rdoc files and Ruby comments use RDoc parsing. Headings, paragraphs, lists, and link labels are checked; code, link destinations, and documentation directives are skipped. Directives such as :include: are never executed.

Markdown

The cop discovers .md and .markdown files and checks their prose:

# The red brown fox jumsp over the lazy dog.

Check [the spelling](https://example.com) but not `code_identifiers`.

Prose, headings, lists, tables, link labels, image descriptions, and footnotes are checked. Code other than explicitly tagged ruby fences, link destinations, HTML, Liquid expressions, URLs, and email addresses are skipped. No rubocop-md plugin is required.

YAML front matter

String values are checked recursively, including multiline values and arrays. Keys, numbers, booleans, dates, and nulls are skipped. Layout names and slugs are strings too; use front matter paths to select prose fields. Invalid YAML produces an error. To disable these checks:

Spellcheck/Spelling:
  Markdown:
    FrontMatter:
      Enabled: false

AsciiDoc

.adoc and .asciidoc files use Asciidoctor to check prose, headings, lists, tables, and link labels. Code, comments, attributes, link destinations, and macros are skipped. Includes and extensions are disabled; linting does not render documents or access external resources.

Plain text

.txt files are checked literally, excluding URLs and email addresses. Configured dictionaries and bundled resources are excluded automatically. Use normal RuboCop exclusions for other files you do not want checked.

Autocorrection

Dictionary suggestions may not match your intended meaning, so spelling corrections require rubocop -A; rubocop -a leaves spelling unchanged. To apply corrections, use:

bundle exec rubocop -A --only Spellcheck/Spelling

Lowercase and title-case words whose first suggestion is at a distance of one edit are corrected: one insertion, deletion, substitution, or adjacent transposition. The replacement must pass the configured dictionaries. Other suggestions may be equally close; the first suggestion wins, preserving lowercase or title case. ALL CAPS, mixed-case words, and components of dotted or identifier-like tokens remain report-only. Corrections do not introduce multiple words or formatting characters. Title-case corrections can change people's names; review the resulting diff.

Corrections preserve surrounding markup and string delimiters; escaped letters may become literal letters. Unsafe replacements such as a heredoc terminator or a typed YAML value are withheld. Identifiers are never renamed.

Configuration

Front matter paths

By default, all front matter string values are checked. Use dotted paths under Markdown.FrontMatter to select which values participate:

Spellcheck/Spelling:
  Markdown:
    FrontMatter:
      Enabled: true
      Include:
        - title
        - description
        - metadata
        - authors.description
      Exclude:
        - metadata.slug
        - metadata.internal

Paths are case-sensitive, with dots separating nested keys. Selecting a parent includes its descendants; authors.description selects descriptions in every author mapping without array indices. Wildcards and literal dots in key names are not supported.

Include: null checks all paths; Include: [] checks none. Exclude always takes precedence. These settings do not affect Markdown body prose.

Dictionary files

DictionaryFiles maps language codes to lists of dictionary paths. When omitted or null, it selects packaged English, equivalent to:

Spellcheck:
  DictionaryFiles:
    en:
      - gem:rubocop-spellcheck/data/en/en.dic

An explicit map replaces the defaults: retain the English path if you still want English. A word passes if any configured dictionary accepts it; there is no automatic language detection.

gem:<gem-name>/ paths resolve inside the installed gem. Other paths are relative to the effective RuboCop configuration directory. Missing dictionaries and invalid settings produce errors rather than falling back to defaults.

Hunspell .dic files load their matching .aff file in the same directory with the same basename. Plain .txt files contain literal words, one per line, matched case-insensitively without automatic inflection. Blank lines and lines starting with # are ignored; phrases are rejected.

Normal RuboCop inheritance and cop-specific overrides apply. Dictionary changes invalidate cached results; Kotoshu's personal dictionary is not used.

Adding project vocabulary

Project vocabulary is just a plain .txt file with one word per line. Retain the gem dictionary path and append your version-controlled word list for product names and domain terms:

Spellcheck:
  DictionaryFiles:
    en:
      - gem:rubocop-spellcheck/data/en/en.dic
      - .spellcheck.txt
# Project vocabulary
Kotoshu
RuboCop

Words match case-insensitively; list plural and other forms explicitly. Blank lines and # comments are ignored. To use only your own word list, omit the gem path.

Generating project vocabulary

Use the RuboCop configuration generator to build an initial vocabulary:

bundle exec rubocop --auto-gen-config

Spelling offenses create or update .spellcheck.txt. To generate vocabulary without configuring other cops:

bundle exec rubocop --auto-gen-config --only Spellcheck/Spelling

Every reported misspelling becomes accepted vocabulary, including genuine typos and words with correction suggestions. Review the generated list, remove mistakes, and fix them in the source. Generation does not correct source files.

Rerunning rebuilds .spellcheck.txt from current violations without accepting its existing words during checking. Unneeded entries are removed, including manually added ones. Comments and capitalization of retained words are preserved; new words are lowercase, sorted, and added without duplicates. The command adds the vocabulary to DictionaryFiles while retaining existing dictionaries, or bundled English when using defaults.

Vocabulary is written beside the effective configuration, including nested configurations. Exclusions and suppression still apply. Run against the full intended file set: words needed only in omitted files will be removed. Clean runs clear obsolete entries but do not create a new vocabulary file.

Replacing dictionaries and adding languages

List replacement dictionaries and any other active languages explicitly:

Spellcheck:
  DictionaryFiles:
    en:
      - dictionaries/custom-en.dic
    de:
      - dictionaries/de/de.dic

Both dictionaries participate in spelling checks. To check only German, omit the en key. Download instructions above show how to obtain the latest German files and their license.

Exclusions and suppression

Use standard RuboCop exclusions and inline directives:

Spellcheck/Spelling:
  Exclude:
    - spec/fixtures/**/*
# rubocop:disable Spellcheck/Spelling
# Deliberately misspelled example: resutl.
# rubocop:enable Spellcheck/Spelling

Ruby directives apply to comments, strings, and identifiers, including within tagged Ruby fences. In Markdown, use HTML comments:

<!-- rubocop:disable Spellcheck/Spelling -->
Intentional project vocabulary.
<!-- rubocop:enable Spellcheck/Spelling -->

A trailing disable or any todo applies only to its own line. Directives accept all, cop lists, and reasons after --. HTML-comment directives inside code, Liquid, or front matter are ignored; Ruby directives apply within their own fence. Suppression prevents diagnostics and autocorrection.

To check only one format, use standard file inclusion:

Spellcheck/Spelling:
  Include:
    - "**/*.rb"

Scope and limitations

English words retain accented letters and internal apostrophes; surrounding quotation marks and numeric identifiers such as commit hashes and ordinals are not checked.

Ruby comments use RDoc markup, not YARD or other documentation syntaxes. Other documentation tags are treated as text. Use a project dictionary or standard suppression for intentional non-prose. Word boundaries and spelling follow Kotoshu's selected language; this extension does not add language detection or grammar checking.

Kotoshu ships precompiled gems for macOS, Linux, and Windows. Building native dependencies from source on other platforms may require a Rust toolchain.

Contributing

See CONTRIBUTING.md for development and RELEASING.md for releases.

Copyright and License

Copyright (c) 2026 Daniel (dB.) Doubrovkine. MIT License; see LICENSE.txt.

Kotoshu is a separate BSD-2-Clause dependency. The bundled SCOWL-derived American English dictionary carries its own copyright and redistribution terms; see its full license and pinned provenance. Dictionary files and notices are included in the packaged gem.

Other dictionaries have their own licenses regardless of the dictionary repository's license. The German example is GPL-2.0 OR GPL-3.0 and is not bundled. Review each dictionary's notices before redistributing it.