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:
packages/web/package.json- Web package configurationpackages/chrome-plugin/src/contentScript/googleDocs.ts- Google Docs integrationpackage.json(repo root) - Monorepo scripts and dev dependencies
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-pythonpackage. - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →