# What Is Automattic Harper? A Deep Dive Into the Rust-Based Grammar Engine

> Explore Automattic Harper, a privacy-first Rust grammar engine compiled to WebAssembly. Discover its capabilities as a language server and editor integration for developers.

- Repository: [Automattic/harper](https://github.com/Automattic/harper)
- Tags: deep-dive
- Published: 2026-07-26

---

**Automattic Harper is a privacy-first, open-source grammar-checking platform built as a Rust core engine compiled to WebAssembly, distributed via a language server, desktop application, and extensive editor integrations.**

The Automattic Harper repository is a monorepo that packages a high-performance grammar engine for multiple runtimes. Written primarily in Rust, the project emphasizes on-device processing to keep user data private while providing consistent diagnostics across VS Code, Neovim, Obsidian, browsers, and standalone desktop applications.

## Core Architecture: Rust, WebAssembly, and Multi-Runtime Distribution

The project follows a layered architecture where a single Rust core powers all interfaces through targeted compilation and wrappers.

### The Core Engine (`harper-core`)

At the foundation lies `harper-core`, the Rust crate containing the rule engine and built-in linters. This crate handles the actual grammar analysis without external dependencies, ensuring fast, offline operation. The source code resides in [`harper-core/src`](https://github.com/Automattic/harper/tree/master/harper-core/src), where the engine processes text and returns diagnostic structures used by all higher-level components.

### WebAssembly Bridge (`harper-wasm`)

To expose the engine to JavaScript environments without requiring a native binary, the project compiles the Rust core to WebAssembly via `harper-wasm`. The bridge code in [[`harper-wasm/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-wasm/src/lib.rs)](https://github.com/Automattic/harper/blob/master/harper-wasm/src/lib.rs) creates a WASM module that browsers and Node.js can load directly, maintaining the same rule logic as the native implementation.

### JavaScript Wrapper ([`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js))

The [[`packages/harper.js/src/main.ts`](https://github.com/Automattic/harper/blob/main/packages/harper.js/src/main.ts)](https://github.com/Automattic/harper/blob/master/packages/harper.js/src/main.ts) file provides a TypeScript-friendly API that loads the WASM module and offers convenient linting helpers. This wrapper simplifies integration for web developers who need grammar checking in Node.js or browser contexts.

## Editor Integrations and Language Server

Harper implements the Language Server Protocol (LSP) through `harper-ls`, enabling real-time diagnostics in compatible editors.

### Language Server Protocol (`harper-ls`)

The Rust binary defined in [[`harper-ls/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-ls/src/main.rs)](https://github.com/Automattic/harper/blob/master/harper-ls/src/main.rs) exposes diagnostics, code actions, and auto-fixes to any LSP-compliant editor. VS Code communicates with this server through a thin client extension, while Neovim users can configure it via standard LSP settings.

### Desktop Application

For users preferring a standalone interface, Harper provides a desktop application built with **Tauri** (Rust backend) and **Svelte** (frontend). The Rust highlighter process runs in [[`harper-desktop/src-tauri/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-desktop/src-tauri/src/main.rs)](https://github.com/Automattic/harper/blob/master/harper-desktop/src-tauri/src/main.rs), communicating with the UI via JSON-line IPC channels defined in [[`harper-desktop/src-tauri/src/communication/message.rs`](https://github.com/Automattic/harper/blob/main/harper-desktop/src-tauri/src/communication/message.rs)](https://github.com/Automattic/harper/blob/master/harper-desktop/src-tauri/src/communication/message.rs).

### Browser and CMS Extensions

Beyond editors, Harper extends to Chrome, Firefox, and WordPress through dedicated packages. The browser extensions and CMS integrations wrap either the WASM module or language server, allowing grammar checking directly in web forms and content management systems.

## Privacy-First Design Philosophy

Unlike cloud-based grammar services, Harper processes all text locally on the user's device. The architecture ensures that no content leaves the local environment, as the Rust core operates entirely offline. This design applies uniformly across the desktop app, browser extensions, and language server instances.

## Implementation Examples

### Using Harper in Node.js

The JavaScript wrapper enables quick integration for server-side or build-tool usage:

```typescript
import { LocalLinter } from "harper.js";

async function lintExample() {
  const linter = await LocalLinter.create();   // loads the WASM module
  const text = "This is a teh example.";
  const results = await linter.lint(text);
  console.log(results);   // → [{ message: "Replace “teh” with “the”", ... }]
}

lintExample();

```

This code loads the WebAssembly module through the `LocalLinter` class and returns structured diagnostic objects.

### Configuring the VS Code Extension

After installing the Harper VS Code extension, the editor automatically launches `harper-ls`. Users can customize the server path via settings:

```json
{
  "harper.languageserver.command": "harper-ls",
  "harper.languageserver.args": []
}

```

The extension communicates with the binary specified in [[`harper-ls/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-ls/src/main.rs)](https://github.com/Automattic/harper/blob/master/harper-ls/src/main.rs) to provide file diagnostics.

### Desktop IPC Communication

The Tauri-based desktop app uses internal IPC for dictionary management:

```typescript
import { Client } from "./client";

await Client.addToDictionary("foobar");   // adds a word to the user dictionary

```

This TypeScript frontend method corresponds to the Rust message handlers in the desktop communication layer.

## Summary

- **Automattic Harper** is a Rust-centric grammar engine distributed as a monorepo with multiple runtime targets.
- The **core engine** in `harper-core` powers all integrations through a shared rule set.
- **WebAssembly compilation** via `harper-wasm` enables browser and Node.js usage without native binaries.
- **Editor support** spans VS Code, Neovim, Obsidian, and browsers through LSP and extension wrappers.
- **Privacy architecture** ensures all processing occurs locally, with no data transmitted to external servers.
- **Testing strategy** includes Rust unit tests, plugin integration tests, and Playwright-based browser extension validation.

## Frequently Asked Questions

### What programming languages does Automattic Harper use?

Harper is primarily written in **Rust** for the core engine, language server, and CLI. The desktop application combines Rust (Tauri backend) with **TypeScript** and **Svelte** for the frontend. JavaScript/TypeScript wrappers facilitate WebAssembly integration for Node.js and browser environments.

### How does Harper keep my data private?

Harper processes all grammar checks locally on your device using the compiled Rust core or WebAssembly module. Because the engine runs entirely offline without cloud API calls, sensitive text never leaves your machine, whether you use the VS Code extension, desktop app, or browser plugin.

### Can I use Harper without installing a desktop application?

Yes. Harper distributes its functionality through multiple channels: you can use the **VS Code extension**, **Obsidian plugin**, **Chrome/Firefox extensions**, or **Node.js package** ([`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js)) without installing the standalone Tauri desktop application. Each option leverages the same WebAssembly-compiled core engine.

### Where are the grammar rules defined in the source code?

All grammar rules reside in the **core library** within the `harper-core/src` directory. This centralized approach ensures that whether you run Harper via the language server, JavaScript wrapper, or desktop app, you receive identical diagnostics generated by the same Rust logic.