Plume

Select text in any app, then fix its spelling and grammar or translate it in place. Works on Android, iOS, Windows, macOS and Linux.

Back to Projects
Kotlin Multiplatform, Compose Multiplatform, Rust, JNA, Ktor, SwiftUIView Live

You are halfway through a message in a language that is not your first. The accents are wrong, the agreement is off, and you know it. Normally you would copy the text into another app, fix it there, copy it back, and hope you did not lose the last sentence.

Plume removes that round trip. Select the text, ask for a correction, and the corrected version replaces what you selected, in the app you were already using. Same for translation. Nothing to paste back.

Builds for Android, Windows, macOS and Linux are on the releases page.

What it feels like to use

On a phone, Revise and Translate appear in the text selection menu, next to Cut and Copy. They show up in your messaging app, your email, your browser, anywhere that uses the standard menu.

There is also an optional Plume keyboard. It is not a typing keyboard, just the two actions as buttons. You switch to it the way you switch to an emoji keyboard, and it can read your whole message without you selecting anything first.

The Plume keyboard panel open below a message, showing Revise and Translate

One tap, and the message is rewritten in place.

The same message with the accents and contractions corrected

On a laptop there is no selection menu to join, so Plume waits quietly in the menu bar and listens for a keyboard shortcut. Select a sentence anywhere, press the shortcut, and the same thing happens.

Plume's desktop shortcut settings

Why I built it

I write in French and English every day, and the tools that help with that all want you to come to them. You open their app, or their website, or their sidebar. That works fine when you are writing an essay. It works badly when you are answering a message and the whole exchange takes twenty seconds.

I wanted the correction to happen where the writing already is, and to feel closer to a spellchecker than to a chatbot. Two actions, no conversation, no new place to visit.

Plume's desktop half grew out of MyReviser, an earlier tool of mine that did this job on a laptop with a keyboard shortcut. Plume kept its shortcuts unchanged, because they had already been proven in daily use, and the small native library that listens for them is the ancestor of the one Plume uses now. What Plume adds is everywhere else: the phone, the tablet, and the second action.

The part that took the longest

Replacing text in someone else's app is not something an app is normally allowed to do. Each system offers exactly one opening, and they are all different. Android has the selection menu. iPhones have keyboard extensions. Desktops have global shortcuts and the clipboard.

The desktop version is the one with a real trap in it. To replace your selection, Plume has to borrow the clipboard: remember what was on it, copy your selection, do the work, paste the result, then put the clipboard back the way it was.

The naive version of that has a quiet failure. If the copy does not go through, because the app was busy or the system was slow, the clipboard still holds whatever it held before. The tool then corrects that old text and pastes it over your selection. You lose a sentence and gain a correction of something you wrote an hour ago.

I found that by reading MyReviser closely enough to port it, along with two smaller versions of the same problem. A picture on the clipboard would come back as text. The keys still held down from the shortcut would leak into the keystrokes Plume sent next.

So Plume empties the clipboard first, then watches until something appears. If nothing does, it knows the copy failed and says so instead of guessing. It puts your clipboard back exactly as it found it, pictures included. That is the sort of thing nobody notices when it works, and never forgives when it does not.

Your writing stays yours

There is no Plume account and no server of mine in the middle. You bring a key from an AI provider you already use, and your text goes to that provider and nowhere else.

Choosing an AI provider

The key is stored in whatever your device uses for passwords, so it is protected the same way your other credentials are. OpenAI, OpenRouter, Anthropic and Gemini work out of the box, and so does a model running on your own machine, which never sends anything anywhere.

The log records what happened, never what you wrote.

How it is built

One codebase in Kotlin covers Android, iPhone, Windows, macOS and Linux. Everything that decides what to send and what to do with the answer is written once. Only the way you reach it is written per platform, because that is the part no two systems agree on.

The interface is shared too, with one deliberate exception. An iPhone keyboard runs under a tight memory limit, and if it goes over, the keyboard silently vanishes while you are typing. The shared interface toolkit costs too much of that budget before drawing anything, so the iPhone keyboard is written natively instead. It is the one place the shared approach is abandoned, and it is abandoned on purpose.

The desktop needed something a Java runtime cannot do at all: listen for keyboard shortcuts system-wide, read the clipboard, and type on your behalf. That part is a small Rust library the app loads at startup.

Stack

Kotlin Multiplatform and Compose Multiplatform for the shared logic and interface. SwiftUI for the iPhone keyboard. Rust for the desktop input layer. Ktor for network calls, and the platform's own secure storage for keys.

Android and Linux are the two I use daily. Windows and macOS build and test automatically on every change. The iPhone version is written and not yet released.

The source is on GitHub.

Connect
Let's get in touch