Skip to content

Grammit

Fix grammar and spelling as you type — all on-device

Overview

Grammit is a private writing assistant in the style of Grammarly. You just type — a moment after you stop, it underlines spelling and grammar issues right under your words. Click an underline to accept the fix. It is part of the kimtos new-tab app suite.

Everything is fully on-device. There is no backend, no account, and no network call: every check runs inside your browser, and the text you write never leaves the machine.

Highlights

  • Live underlines — type or paste text and Grammit flags issues as you go, Grammarly-style, on a backdrop that sits perfectly under your words.
  • Deterministic rules — high-confidence fixes that are always on: common misspellings, missing apostrophes (contractions), the pronoun "I", capitalization, a/an, repeated words, spacing, subject–verb agreement, double negatives, comparatives, then/than, modal + of/to, and contextual homophones (their/there, your/you're, its/it's, to/too).
  • Real spell check — a built-in 60k-word dictionary catches any misspelling, with frequency-ranked suggestions (loaded the first time you use it, no download from a server).
  • Click to fix — clicking an underline opens a popover with one or more suggestions; pick one, type your own correction, or dismiss it.
  • Fix all — apply every current suggestion at once as a single undoable edit.
  • Copy — copy your cleaned-up text to the clipboard.
  • Optional AI deep grammar — an on-device AI model for deeper grammar, off by default. When enabled it downloads once on first use and then runs locally.

Privacy model

Grammit performs all of its analysis on your device:

  • The deterministic rules and the spell-check dictionary run entirely in the browser, with no network access at all.
  • The optional AI model downloads its files once (cached in the browser) and then runs locally; your text is never sent anywhere.
  • There are no analytics and no third-party calls.

Because the whole pipeline is local, your writing stays yours — nothing is uploaded, logged, or shared.

Getting Started

Open Grammit from the dock. You get a single editor — a large text area with a hint above it. Start writing, or paste text in, and Grammit takes care of the rest.

Type and see underlines

Just type. A short moment after you stop (about a beat), Grammit checks your text and draws red wavy underlines beneath anything it wants to fix. The footer shows the status: a spinner while it checks, then either No issues found or a count like 3 suggestions.

While you are actively typing, the underlines clear so they never point at the wrong spot; they reappear once you pause.

Accept a fix by clicking

Click (or move the caret into) an underlined word to open its suggestion popover. From there you can:

  • Accept a suggestion — click one of the suggested replacements. Spelling issues may offer a few candidates, ranked best-first; pick whichever fits.
  • Type your own — use the text field to write a custom correction (for example "repos" → "repositories") and click Apply.
  • Dismiss — wave the suggestion off. Grammit remembers it and won't flag that same word-and-fix again while the window is open.

You can also right-click an underline to open its popover. Every accepted fix joins the editor's native undo history, so ⌘/Ctrl+Z reverses it.

Fix all and copy

The footer has two actions:

  • Fix all — applies every current suggestion at once, as a single undoable edit, then re-checks the rewritten text.
  • Copy — copies the current text to the clipboard, with a brief "Copied!" confirmation.

Optional: AI deep grammar

By default Grammit uses only its fast, instant rule-based and spell-check passes — no download required. For deeper grammar, you can turn on an on-device AI model in the app's settings:

  • AI deep grammar — set this to On to also run the AI model. The fast rule-based checks always run regardless.
  • AI model — choose Base (more accurate, larger download) or Small (faster, weaker, smaller download).

The model downloads once on first use (you'll see a "Downloading model" percentage in the footer), is cached in the browser, and then runs locally on later checks. As with everything in Grammit, your text never leaves the browser. If the model can't be loaded, Grammit keeps showing the rule and spelling results and notes that the deep check is unavailable.

You can also turn the built-in Spell check off in settings if you only want the deterministic rules.

Architecture

Grammit is built from three independent on-device checking layers whose results are merged into one set of underlines. The app shell lives in extension/src/apps/grammit/index.ts; the checking layers live in extension/src/lib/. Nothing in this pipeline talks to a server.

The three layers

Layer 1 — deterministic rules (lib/grammarRules/). A set of hand-written, high-confidence rules with no model required. They run instantly and cover misspellings from a curated typo list, contractions, the pronoun "I", sentence capitalization, a/an, repeated words, spacing, subject–verb agreement (via a real conjugator, both directions), double negatives, comparatives, then/than, modal + of/to, and contextual homophones. The exported ruleIssues(text) returns a sorted, non-overlapping list of issues. These rules are tuned for no false positives — they only fire when the fix is unambiguous.

Layer 2 — spell check (lib/spellcheck.ts). A real dictionary speller backed by a 60k-word, frequency-ordered English word list. It catches any misspelling the rule list doesn't know, and generates suggestions Norvig-style (all words within edit distance 1–2) ranked by frequency. The word list is loaded lazily — only the first time spell check actually runs — so opening the app costs nothing. Guards keep it quiet on proper nouns, acronyms, short words, and known tech terms.

Layer 3 — optional AI model (lib/engines/grammar.ts). An on-device FLAN-T5 sequence-to-sequence model (via Transformers.js, ONNX/WASM) for deeper grammar. It is off by default, downloads its files once on first use (cached in the browser), and then runs locally. Grammit checks the text sentence by sentence, diffs each corrected sentence against the original with lib/textDiff.ts, and keeps only changes that genuinely resemble the input (rewrites and hallucinations are rejected by trustworthy()).

The three layers are merged so that higher-confidence results win: rules first, then spelling for spans the rules didn't cover, then any AI suggestion that doesn't overlap an existing one.

Modules

FileRole
apps/grammit/index.tsThe app descriptor and UI — the editor, the underline backdrop, the suggestion popover, Fix all / Copy, debounced live checking, and merging the three layers.
lib/grammarRules/Layer 1 — deterministic rules (ruleIssues(text) in index.ts, rule set in rules.ts, data tables in dictionaries.ts). Returns sorted, non-overlapping issues.
lib/spellcheck.tsLayer 2 — the 60k-word dictionary speller. spellIssues(text) returns misspellings with frequency-ranked suggestions; lazy-loaded.
lib/engines/grammar.tsLayer 3 — the optional FLAN-T5 corrector. createCorrector() loads the model and exposes correct(text); off by default.
lib/textDiff.tsWord-level diff (grammarIssues) turning a corrected sentence into underline spans, with a resemblance check to reject rewrites.

Data flow

The AI path is dashed because it only runs when you enable "deep grammar"; the rules and spell check always run, instantly.

The underline technique

You can't style individual words inside a <textarea>, so Grammit paints the red wavy underlines on a separate backdrop behind it. A transparent-text textarea sits over a backdrop "mirror" built with identical text metrics; the backdrop re-renders the same text with each issue wrapped in a <mark>, so the underlines line up exactly under the words.

The wrapper is the single scroll container and the textarea auto-grows to its content, which keeps the backdrop and the text from ever drifting apart. A hidden mirror element is also used to measure where a given word sits, so the suggestion popover can be placed right beneath the underline you clicked.