I built a one-hotkey inline AI rewriting tool (and what went wrong)
by AzeniqTech | 2025-12-28 07:57:42+00:00
I’ve been dogfooding a small writing helper I built called Rephrazo, and I thought it might be useful to share some implementation details and mistakes so far.

The idea is simple:

* highlight text where you’re writing
* press a hotkey
* get an AI paraphrase in a small popup
* insert it back with one click

The goal is to remove the “copy - open AI tool - paste - rewrite - paste back” loop for small edits.

This post is about how I wired it up, what worked technically, and what didn’t.

### Constraints I designed for

From the beginning I tried to design under a few constraints:

* One hotkey → one main action
* Stay inside the current app (no browser, no big side panel)
* Minimal UI: single suggestion, one click to insert
* Latency “feels instant” or it doesn’t get used

Whenever I broke these constraints (added extra choices, prompts, etc.), usage dropped in dogfooding.

### High-level architecture

Rough breakdown:

* Desktop client that:

* listens for a global hotkey
* grabs the current text selection
* sends it to an API
* displays the returned paraphrase in a small overlay near the selection

* Backend API that:

* accepts the selected text + some minimal context
* calls an LLM
* applies a fixed prompt (“make this clearer, keep tone/voice as much as possible”)
* returns a single suggestion (no multi-choice for now)

No fancy infra yet, just trying to keep the path from “key press” to “returned text” as short as possible.

### Text capture and insertion

The surprisingly tricky part wasn’t the LLM, it was:

* reliably capturing the selected text
* not messing up the user’s clipboard
* inserting the rewritten text back without breaking formatting

The first version literally abused the clipboard:

* save clipboard
* copy selection
* send to backend
* replace selection by pasting the result
* restore clipboard

This worked… until it didn’t:

* some apps ignore simulated keypresses
* sometimes the clipboard got overwritten by other things in between
* it felt fragile and “hacky”

I’m slowly moving toward more app-aware integrations (where possible) while still keeping a generic fallback.

### Latency and UX

Latency matters more than I expected. Rough buckets:

* < 500 ms → feels instant, people are happy
* 1–2 seconds → acceptable if the suggestion is clearly better
* > 3 seconds → people regret pressing the hotkey and use it less

A few tiny UX things helped:

* show a small “loading” state immediately near the selection
* render the popup instantly (skeleton state), then fill it when the response arrives
* on failure, show a short, honest message instead of silently doing nothing

If you’re building AI tools, this won’t surprise you, but it’s different when you watch your own users hesitate after a few slow responses.

### Things that went wrong

* I overbuilt customization early:

* tone dropdowns
* multiple modes (“shorter”, “longer”, “more formal”)
* extra toggles

People ignored them, or got decision fatigue.

* I underestimated how many edge cases there are with selection/insertion across different apps.

* I didn’t log enough in the first builds, so I had to retrofit telemetry to understand actual usage.

If you’re curious, the current early version is here:
[https://rephrazo-ai.app/](https://rephrazo-ai.app/)