demo · v141

Chat Realtime

A chat input that fires the Proofreader on each pause — debounced, cached, with the latency shown. Single Proofreader instance is reused across keystrokes (the expensive part is create(), not proofread()). Suggestions appear under the input; press Tab to accept the first one, send to commit the message.

Heads up Requires Chrome 141+ behind chrome://flags/#proofreader-api. The on-device model needs to be downloaded once; first create() may stall while that happens. Subsequent calls are fast.
checking support…
(chat is empty)
(no suggestions)

the call (reuse the instance!)

// create() is expensive; do it once per session
const proofreader = await Proofreader.create({
  expectedInputLanguages: ["en"],
  correctionExplanationLanguage: "en",
});

let debounce = 0;
input.addEventListener("input", () => {
  clearTimeout(debounce);
  debounce = setTimeout(async () => {
    const r = await proofreader.proofread(input.value);
    showSuggestion(r.corrections[0]);
  }, 250);
});

why this angle

The explainer's first listed use case is "proofreading user messages in chat applications" — a setting with very tight latency budgets (under 200ms feels live, over 500ms feels broken). The Proofreader API's design specifically anticipates this: create() is the slow part because it warms the model; proofread() calls afterward share state. This concept measures the per-keystroke latency so you can see how much budget you have for proofreading inside a real chat input loop.

see also