# Main Modules in Automattic Harper: A Complete Architecture Breakdown

> Explore the nine core modules of Automattic Harper. This architecture breakdown reveals the grammar-checking platform's Rust, WebAssembly, and JavaScript components.

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

---

**The Automattic Harper project organizes its grammar-checking platform into nine distinct modules spanning Rust crates, WebAssembly bindings, JavaScript packages, and desktop applications, all unified under a single monorepo workspace.** These components range from the core linting engine to language-server-protocol implementations and browser extensions.

Harper is an open-source grammar checker designed to run everywhere—from browsers to native desktop apps—while maintaining a single Rust-based core for its linguistic logic. Understanding the main modules in Automattic Harper helps developers choose the right integration path, whether they need a command-line tool, a library for their web app, or a full desktop experience. Each module lives in the repository root as a separate crate or package, tied together by a shared Cargo workspace and pnpm configuration.

## Core Rust Modules

The foundation of Harper rests on several specialized Rust crates that handle everything from basic linting to document-specific parsing.

### harper-core: The Grammar Engine

**`harper-core`** is the language-agnostic heart of the system. Located in the `harper-core` directory, this crate contains the actual grammar-checking logic that all other modules consume.

In [`harper-core/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-core/src/lib.rs), the crate defines the public API for linting documents, including text parsing and span generation. Every other component—from the CLI to the WASM build—depends on this crate for the actual linguistic analysis. When you invoke a lint function anywhere in the Harper ecosystem, it ultimately calls into this core library.

### harper-ls: Language Server Protocol Implementation

**`harper-ls`** exposes Harper’s capabilities to modern editors through the Language Server Protocol (LSP). Found in the `harper-ls` crate, this module bridges the core engine with IDE features like real-time diagnostics and code actions.

The entry point at [`harper-ls/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-ls/src/main.rs) initializes the LSP server and wires the core linter to editor requests, supporting VS Code, Neovim, Helix, Zed, and other LSP-compatible editors.

### harper-cli: Command-Line Interface

**`harper-cli`** provides a standalone binary for debugging and direct usage of the core engine. This crate handles argument parsing and file I/O for quick linting tasks without editor integration.

The [`harper-cli/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-cli/src/main.rs) file parses CLI arguments and forwards text directly to the core linter, making it useful for CI/CD pipelines or quick local checks.

### harper-wasm: WebAssembly Bindings

**`harper-wasm`** compiles the Rust core to WebAssembly, enabling browser and Node.js usage. The crate at `harper-wasm` exposes a `wasm_bindgen` API that [`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js) consumes.

The entry point in [`harper-wasm/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-wasm/src/lib.rs) wraps core functionality for JavaScript environments, allowing the grammar engine to run in web pages without server-side processing.

### harper-typst: Document-Specific Parsing

**`harper-typst`** extends the core engine with support for Typst documents. This integration parses Typst ASTs and translates them into Harper spans for linting academic papers and technical documents.

Located in [`harper-typst/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-typst/src/lib.rs), this module serves as the entry point for translating Typst-specific syntax while leveraging the same linting rules as the main engine.

### harper-thesaurus: Lexical Resources

**`harper-thesaurus`** powers synonym suggestions and enriched spelling checks. This auxiliary crate loads static word-frequency lists and thesaurus data used by the main linter to suggest corrections.

