How to Contribute to Automattic Harper: The Complete Guide to This Rust Grammar Checker

To contribute to Automattic Harper, clone the repository, run just setup to configure the build toolchain, select a component from the Rust core to the WebAssembly bridge, and submit changes via pull request after running just precommit to verify formatting and tests.

Automattic Harper is a high-performance grammar checker built as a modular Rust monorepo with WebAssembly bindings and editor integrations. Whether you want to improve the core linting engine, add language server features, or build plugins for VS Code and Obsidian, understanding the repository structure is essential before you contribute to Automattic Harper.

Understanding the Harper Monorepo Architecture

Harper organizes its codebase into distinct packages that share a common Rust core. Knowing where each component lives helps you target contributions effectively.

The repository structure includes:

  • harper-core: The Rust engine at harper-core/src that tokenizes, parses, and lints English text. It provides the Document, Parser, and Linter traits.
  • harper-wasm: Builds the WebAssembly binary using wasm-pack, located in the harper-wasm directory.
  • harper-ls: The Language Server Protocol implementation in harper-ls that powers VS Code, Neovim, Helix, and Emacs.
  • harper.js: The NPM package in harper.js that loads the WASM module for Node.js and browser environments.
  • Integration plugins: Chrome/Firefox extensions, Obsidian, and WordPress plugins, each with their own pnpm-based build pipeline.
  • harper-desktop: A Tauri/SvelteKit desktop application providing an overlay highlighter.

Setting Up Your Development Environment

Before writing code, install the required tooling: just (task runner), cargo (Rust), pnpm, node, and wasm-pack. The repository automates dependency installation through the justfile.

Run the setup command from the repository root:

just setup

This command populates caches and pulls all dependencies across the monorepo, preparing you to build any component.

The Contribution Workflow

Follow these steps to ensure your contribution aligns with project standards and passes CI.

1. Review the Contributor Documentation

Start with the contributor introduction at packages/web/src/routes/docs/contributors/introduction/+page.md. This explains where to file bugs, ask questions, and find environment-specific guides.

2. Fork and Branch

Create a fork on GitHub and branch from main using a descriptive name related to your feature or fix.

3. Pick Your Target

Decide whether you will work on:

  • The core engine (harper-core) for grammar rules and parsing
  • The language server (harper-ls) for LSP features
  • JavaScript bindings (harper.js) for API improvements
  • Editor plugins (VS Code, Obsidian, etc.)
  • The desktop application (harper-desktop)

The architecture overview at packages/web/src/routes/docs/contributors/architecture/+page.md maps these relationships.

4. Code to Standards

All Rust code must pass cargo fmt and cargo clippy. JavaScript and TypeScript code must pass pnpm format. The project uses conventional commit messages (documented in packages/web/src/routes/docs/contributors/committing/+page.md).

5. Run Pre-Commit Checks

Before pushing, execute:

just format
just precommit

The just format command formats all Rust and JavaScript code. The just precommit task runs the full test suite and linters. Fix any failures before submitting.

6. Open a Pull Request

Push your branch and open a PR against main. GitHub Actions automatically lint the contribution. Reviewers expect all checks to pass and guidelines to be honored.

Essential Commands for Contributors

The justfile serves as the single source of truth for build scripts. Here are the commands you'll use most frequently when you contribute to Automattic Harper.

Building the Project

Compile the entire repository or specific components:


# Build everything including WebAssembly

just build-web

# Build the Chrome extension specifically

just build-chrome

Running Tests

Execute the test suites for different components:


# Run Rust unit tests

just test-rust

# Run VS Code extension tests

just test-vscode

# Run Chrome extension tests

just test-chrome

Using the CLI for Testing

Test the core engine directly on files:

cargo run --bin harper-cli -- lint README.md

This uses the same Document and Linter traits that power all integrations.

Adding Dictionary Words

To add curated nouns to the dictionary:

just addnoun "HarperBot"

This appends the entry to harper-core/dictionary.dict with proper formatting.

Implementing New Linters

To add a new grammar rule, create a Rust file in harper-core/src/linting/linters/ and implement the Linter trait:

// Example: harper-core/src/linting/linters/my_rule.rs
pub struct MyRule;

impl Linter for MyRule {
    fn lint(&self, doc: &Document) -> Vec<Lint> {
        // Detection logic here
        vec![]
    }
}

Register your linter in harper-core/src/linting/lint_group.rs to include it in the default lint set. After changes, run:

just format
just test-rust

Summary

  • Automattic Harper is a Rust monorepo with WebAssembly bindings, language servers, and editor plugins.
  • Run just setup to configure your environment, then use just precommit before submitting PRs.
  • Core contributions modify harper-core/src/, while integrations live in separate package directories.
  • All code must pass cargo fmt, cargo clippy, or pnpm format, and use conventional commit messages.
  • The justfile centralizes build commands like just test-rust, just build-web, and just addnoun.

Frequently Asked Questions

What programming languages do I need to know to contribute to Automattic Harper?

You will primarily work with Rust for the core engine and language server, and JavaScript/TypeScript for the WASM bindings, VS Code extension, Obsidian plugin, and desktop application. The Chrome extension and web packages may also require Svelte or HTML/CSS knowledge.

How do I run the Harper CLI locally to test my changes?

Use Cargo to run the CLI binary directly: cargo run --bin harper-cli -- lint path/to/file.rs. This executes the harper-cli tool using your local source code, allowing you to test grammar rules against any text file before committing changes.

Where should I add a new grammar rule or linter?

Create a new file in harper-core/src/linting/linters/ implementing the Linter trait, then register it in harper-core/src/linting/lint_group.rs. This directory contains all linting implementations, and the lint_group.rs file manages which rules are active by default.

How do I add words to Harper's curated dictionary?

Run the command just addnoun "YourWord" from the repository root. This utility updates harper-core/dictionary.dict with the proper flags and formatting required by the core tokenizer, ensuring consistent dictionary management across the project.

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 →