How to Use the Harper Command-Line Interface (CLI) for Grammar Checking

The Harper CLI (harper-cli) is an experimental binary that exposes Harper’s grammar-checking engine directly in your terminal, supporting sub-commands like lint, parse, and spans with configurable dialects, dictionaries, and output formats.

The Harper command-line interface provides direct access to the same grammar and spelling engine that powers the Harper language server and editor extensions. Built on top of harper-core, the CLI allows you to lint text files, inspect token streams, and integrate grammar checking into CI pipelines without requiring a graphical environment.

Installing the Harper CLI

You can compile and install the binary directly from the repository using Cargo. This installs the harper-cli executable to your local cargo bin directory.

cargo install --path harper-cli --locked

The installation process compiles the CLI against the locked dependency versions specified in the repository, ensuring compatibility with the core library components defined in harper-core.

Core Commands and Architecture

The CLI entry point in harper-cli/src/main.rs uses clap to define the Cli struct and route sub-commands. The primary functionality resides in harper-cli/src/lint.rs, which implements the lint function along with supporting types like LintOptions and the OutputFormat enum.

Linting Text and Documents

The lint sub-command is the most common entry point. It reads one or more text files (or standard input) and reports grammar and spelling issues using the same rule engine as the graphical extensions.


# Lint a single file

harper-cli lint src/docs/example.md

# Lint multiple files with glob patterns

harper-cli lint src/**/*.md

# Lint from standard input in a pipeline

cat README.md | harper-cli lint -

The lint implementation loads the curated dictionary, optionally merges user and file-specific dictionaries, creates a LintGroup, executes the rule set, and formats results according to your selected output style.

Inspecting Token Structure

Beyond linting, the CLI provides utilities for debugging and analysis:

  • parse – Displays the token stream generated by Harper’s parsers
  • spans – Shows token spans with positional information
  • metadata – Retrieves lexical metadata for the input text

# Show token spans including newline characters

harper-cli spans --include-newlines src/main.rs

Configuration and Dictionaries

The Harper CLI respects the same configuration conventions as harper-ls, looking for dictionaries in platform-specific directories while allowing explicit overrides via command-line flags.

User and File Dictionaries

By default, the CLI searches for a user dictionary at config_dir()/harper-ls/dictionary.txt and file-local dictionaries under data_local_dir()/harper-ls/file_dictionaries/. You can override these locations using:

  • --user-dict-path – Path to a plain-text dictionary file loaded into a MutableDictionary
  • --file-dict-path – Directory containing file-specific dictionary overrides
harper-cli lint --user-dict-path ~/.config/harper/my-dict.txt document.md

Dialect Selection

Use the --dialect flag to specify spelling conventions for the linting session. Supported values include us (American), gb (British), ca (Canadian), and au (Australian) English.

harper-cli lint --dialect gb document.txt

Weirpack Rule Extensions

The CLI supports loading custom rule packs via Weirpack files. The load_dict function in harper-cli/src/lint.rs handles reading these binary files and injecting custom rules into the linter.

harper-cli lint --weirpack rules/custom.weirpack src/**/*.txt

Output Formats

The OutputFormat enum in harper-cli/src/lint.rs defines three reporting styles selectable via the --format flag:

  • default – Rich, colorized Ariadne reports with contextual snippets
  • json – Machine-readable JSON output for integration with other tools
  • compact – Single-line-per-issue format suitable for logs or quick scans

# JSON output for CI integration

harper-cli lint --format json --no-color src/**/*.md

# Compact format for quick review

harper-cli lint --format compact document.txt

Use --no-color to suppress ANSI color codes when redirecting output to files or systems that do not support terminal formatting.

Rule Filtering

Control which rules execute during a linting run with filtering options:

  • --only <rule> – Run only the specified rule (e.g., passive-voice)
  • --ignore <rule> – Skip the specified rule
  • --count – Display only the error count rather than full diagnostics

# Run only the passive voice rule and show error count

harper-cli lint --only passive-voice --count src/**/*.rs

Practical Workflow Examples


# 1️⃣ Install the binary (run once)

cargo install --path harper-cli --locked

# 2️⃣ Lint a single file with default settings

harper-cli lint src/docs/example.md

# 3️⃣ Lint multiple files, suppress colour, and output JSON

harper-cli lint --no-color --format json src/**/*.md

# 4️⃣ Lint from standard input (useful in pipelines)

cat README.md | harper-cli lint -

# 5️⃣ Apply a custom Weirpack with additional rules

harper-cli lint --weirpack rules/custom.weirpack src/**/*.txt

# 6️⃣ Run only the “passive‑voice” rule and count errors

harper-cli lint --only passive-voice --count src/**/*.rs

# 7️⃣ Show token spans for a file (useful for debugging)

harper-cli spans --include-newlines src/main.rs

Summary

  • The Harper CLI provides terminal access to the full harper-core grammar engine used by editor extensions and language servers.
  • Key source files include harper-cli/src/main.rs for argument parsing and harper-cli/src/lint.rs for the linting logic and output formatting.
  • The lint sub-command supports stdin, multiple files, and three output formats: default (Ariadne), JSON, and compact.
  • Configuration options include --dialect, --user-dict-path, --file-dict-path, and --weirpack for customizing dictionaries and rule sets.
  • Because the CLI is a thin wrapper around the core library, behavior remains consistent across all Harper integrations, making it ideal for CI pipelines and batch processing.

Frequently Asked Questions

How do I install the Harper CLI?

Compile and install the binary using Cargo from the repository root: cargo install --path harper-cli --locked. This builds the experimental harper-cli binary and places it in your cargo bin directory, ready for use in your terminal.

Can I use harper-cli in CI pipelines?

Yes. Use the --format json flag for machine-readable output that CI systems can parse, and --no-color to disable terminal formatting. The CLI exits with a non-zero status when lints are found, making it compatible with standard CI failure detection mechanisms.

What is the difference between the Harper CLI and harper-ls?

The Harper CLI (harper-cli) is a standalone binary for one-off linting and text analysis from the command line, while harper-ls is a language server protocol implementation for continuous integration with editors. Both use the same harper-core library and configuration paths, but the CLI is better suited for batch processing and scripting.

How do I add custom words to the Harper dictionary?

Create a plain-text file with one word per line and pass it via --user-dict-path, or place it at the default location config_dir()/harper-ls/dictionary.txt. The CLI loads this into a MutableDictionary during initialization, merging your custom words with the curated built-in dictionary before linting begins.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →