Brainstorming a Harper Service

SaaS prod­ucts are all the rage these days. His­tor­i­cally, Harper has po­si­tioned it­self as lo­cal-first, which many of­ten view as anti-SaaS. That is not the case.

I de­scribe Harper as local-first” be­cause it is prin­ci­pally meant to be run lo­cally, mean­ing that your data does­n’t leave your de­vice. Pri­vacy is one of our core be­liefs, and be­ing local-first” is part of how we honor that.

Given Harper’s po­si­tion on pri­vacy, dis­cus­sion of a cen­tral­ized ser­vice (running on a server) might seem strange. To­day, I want to ex­plain why a cen­tral­ized ser­vice is nec­es­sary, how we in­tend to tackle it as part of the open source pro­ject, and how it’s ex­is­tence will not stand to af­fect our users’ pri­vacy in any way.

Why We Need It Now

User’s de­spise false-pos­i­tives in Harper’s gram­mar en­gine.

We’ll of­ten make a mod­i­fi­ca­tion, test it as much as pos­si­ble in­ter­nally, and re­lease it, only for a user to dis­cover false-pos­i­tives on their col­lege es­say. We’ve sig­nif­i­cantly re­duced their fre­quency through tech­niques like LLM-Assisted Fuzzing and ar­ti­fi­cial se­lec­tion, but they per­sist.

Far and wide, most of the time be­tween when we get a bug re­port and when we get a fix into pro­duc­tion is spent do­ing mean­ing­less paperwork”. Reading through is­sues, writ­ing boil­er­plate code for tests, and prepar­ing pull re­quests take up a lot of time. I want to up­end this en­tire loop and find a sim­pler way to it­er­ate on false-pos­i­tives.

The first step in this process is re­duc­ing the over­head for users to re­port them in the first place. In­stead of fil­ing an is­sue, I’d love for user’s to be able to push a but­ton have have all rel­e­vant con­text sent di­rectly to our in­boxes. Not GitHub ac­count re­quired, no fuss.

Obviously, we won’t be send­ing any in­for­ma­tion with­out clearly dis­clos­ing the pre­cise data be­ing sent from the client.

Since these re­ports will be in a struc­tured for­mat, we can bun­dle fixes into larger batches, re­duc­ing over­head (and po­ten­tially mak­ing things eas­ier for LLMs). The Harper pro­jec­t’s abil­ity to con­tin­u­ously and sur­gi­cally im­prove our ser­vice is part of what sets us apart from our com­peti­tors. It’s rare for user feed­back to have such a di­rect im­pact on Grammarly’s core en­gine.

This is just the start. Once we’ve proven that we can main­tain such a sys­tem for our users, we will move on to more am­bi­tious goals.

How We Plan to Make It Happen

I’ve had suc­cess with these tech­nolo­gies in the past, and be­lieve they’ll work quite well for our ini­tial use-case, and scale quite nicely as the ser­vice be­comes more ca­pa­ble.

SvelteKit

Harper’s web­site is al­ready built us­ing SvelteKit. It works. Why mess with suc­cess?

Database: SQLite with Drizzle

On mod­ern hard­ware, SQLite can han­dle tens of thou­sands of trans­ac­tions per sec­ond. Since Harper (as a rule) will place lit­tle load on the ser­vice per-user, I ex­pect SQLite can ser­vice our needs for a long time. When that time ex­pires, Drizzle (an ORM) makes it triv­ial to move to a more ro­bust data­base down the road (I imag­ine PostgreSQL).

For the mo­ment, it­er­a­tion speed is para­mount. I want to move fast. To that end, James and I have dis­cussed host­ing every­thing on a small VPS, and we agree it’s the best choice.

Auth.JS

Authentication is not some­thing any­one should roll on their own. Auth.JS is a proven so­lu­tion that bun­dles well with Drizzle to build­ing out user pro­files, au­then­ti­ca­tion pages, and every­thing in-be­tween. The needs of the pro­ject won’t ne­ces­si­tate this right away. When the time comes, us­ing Auth.JS (from my ex­pe­ri­ence) will shorten the auth prob­lem down from weeks to just hours.

The Future

I’m thrilled that we’re fi­nally mov­ing in this di­rec­tion. Be­ing lo­cal-only has taken us far, but loos­en­ing the reigns to be more sim­ply local-first” will al­low us to tackle more in­ter­est­ing prob­lems and pro­vide more value to our users. I can’t wait to get started.

Published September 29, 2025 at 6:00 AM

Proofread by Harper.

Comments

Gravatar for potter.protrude118@passmail.net
Renato

That seems like a useful idea. I still think users would like a local-first only option. Like, consent when sending any information.

Gravatar for me@elijahpotter.dev
Elijah Potter

I agree. To begin, I am imagining a popup with a literal JSON string showing the user exactly what will be sent to us.