What Scripting Languages Are Used in Automattic/harper? A Complete Guide

The Harper project uses JavaScript/TypeScript, Python, Shell (Bash), and Ruby as its primary scripting languages, wrapping a high-performance Rust core that provides the actual grammar and spell checking engine.

The Automattic/harper repository is a polyglot codebase that combines a compiled Rust core with multiple scripting languages to power its linter ecosystem. While the core engine is written in Rust and compiled to WebAssembly for portability, the project relies on JavaScript, Python, Shell scripts, and Ruby to handle integration, tooling, and testing across different platforms.

JavaScript and TypeScript: Web Integration and Browser Extensions

Harper uses JavaScript and TypeScript extensively for its web-facing components. The packages/web/package.json defines the web package dependencies, while browser extensions like the Chrome plugin are implemented in TypeScript. The harper.js NPM package bundles the WebAssembly core for use in Node.js or browsers.

Key files include:

import { Linter } from 'harper.js';

// Initialise a Linter with default config
const linter = new Linter();

// Lint a markdown string
const result = await linter.lint('This is a testt.'); // typo on purpose

console.log(result.lints[0].message); // → "Possible misspelling: testt"

Source: packages/harper.js/examples/commonjs-simple/index.ts

Python: Native Language Bindings

The harper-python wrapper exposes Harper's functionality to Python environments. The binding layer is implemented in harper-python/src/lib.rs, which provides Python access to the underlying Rust Linter struct. Tests reside in harper-python/tests/test_sources/comments.py.

from harper_python import Linter

linter = Linter()
result = linter.lint("She has an eleganty style.")   # typo on purpose

print(result.lints[0].message)  # → "Possible misspelling: eleganty"

Source: harper-python/src/lib.rs

Shell (Bash): Build Scripts and CLI Automation

Shell scripts handle build automation, CI helpers, and CLI demonstrations. The file packages/harper.js/docs.sh demonstrates how to invoke the harper-cli binary from shell scripts for documentation generation tasks.

#!/usr/bin/env bash

# Run Harper on a markdown file

harper-cli lint ./docs/example.md

Source: packages/harper.js/docs.sh

Ruby: Test Fixtures for Language Parsing

Ruby appears specifically as test fixtures in the VS Code plugin. The file packages/vscode-plugin/src/tests/fixtures/languages/ruby.rb provides sample Ruby code used to test the parser's ability to handle Ruby-specific comment syntax and language constructs.


# frozen_string_literal: true

module Languages
  RUBY = <<~RUBY
    # This is a comment

    class HelloWorld
      def greet
        puts 'Hello, world!'
      end
    end
  RUBY
end

Source: packages/vscode-plugin/src/tests/fixtures/languages/ruby.rb

Summary

  • Harper combines a Rust core with JavaScript/TypeScript, Python, Shell, and Ruby scripting layers.
  • JavaScript/TypeScript powers the web interface, browser extensions, and Node.js bindings via harper.js.
  • Python bindings allow programmatic access through the harper-python package.
  • Shell scripts automate builds and demonstrate CLI usage in packages/harper.js/docs.sh.
  • Ruby serves as test fixtures for language-specific parsing in the VS Code plugin.

Frequently Asked Questions

Is Harper written entirely in Rust?

No. While the core grammar and spell checking engine in harper-core is written in Rust (including the Weir rule language implemented in harper-core/src/weir/mod.rs), the project uses JavaScript/TypeScript, Python, Shell, and Ruby for integration, bindings, and tooling.

Can I use Harper as a JavaScript library?

Yes. Harper is distributed as the harper.js NPM package, which bundles the Rust core as WebAssembly. You can import the Linter class from harper.js in Node.js or browser environments, as shown in packages/harper.js/examples/commonjs-simple/index.ts.

How does Harper integrate with Python?

Harper provides a Python wrapper via the harper-python package. The integration uses Rust binding techniques exposed in harper-python/src/lib.rs to wrap the Rust Linter struct, making it available as a native Python module that you can import and use programmatically.

Why does the repository contain Ruby code if it's not a primary language?

Ruby appears only in test fixtures located at packages/vscode-plugin/src/tests/fixtures/languages/ruby.rb. These files test Harper's ability to parse Ruby comments and syntax correctly within the VS Code extension, ensuring the linter works across multiple programming languages.

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 →