What Is Automattic/harper? A Local-First Grammar Checker Built in Rust
Automattic/harper is an open-source English grammar-checking engine that runs entirely locally using a Rust core compiled to WebAssembly, offering privacy-focused linting across editors and JavaScript environments without sending data to external servers.
Automattic/harper is a modular grammar checking system designed for developers who need fast, private text analysis. Unlike cloud-based alternatives, Harper processes all text locally using a Rust-based core engine, making it suitable for sensitive environments and offline workflows. The project maintains a unified semantic versioning scheme across its ecosystem, ensuring consistent behavior whether you use the command-line language server, JavaScript library, or editor plugins.
How Automattic/harper Works: Modular Architecture
The project is deliberately structured as a collection of interoperating packages centered around a high-performance Rust core.
Harper Core: The Rust Grammar Engine
At the heart of the system is harper-core, located in harper-core/src, which handles the grammar-checking engine, rule catalog, and dictionary management. This component is defined in [harper-core/Cargo.toml](https://github.com/Automattic/harper/blob/master/harper-core/Cargo.toml) and serves as the foundation for all other integrations.
WebAssembly and JavaScript Bindings
To make the Rust core available in browsers and Node.js environments, Harper compiles to WebAssembly via harper-wasm. The WebAssembly interface is defined in [harper-wasm/src/lib.rs](https://github.com/Automattic/harper/blob/master/harper-wasm/src/lib.rs) and configured in [harper-wasm/Cargo.toml](https://github.com/Automattic/harper/blob/master/harper-wasm/Cargo.toml) with crate-type = ["cdylib", "rlib"].
The Harper.js package (packages/harper.js) provides a TypeScript wrapper around the WASM module, exposing two primary classes:
LocalLinter– Runs the grammar engine in the main thread for Node.js applications.WorkerLinter– Offloads processing to a Web Worker for browser environments.
Language Server Protocol (LSP) Implementation
For editor integration, Harper provides harper-ls, a Language Server Protocol implementation written in Rust. The entry point resides in [harper-ls/src/main.rs](https://github.com/Automattic/harper/blob/master/harper-ls/src/main.rs), exposing the core functionality to any LSP-compatible editor including VS Code, Neovim, and Obsidian.
Why Use Automattic/harper? Privacy and Performance
Harper distinguishes itself from other grammar checkers through three core characteristics:
- Privacy-First Architecture – All analysis happens locally with no network calls or data collection, ensuring sensitive content never leaves the machine.
- Minimal Resource Usage – The Rust-based engine provides millisecond-scale linting with approximately ½% of LanguageTool's memory footprint.
- Extensible Rule System – Developers can add new grammar rules using the Weir DSL or by contributing Rust code directly to the core engine.
Using Automattic/harper: Code Examples
Linting with Harper.js in Node.js
The JavaScript API provides a straightforward interface for grammar checking in server-side applications:
import { LocalLinter } from 'harper.js';
// Create a linter that loads the WASM binary once.
const linter = await LocalLinter.create({ binary: await import('harper.js/slimBinary') });
await linter.setup();
// Lint a piece of text.
const result = await linter.lint({
text: "I cant beleive this is happending.",
dialect: "American", // default is American English
});
console.log(result.lints.map(l => ({
message: l.message,
suggestion: l.suggestion?.replace,
})));
This example mirrors the documented usage in the Harper.js Node.js guide at packages/web/src/routes/docs/harperjs/node/+page.md.
Running the Language Server from the Command Line
You can invoke the grammar engine directly via the harper-ls binary:
# Install the binary (via Homebrew, Scoop, or Cargo)
brew install harper
# Run the LSP on a file (e.g., `example.md`)
harper-ls --stdin < example.md
The CLI entry point is implemented in [harper-ls/src/main.rs](https://github.com/Automattic/harper/blob/master/harper-ls/src/main.rs).
Integrating with Svelte Applications
For browser-based implementations, use the WorkerLinter class to avoid blocking the main thread:
<script>
import { Editor } from 'harper-editor';
import { onMount } from 'svelte';
let linter = null;
onMount(async () => {
const [{ WorkerLinter }, { slimBinary }] = await Promise.all([
import('harper.js'),
import('harper.js/slimBinary')
]);
linter = new WorkerLinter({ binary: slimBinary });
await linter.setup();
});
</script>
{#if linter}
<Editor content="Your text here…" {linter} />
{/if}
This pattern is used in the live editor demo on the project's documentation site, located in packages/web/src/routes/docs/about/+page.md.
Editor Integrations and Plugins
Automattic/harper supports a wide range of editing environments through thin UI layers:
- VS Code – Extension wrapping the language server (
packages/vscode-plugin/). - Neovim – Native LSP client configuration using
harper-ls. - Obsidian – Plugin leveraging the JavaScript API for real-time checking.
- Chrome/Firefox – Browser extensions for web-based writing.
Each integration shares the same underlying engine, ensuring consistent grammar suggestions across all platforms.
Summary
- Automattic/harper is a Rust-based grammar checker that runs entirely offline via WebAssembly.
- The architecture separates concerns into
harper-core(engine),harper-wasm(bindings),harper-ls(LSP server), and harper.js (JavaScript API). - Privacy and performance are primary design goals, with no network dependencies and minimal memory usage compared to Java-based alternatives.
- Integration options include command-line usage, Node.js applications, browser-based editors, and native LSP clients.
Frequently Asked Questions
How does Automattic/harper protect user privacy?
Harper processes all text locally using the Rust core engine compiled to WebAssembly. Because the system operates entirely offline without sending data to external servers, sensitive content never leaves the user's machine, making it suitable for confidential documents and secure environments.
What is the performance difference between Harper and LanguageTool?
According to the project documentation, Harper uses approximately ½% of LanguageTool's memory footprint while providing millisecond-scale linting. This efficiency comes from Harper's Rust-based implementation compared to LanguageTool's Java architecture, enabling faster startup times and lower resource consumption.
How do I add custom grammar rules to Automattic/harper?
Developers can extend Harper's functionality using the Weir DSL or by writing native Rust code in the harper-core package. The modular architecture allows new rules to be added to the core engine and automatically propagated to all downstream integrations including the JavaScript API and language server.
Which editors are officially supported by Automattic/harper?
Harper provides official integrations for VS Code, Neovim, and Obsidian through dedicated plugins, plus browser extensions for Chrome and Firefox. Additionally, any editor supporting the Language Server Protocol can connect to harper-ls for grammar checking capabilities.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →