Case study · StylisticBack to portfolio
Stylistic add-in icon: a quill over a document
Editorial AI inside Microsoft Word

Stylistic

The AI proposes. Word is still where you decide.

Most writing assistants pull the author out of the editor, review the text somewhere else, and hand back a rewritten version. Stylistic does the opposite: it reads the open document, sends it to an authenticated Mastra backend, and writes the answer back as real Track Changes with a comment justifying each one. Nothing is applied silently — every suggestion is accepted or rejected with the Review tools the author already uses.

pages edited on a real book
200+
suggestion types
2
minimum host API
WordApi 1.6
chars of standing instructions
4000
One run, end to end

From an open paragraph to a tracked change

Analysis is a Chain of Responsibility: seven ordered handlers, each with one job, each able to stop the run before the document is touched. This is the real order they are wired in.

  1. The open documentOffice.js · WordApi 1.6
  2. Stylistic taskpaneReact · Fluent UI · Zustand
  3. Mastra backendBun · PostgreSQL · pgvector
Authenticated surface
  • POST /documents/resolve
  • GET /user/preferences
  • PUT /user/preferences
  • POST /auth-bridge-session
Suggestion payload
  • type: track-change | comment-only
  • context
  • anchor
  • suggestedText
  • justification
  • category
  • severity
The two halves

A thin client in Word, the reasoning behind an authenticated API

The add-in owns everything that touches the document. The backend owns authentication, the persisted author profile, and the editorial reasoning. Neither one reaches across that line.

Stylistic add-in icon: a quill over a document

Stylistic

Word add-in · Office.js · React

The taskpane orchestrates Word: it reads the document, applies the revisions, and keeps the author in control of every one of them.

  • TypeScript
  • React
  • Fluent UI v9
  • Zustand
  • Office.js
  • @mastra/client-js
  • better-auth
  • Vitest
View source
Word with the Stylistic taskpane open beside a document under review
Sixteen suggestions over a novel chapter, filtered by severity. Each card carries its category, its justification, and its own accept or reject.
  • Revisions, not a rewrite

    A track-change becomes a real Word revision and a comment-only becomes a margin comment with its category and reasoning.

  • The author owns the tracking mode

    Track Changes is enabled lazily, stays on while Stylistic work is pending, and is never switched off behind the author: an explicit action does that.

  • Office.js stays in one layer

    Only the Word adapters may touch the host API. Domain, state and UI are testable without a Word instance in the room.

  • It cleans up after itself

    Resolved suggestions leave metadata behind; a dedicated cleanup removes the orphaned comments once the review is finished.

Stylistic taskpane before analysis, with an active selection of 1544 characters
Before the run. The pane states what it is about to read — the whole document, or the selection and its exact character count.
Native Word tracked changes and comments generated by Stylistic
After the run. Deletions, insertions and margin comments are ordinary Word revisions: the Review tab, the accept-all button and the document history all keep working.

Stylistics Backend

Mastra · PostgreSQL + pgvector · Bun

Not prompts behind an API: authentication, persisted document context and thin workflows that keep the deterministic logic out of the model.

  • Mastra
  • TypeScript
  • Better Auth
  • PostgreSQL
  • pgvector
  • Drizzle ORM
  • Zod
  • Pino
  • Docker
View source
Mastra Studio metrics view for the Stylistics backend
Mastra Studio over the running backend: traces, token cost and latency per agent run, which is how a bad correction gets tracked back to the run that produced it.
  • Workflows stay thin

    The correction workflow only sequences three steps — load the profile, correct, update the profile. Mastra orchestrates; it is not where the business rules live.

  • The author profile learns and forgets

    Live patterns carry a traffic-light state. A pattern that comes back clean twice is promoted and then deleted, so the context the agent reads stays small.

  • Auth built for an Office dialog

    Better Auth with Google OAuth finishes the callback on the backend origin and hands the add-in a session through a short-lived one-time code.

  • Model choices are one file

    Agents read from a central model pool with ordered fallbacks, so swapping Gemini for GPT — or adding a local one — never touches a workflow.

Edge cases

The questions worth asking before it touches a manuscript

Anything that edits somebody else’s text gets asked the same six questions. Each one is answered in the repository and each answer is a behaviour you can check, so you can decide with the awkward cases in view rather than meeting them later.

  • What if Word only resolves half of a replacement?

    Word applies a replacement as two separate mutations — a deletion and an insertion — and can resolve one without the other. The add-in watches for exactly that and surfaces it as a half-resolved replacement, so you learn about it from the tool at the moment it happens rather than from rereading the paragraph later.

  • What if the text moved between analysis and review?

    Suggestions are located by context first and anchor second. If the author edited that fragment in the meantime and the anchor no longer exists, the card reports it as not found instead of applying an approximate match somewhere else in the document.

  • Who signs the changes?

    Word attributes revisions to the signed-in user, not to the add-in. In a shared document the AI edits are indistinguishable from the author’s own, which is exactly why every one of them arrives with a justification comment attached.

  • Which documents are out of range?

    Files protected with DRM or RMS cannot be modified by any add-in, and live co-authoring is not a safe target scenario: two people rewriting the same range while revisions are being written is not something this flow tries to arbitrate.

  • Does it work without the backend?

    Analysis and feedback run on a Mastra server with Better Auth and a valid bearer session. The add-in verifies that connection before it reads a single paragraph, so an unreachable backend stops at a message and your document is never opened, let alone half-edited.

  • What about languages other than Spanish?

    Spanish is the validated language, and the editorial criteria are built around its usage rather than translated into it. The contract already carries a language code, so the path to a second one is open once its criteria have been written and tested to the same standard.

Get it running

Two repositories, one local setup

  1. Start with the backend: the add-in has nothing to talk to until Mastra is up.

  2. Copy .env.example, point POSTGRES_URL at the local database, and register your Google OAuth credentials with https://localhost:3000 as a trusted origin.

  3. Bring up PostgreSQL with pgvector through Docker Compose, then boot Mastra on port 4111 — Studio, OpenAPI and Swagger UI come with it.

  4. Now the add-in: bun run start serves the taskpane over https://localhost:3000 and sideloads it into Word desktop.

  5. In Word: Show Task Pane, sign in with Google, pick the analysis profile, and run Analizar y sugerir.

Stylistic settings panel with the analysis profile and the standing correction instructions
Settings: the analysis profile plus up to 4000 characters of standing instructions the corrector must watch for in every document. The account email is redacted in the capture.

Run it from source

Both repositories are Apache-2.0 and boot with Bun. These are the documented commands, in the order they have to run.

  • Stylistics BackendNode >= 22.13 · Bun · Docker
    bun installcp .env.example .envdocker compose up -d postgresbun run dev
  • Stylistic add-inNode 18+ · Bun · Word 2019+ or Word Online
    bun installbun run start