The [`harper-thesaurus/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-thesaurus/src/lib.rs) file initializes these lexical resources, which the core engine references when generating spelling hints and style improvements.

## JavaScript and Web Ecosystem

Harper’s web presence relies on a layered JavaScript architecture that wraps the WebAssembly build.

### harper.js: The JavaScript API

**[`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js)** (located in [`packages/harper.js`](https://github.com/Automattic/harper/blob/main/packages/harper.js)) provides a friendly JavaScript façade around the WASM module. The [`packages/harper.js/src/index.ts`](https://github.com/Automattic/harper/blob/main/packages/harper.js/src/index.ts) file loads the WebAssembly bundle and re-exports high-level functions like `lint` and `configure`.

This package allows Node.js and browser applications to use Harper without managing the WebAssembly compilation directly.

### Web Demo and Documentation Site

**`packages/web`** houses the public Harper website, built with Vite and SvelteKit. The `packages/web/src/routes/+layout.svelte` file bootstraps the demo UI that showcases the linting flow in real-time.

This module serves as both documentation and a live playground for testing Harper’s capabilities against sample text.

## Desktop and Plugin Integrations

Beyond core libraries, Harper ships with native applications and thin wrapper plugins for various ecosystems.

### harper-desktop: Tauri Application

**`harper-desktop`** is a cross-platform desktop application built with Tauri v2. Located in the `harper-desktop` directory, this crate combines a web-based UI with native overlay highlighting capabilities.

The entry point at [`harper-desktop/src-tauri/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-desktop/src-tauri/src/main.rs) launches the Tauri window and manages the highlighter service, providing system-native grammar checking that works across macOS, Windows, and Linux.

### Editor Plugins and Extensions

**`packages/*-plugin`** directories contain thin wrappers for Chrome, Firefox, VS Code, Obsidian, WordPress, and other platforms. These plugins typically delegate to either [`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js) or the LSP server, depending on the host environment’s capabilities.

Each plugin’s [`src/manifest.json`](https://github.com/Automattic/harper/blob/main/src/manifest.json) or [`src/main.ts`](https://github.com/Automattic/harper/blob/main/src/main.ts) serves as the integration point, embedding Harper into existing workflows with minimal overhead.

## How the Modules Connect

All modules share a common **workspace configuration** defined in the root [`Cargo.toml`](https://github.com/Automattic/harper/blob/main/Cargo.toml) and [`pnpm-workspace.yaml`](https://github.com/Automattic/harper/blob/main/pnpm-workspace.yaml). This monorepo structure ensures that the heavy-weight Rust core remains the single source of truth while allowing flexible deployment across native, WASM, and JavaScript runtimes.

The architecture follows a deliberate layering pattern: `harper-core` contains the logic, `harper-wasm` exposes it to the web, [`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js) simplifies the API, and various consumer modules (desktop, plugins, CLI) provide the final user interface.

## Getting Started with Each Module

To use Harper from the command line, install and run the CLI:

```bash

# Install from source

cargo install --path harper-cli

# Lint a Markdown file

harper-cli lint example.md

```

For JavaScript projects, import the high-level API:

```javascript
import { lint } from "harper.js";

const text = "She don't know nothing.";
const result = await lint(text, { dialect: "american" });

console.log(result.lints);
// → [{ message: "Double negative", ... }]

```

To start the LSP server for editor integration:

```bash

# Run the language server

cargo run -p harper-ls -- --stdio

```

For desktop application development, invoke the core through Tauri commands:

```typescript
// src/lib/client.ts
import { invoke } from "@tauri-apps/api/tauri";

export async function lintDocument(text: string) {
  return invoke("lint_text", { text });
}

```

## Summary

- **harper-core** ([`src/lib.rs`](https://github.com/Automattic/harper/blob/main/src/lib.rs)) provides the grammar-checking engine that all other modules depend on.
- **harper-ls** exposes linting via Language Server Protocol for editor integration.
- **harper-cli** offers standalone command-line access for scripts and debugging.
- **harper-wasm** compiles the core to WebAssembly for browser environments.
- **harper.js** wraps the WASM build with a TypeScript-friendly API.
- **harper-desktop** delivers a native Tauri-based application with overlay highlighting.
- **harper-typst** adds document-specific support for the Typst markup language.
- **harper-thesaurus** supplies lexical data for spelling suggestions and synonyms.
- **Editor plugins** distribute Harper through marketplace extensions for browsers and IDEs.

## Frequently Asked Questions

### What is the entry point for the core grammar engine?

The core grammar engine initializes in [`harper-core/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-core/src/lib.rs), which defines the public API for document parsing and lint generation. All other modules, whether compiling to native code or WebAssembly, import this crate to access the actual linguistic logic.

### How does Harper support browser usage?

Harper compiles its Rust core to WebAssembly through the `harper-wasm` crate, then wraps it with the [`harper.js`](https://github.com/Automattic/harper/blob/main/harper.js) package. The `wasm_bindgen` exports in [`harper-wasm/src/lib.rs`](https://github.com/Automattic/harper/blob/main/harper-wasm/src/lib.rs) allow JavaScript environments to load and execute the grammar checker without requiring a server backend.

### Can I use Harper as a language server in my editor?

Yes. The `harper-ls` crate implements the Language Server Protocol, starting from [`harper-ls/src/main.rs`](https://github.com/Automattic/harper/blob/main/harper-ls/src/main.rs). You can run it directly with `cargo run -p harper-ls -- --stdio` or install it globally to provide real-time grammar checking in LSP-compatible editors like Neovim, VS Code, or Helix.

### Where is the architecture documented beyond source files?

The repository includes an [`ARCHITECTURE.md`](https://github.com/Automattic/harper/blob/main/ARCHITECTURE.md) file at the root that provides a canonical description of component interactions and data flow. This document explains how the Rust crates, JavaScript packages, and plugin wrappers communicate to provide a unified grammar-checking experience across platforms.