v2.0.0
Automattic/harperv2.0.0Apr 8, 2026by github-actions[bot]
AI Summary
Major version bump focusing on optimizing the JavaScript/WASM bundle structure for better tree-shaking and smaller bundle sizes.
Key Highlights
- Breaking change: `binary` import moved from `harper.js` to `harper.js/binary`
- New shell completions subcommand
- Dark mode auto-detection from OS preferences
- Quarto qmd file support
Breaking Changes
- Import structure changed: `binary` must be imported from `harper.js/binary` instead of `harper.js`
New Features
- Shell completion generation
- OS dark mode detection
- Quarto qmd support
- Obsidian WASM bundle size optimization
Full Release Notes
## What's Changed
Hey all! We're finally releasing Harper 2.0. Why?
It isn't because we have any new groundbreaking features in this release, because we don't let major versioning stop us from pushing those out as soon as they're ready. It's because we have some breaking changes.
The biggest one only applies to you if you consume `harper.js`. From now on, instead of importing your binary from the main Harper module, you'll import it from one of four specialized modules.
Previously, you'd import the Harper WebAssembly binary with:
```javascript
import { LocalLinter, binary } from "harper.js";
```
As of Harper 2.0, you'll import it like this:
```javascript
import { LocalLinter } from "harper.js";
import { binary } from "harper.js/binary";
```
It's that simple! Thanks to this change, you'll find that your applications are more conducive to tree-shaking and therefore might even be a bit smaller!
In addition to that large breaking change, we also have a bunch of smaller improvements rolling out. I won't go through them one by one, but you're free to read through any of the linked pull requests below.
* refactor(core): use `Option::get_or_insert_with` by @86xsk in https://github.com/Automattic/harper/pull/2977
* test(linting): add comprehensive test cases for were/where lint rule by @estefafdez in https://github.com/Automattic/harper/pull/2984
* feat: means a lot for→means a lot to by @hippietrail in https://github.com/Automattic/harper/pull/2982
* feat: add subcommand to generate shell completions by @deckstose in https://github.com/Automattic/harper/pull/2978
* refactor(core): extract indefinite article logic into its own module by @mvanhorn in https://github.com/Automattic/harper/pull/2980
* feat(web): auto-detect dark theme from OS preference in https://github.com/Automattic/harper/pull/2963
* build(deps): bump tar from 0.4.44 to 0.4.45 by @dependabot[bot] in https://github.com/Automattic/harper/pull/2986
* feat: as evident by -> as evidenced by by @mvanhorn in https://github.com/Automattic/harper/pull/2985
* fix(core): `SplitWords` allowing uncommon merges by @elijah-potter in https://github.com/Automattic/harper/pull/2874
* feat: add lint rule for flaunt/flout mix-up in https://github.com/Automattic/harper/pull/2962
* test: add regression tests for need_to_noun false positives (#2320) by @majiayu000 in https://github.com/Automattic/harper/pull/3014
* fix: case-insensitive same-form check in SimplePastToPastParticiple by @saschabuehrle in https://github.com/Automattic/harper/pull/3012
* build(deps): bump pulldown-cmark from 0.13.1 to 0.13.3 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3002
* build(deps): bump tree-sitter-rust from 0.24.0 to 0.24.1 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3003
* build(deps): bump zip from 8.1.0 to 8.3.1 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3000
* build(deps): bump cached from 0.56.0 to 0.59.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3001
* chore(harper.js): update `raw-web` example to `1.12.0` by @elijah-potter in https://github.com/Automattic/harper/pull/3015
* feat: "a" & "an" both OK for "URL" by @hippietrail in https://github.com/Automattic/harper/pull/2981
* feat: except of→except for / exception of by @hippietrail in https://github.com/Automattic/harper/pull/2997
* build(deps): bump rustls-webpki from 0.103.8 to 0.103.10 by @dependabot[bot] in https://github.com/Automattic/harper/pull/2991
* feat: aspire for → aspire to by @hippietrail in https://github.com/Automattic/harper/pull/3004
* docs: added link to agent policy by @elijah-potter in https://github.com/Automattic/harper/pull/3016
* fix(lint-framework): reconnect popup host after DOM replacement by @k4sperski in https://github.com/Automattic/harper/pull/2998
* fix(harper-cli): return exit code 0 when no lints are found by @Ryujiyasu in https://github.com/Automattic/harper/pull/2836
* chore: dictionary curation 2026-03-19 by @hippietrail in https://github.com/Automattic/harper/pull/2968
* Added native Neovim LSP config to docs by @RobertCrummett in https://github.com/Automattic/harper/pull/2987
* fix: don't flag "more orange than red" etc. by @hippietrail in https://github.com/Automattic/harper/pull/2928
* perf(core): cache `WordSet` in `ModalVerb` by @86xsk in https://github.com/Automattic/harper/pull/3017
* feat: flag "use to" when "used to" is intended in https://github.com/Automattic/harper/pull/2975
* feat: flag nonstandard "verse" used as a verb (from "versus") in https://github.com/Automattic/harper/pull/2973
* feat: flag "date back from" as blend of "date from" and "date back to" in https://github.com/Automattic/harper/pull/2976
* feat(core): allow users to include dictionaries in Weirpacks by @elijah-potter in https://github.com/Automattic/harper/pull/2922
* feat: try out one's luck→try one's luck by @hippietrail in https://github.com/Automattic/harper/pull/2916
* fix(chrome-ext): reverse the toggle button to it appears "on" by @elijah-potter in https://github.com/Automattic/harper/pull/3026
* chore: dictionary curation by @hippietrail in https://github.com/Automattic/harper/pull/3023
* Improve embedded form support in iframes by @k4sperski in https://github.com/Automattic/harper/pull/3010
* refactor: compact token/lint content & char comparison by @hippietrail in https://github.com/Automattic/harper/pull/2957
* feat: expression to match pronoun-be, word pair or contraction by @hippietrail in https://github.com/Automattic/harper/pull/2944
* fix(chrome-ext): persist lint rule changes from settings page by @queelius in https://github.com/Automattic/harper/pull/3028
* feat: in 1 day from now→in one day/one day from now by @hippietrail in https://github.com/Automattic/harper/pull/3049
* build(deps): bump tree-sitter-ink-lbz from 0.0.1 to 0.0.5 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3064
* build(deps): bump ordered-float from 5.1.0 to 5.3.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3063
* build(deps): bump zip from 8.3.1 to 8.4.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3065
* feat: support Quarto qmd files as markdown by @itamarst in https://github.com/Automattic/harper/pull/3053
* feat: thrive off (of)→thrive on by @hippietrail in https://github.com/Automattic/harper/pull/3055
* perf(core): optimizations in `LintGroup` by @86xsk in https://github.com/Automattic/harper/pull/3052
* feat: worth while/worth-while → worthwhile by @hippietrail in https://github.com/Automattic/harper/pull/3056
* refactor(core)!: `Lrc<[char]>` instead of `Lrc<Vec<char>>` by @86xsk in https://github.com/Automattic/harper/pull/3060
* chore: dictionary curation by @hippietrail in https://github.com/Automattic/harper/pull/3041
* build(deps): bump tree-sitter-rust from 0.24.1 to 0.24.2 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3061
* fix(obsidian): OOM error by reducing WASM bundle size by @elijah-potter in https://github.com/Automattic/harper/pull/3050
* build(deps): bump tree-sitter-scala from 0.24.0 to 0.25.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3062
* fix(lint): add 'side' to ignore list for effect/affect rule (fix issue #2958) by @estefafdez in https://github.com/Automattic/harper/pull/2983
* perf(spell): skip redundant lowercase DFA search in FstDictionary by @k4sperski in https://github.com/Automattic/harper/pull/3025
* refactor!: take argument by value instead of mut ref by @86xsk in https://github.com/Automattic/harper/pull/3051
* feat: Sneaked vs snuck by @hippietrail in https://github.com/Automattic/harper/pull/2209
* feat: skeleton for new `ExprLinter` modules by @hippietrail in https://github.com/Automattic/harper/pull/3024
* feat: web scrapping → web scraping by @hippietrail in https://github.com/Automattic/harper/pull/3059
* fix: add key stroke→keystroke to key stoke→keystroke by @hippietrail in https://github.com/Automattic/harper/pull/3067
* perf(core): avoid conversion between string and char array by @86xsk in https://github.com/Automattic/harper/pull/3074
* fix: don't flag "each of whom" by @hippietrail in https://github.com/Automattic/harper/pull/3078
* docs(web): add link to @KraXen72's work by @elijah-potter in https://github.com/Automattic/harper/pull/3079
* feat: at all cost → at all costs by @hippietrail in https://github.com/Automattic/harper/pull/3082
* fix(core): address recent false positives and negatives by @elijah-potter in https://github.com/Automattic/harper/pull/3090
* feat: add styling for user-defined monospace fonts by @stanley-910 in https://github.com/Automattic/harper/pull/3105
* feat: I am bias/you are prejudice→biased/prejudiced by @hippietrail in https://github.com/Automattic/harper/pull/3058
* fix: don't flag "to" before "only" in ToTwoToo by @joaquinhuigomez in https://github.com/Automattic/harper/pull/3093
* feat: ppl→people by @hippietrail in https://github.com/Automattic/harper/pull/3116
* feat/obsidian web lint styling by @stanley-910 in https://github.com/Automattic/harper/pull/3104
* fix(lint-framework): preserve cursor position when dismissing suggestion popup by @draphy in https://github.com/Automattic/harper/pull/3112
* build(deps): bump uuid from 1.22.0 to 1.23.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3117
* fix: skip PronounVerbAgreement for hyphenated compounds by @mvanhorn in https://github.com/Automattic/harper/pull/3095
* fix(harper-tex): mask additional LaTeX math environments by @jurajkl in https://github.com/Automattic/harper/pull/3103
* feat: look forward for→look forward to by @hippietrail in https://github.com/Automattic/harper/pull/3109
* build(deps): bump tempfile from 3.20.0 to 3.27.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3118
* build(deps): bump indexmap from 2.13.0 to 2.13.1 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3121
* build(deps): bump tracing-subscriber from 0.3.22 to 0.3.23 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3120
* build(deps): bump zip from 8.4.0 to 8.5.0 by @dependabot[bot] in https://github.com/Automattic/harper/pull/3119
* fix(core): exclude prepositions and conjunctions from QuiteQuiet pattern by @draphy in https://github.com/Automattic/harper/pull/3127
* feat: arrive to → arrive at/in by @hippietrail in https://github.com/Automattic/harper/pull/3125
* feat(core): create `UseEllipsisCharacter` rule by @elijah-potter in https://github.com/Automattic/harper/pull/3099
* Fix indentation handling in harper-tex by @jurajkl in https://github.com/Automattic/harper/pull/3106
* feat: will ran → will run / ran by @hippietrail in https://github.com/Automattic/harper/pull/2268
* feat: in the best of times→at the best of times by @hippietrail in https://github.com/Automattic/harper/pull/3133
* feat: render configuration structurally by @elijah-potter in https://github.com/Automattic/harper/pull/3123
* fix(chrome-ext): issues with Google Docs by @elijah-potter in https://github.com/Automattic/harper/pull/3141
## New Contributors
* @estefafdez made their first contribution in https://github.com/Automattic/harper/pull/2984
* @deckstose made their first contribution in https://github.com/Automattic/harper/pull/2978
* @mvanhorn made their first contribution in https://github.com/Automattic/harper/pull/2980
* @majiayu000 made their first contribution in https://github.com/Automattic/harper/pull/3014
* @saschabuehrle made their first contribution in https://github.com/Automattic/harper/pull/3012
* @k4sperski made their first contribution in https://github.com/Automattic/harper/pull/2998
* @Ryujiyasu made their first contribution in https://github.com/Automattic/harper/pull/2836
* @RobertCrummett made their first contribution in https://github.com/Automattic/harper/pull/2987
* @queelius made their first contribution in https://github.com/Automattic/harper/pull/3028
* @itamarst made their first contribution in https://github.com/Automattic/harper/pull/3053
* @joaquinhuigomez made their first contribution in https://github.com/Automattic/harper/pull/3093
* @jurajkl made their first contribution in https://github.com/Automattic/harper/pull/3103
**Full Changelog**: https://github.com/Automattic/harper/compare/v1.12.0...v2.0.0