Skip to content
All work

Case study

PromptStream

A dictation app for Linux and macOS: hold a key, speak, and the cleaned-up text is pasted wherever your cursor is, in any app.

Role
Sole designer and developer
Type
Independent product
Timeline
2026 – today
Status
Released, updated from time to time
  • Electron
  • React
  • TypeScript
  • Next.js
  • Supabase
  • Whisper (Groq)
PromptStream’s account settings window on a laptop, with its “Dictating…” indicator below.

Problem

I use Wispr Flow on my MacBook. When I moved my desktop to Fedora, I couldn’t find a dictation app for Linux that worked as well, so I built one, Linux first. It has to work everywhere: chat, email, the browser, the terminal, the code editor.

Ownership

I designed and built PromptStream on my own: the Electron desktop app for Linux and macOS, the Next.js website and API, accounts with Supabase, and the hosting on my VPS.

Constraints

  • Wayland, the default on Fedora, doesn’t let one app type into another app’s window.
  • It can’t rely on integrations with each app, so it pastes through the clipboard like a person would.
  • Speech has to reach a transcription model, so dictation needs a network connection.

Architecture

The desktop app is Electron with React and TypeScript, with separate macOS and Linux back ends for the global shortcut and for pasting.

While the shortcut is held, a small overlay window records the microphone and shows a live level meter. The app sends the audio to a Next.js API route with the user’s Supabase session token. That route transcribes it with Whisper on Groq, and a second route cleans up the text with an LLM, so the API keys stay on the server. The personal dictionary goes to both as a glossary, so names and jargon come out spelled right.

To paste, the app puts the text on the clipboard and sends the paste shortcut: through AppleScript on macOS, and through the RemoteDesktop portal over D-Bus on Linux. On macOS the previous clipboard comes back afterwards. History stays on the computer, capped at 500 entries.

Tradeoff

On Linux, the usual ways to send a key press don’t work everywhere: XTEST through XWayland only reaches X11 apps, and tools like wtype or ydotool need a wlroots compositor or root access.

The XDG RemoteDesktop portal, which GNOME and KDE both implement, is the only route that reaches native Wayland windows. The cost is a permission prompt the first time on GNOME; the app asks the portal to remember the grant, so it only appears once.

Testing & reliability

  • 24 Vitest unit tests cover the hotkey state machine, key combination tracking and the text helpers, and they pass.
  • If cleanup or pasting fails, the transcribed text stays on the clipboard and in history, so nothing you said is lost.
  • Requests time out (60 seconds for transcription, 25 for cleanup), and an expired session, a plan limit or a rate limit each get their own message.
  • If the microphone only records silence, the app says so and, on macOS, asks for access again. If the chosen microphone disappears, it falls back to the default one.
  • The LLM sometimes answered a dictated question instead of cleaning it up. Few-shot examples and a check that falls back to the raw text fixed it.
  • Not done yet: the website and API have no tests.

Outcome

PromptStream is released at promptstream.alabaganne.com for macOS 13+ and Linux (AppImage), with a free plan, and I update it from time to time. Windows isn’t supported yet.

More case studies