DEV Community

Admin Supafast
Admin Supafast

Posted on

Building an AI translator that lives everywhere on macOS, iOS and Chrome

Most translation tools make you leave what you're doing: copy text, switch to a tab or app, paste, read, copy back. I wanted translation to sit inside whatever I was already using. That turned into Linguin, an AI translator with a native Mac app, an iPhone app, and a Chrome extension. Here's how I think about building the "same" product across three very different surfaces.

One idea, three surfaces

The product promise is identical everywhere: select text, get a fast, context-aware translation in 100+ languages. But the interaction has to be native to each platform, or it feels wrong:

  • macOS: a menu-bar app plus a global hotkey. Select text anywhere, hit the shortcut, get an overlay. The whole point is that you never switch apps.
  • iOS: a share-sheet extension and keyboard, so translation is one tap from any app instead of a context switch to a separate screen.
  • Chrome: an extension that translates selections and full pages in place, keeping layout intact.

Same core, three genuinely different UX shells.

Keeping the core in one place

The translation logic - language detection, prompt construction, tone handling, caching - is the part you never want to fork. If Mac and iOS drift, you get subtly different translations for the same input, which erodes trust fast.

So the model-facing logic lives behind one small service contract, and each client is a thin shell that owns only its platform UX. A translation request looks the same whether it comes from the menu bar, the share sheet, or a browser selection.

Why "AI" translation instead of a classic API

Classic MT is great at literal accuracy but blind to context. "Book" in a travel app and "book" in a library app should not translate the same way. Passing the surrounding context and a tone hint (formal, casual, technical) to an LLM produces translations that read like a human wrote them, not a dictionary.

The tradeoffs I had to design around:

  • Latency: users expect near-instant results, so caching and streaming matter a lot.
  • Consistency: same input should give the same output, so requests are normalized and cached aggressively.
  • Cost: batching and caching keep per-translation cost sane.

Lessons so far

  • Ship the platform-native interaction first. A technically perfect translation behind a clunky flow loses to a decent translation that's one keystroke away.
  • Centralize the model logic early, before the clients diverge.
  • Context and tone are where AI translation actually beats the old tools - lean into that, not raw language count.

If you want to try it, the Mac app, iOS app and Chrome extension are all at https://linguin.app

Curious how others structure a shared core across native + web clients - do you go with a shared service, a shared package, or just accept some duplication?

Top comments (0)