Configuration Files for Automattic/Harper: The Complete Guide to Engine, LSP, and Desktop Customization

Harper provides three primary configuration assets—harper-core/default_config.json, harper-ls/src/config.rs, and harper-desktop/src-tauri/src/config.rs—that control lint rules, language-server behavior, and desktop application settings.

The Harper grammar and spell checker organizes its configuration across three distinct layers: engine-wide defaults, language-server runtime options, and desktop application persistence. Understanding these configuration files for Automattic/Harper allows developers to customize linting rules, integrate Harper into editors like VS Code, and manage user preferences in the standalone desktop application.

The Three Core Configuration Files

Harper's configuration architecture separates concerns between the core linting engine, the LSP client, and the desktop GUI. Each layer has a dedicated configuration source written in either JSON or Rust.

Engine Defaults: harper-core/default_config.json

The file harper-core/default_config.json supplies the curated default lint configuration for the entire Harper ecosystem. This JSON file defines enabled rules, rule-specific options, and dialect defaults (such as American vs. British English). When Harper initializes a FlatConfig structure, it loads this file as the baseline configuration.

According to the Automattic/harper source code, this file lives in the harper-core crate and serves as the fallback when no user-specific overrides are provided.

Language Server Settings: harper-ls/src/config.rs

The Rust module harper-ls/src/config.rs defines the runtime configuration for the Harper Language Server (harper-ls). This implementation parses the LSP settings object received from editors, resolving paths for user dictionaries, ignored-lint storage, and statistical tracking.

Key configuration options handled here include:

  • userDictPath: Path to custom user dictionary files
  • dialect: Language variant (American, British, Canadian, Australian)
  • diagnosticSeverity: Error level mapping (Error, Warning, Information, Hint)
  • maxFileLength: Maximum file size to lint (default 200,000 bytes)
  • excludePatterns: Glob patterns for files to skip
  • codeActions: Code action configuration including ForceStable

The Config::from_lsp_config function deserializes these values from editor-specific JSON into Rust structs.

Desktop Application Persistence: harper-desktop/src-tauri/src/config.rs

The file harper-desktop/src-tauri/src/config.rs manages desktop-app configuration persisted to config.json on disk. This Rust struct aggregates mutable user data including the custom dictionary, active dialect, ignored lints, and the FlatConfig ruleset. It also stores integration settings for browser extensions and editor plugins.

Tauri commands share this Config struct between the Rust backend and the frontend TypeScript code, enabling real-time updates when users change settings in the GUI.

Configuring the Harper Language Server

To override Harper's behavior in VS Code or other LSP-compatible editors, place a configuration object under the "harper-ls" key in your editor settings. Harper reads these values through the Config::from_lsp_config implementation.

{
  "harper-ls": {
    "userDictPath": ".harper-dictionary.txt",
    "dialect": "British",
    "diagnosticSeverity": "Warning",
    "maxFileLength": 200000,
    "excludePatterns": [
      "**/node_modules/**",
      "**/*.min.js"
    ],
    "codeActions": {
      "ForceStable": true
    }
  }
}

This JSON maps directly to the Config struct in harper-ls/src/config.rs, overriding the defaults specified in harper-core/default_config.json.

Customizing Lint Rules in Rust Programs

When using Harper as a library in your own Rust projects, you can bypass the default configuration and load custom lint rules from any JSON file following the default_config.json schema.

use harper_core::linting::FlatConfig;
use std::fs;

fn load_custom_config() -> FlatConfig {
    let json = fs::read_to_string("my_lint_config.json")
        .expect("unable to read custom config");
    serde_json::from_str(&json)
        .expect("invalid lint config JSON")
}

This approach instantiates a FlatConfig directly from your JSON file, allowing complete control over which rules are enabled and their specific parameters.

Managing Desktop App Settings

The Harper desktop application persists user preferences via Tauri commands that interact with the configuration struct in harper-desktop/src-tauri/src/config.rs.

import { Client } from "./client";

async function changeDialect() {
  await Client.setDialect("Canadian");
  // The desktop backend writes the new value into config.json
}

This updates the persisted Config struct, which survives application restarts and syncs between the Rust backend and the web-based frontend.

Summary

  • harper-core/default_config.json provides the baseline lint rules and dialect defaults for the entire Harper engine.
  • harper-ls/src/config.rs parses editor settings via Config::from_lsp_config, handling dictionaries, exclusions, and severity levels.
  • harper-desktop/src-tauri/src/config.rs manages persistent user preferences for the desktop application, including integration toggles and custom dictionaries.
  • All three files work together to provide engine defaults, LSP overrides, and desktop persistence across the Harper ecosystem.

Frequently Asked Questions

Where is the default lint configuration stored?

The default lint configuration resides in harper-core/default_config.json within the repository root. This JSON file defines the initial rule set, dialect preferences, and rule-specific options that Harper uses when no user configuration is provided.

How do I override Harper settings in VS Code?

Add a "harper-ls" object to your VS Code settings.json file. This JSON is parsed by the Config::from_lsp_config function in harper-ls/src/config.rs, allowing you to specify options like dialect, diagnosticSeverity, and excludePatterns directly in your editor configuration.

What configuration options does the desktop app support?

The desktop application, implemented in harper-desktop/src-tauri/src/config.rs, supports persistent storage of your custom dictionary, selected dialect, ignored lints, active lint rules (via FlatConfig), and integration settings for browser extensions like Chrome and editors like VS Code.

Can I use a custom lint configuration in my own Rust project?

Yes. Import harper_core::linting::FlatConfig and deserialize your custom JSON configuration file using serde_json. This allows you to instantiate Harper's linting engine with custom rule sets outside the context of the language server or desktop application.

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 →