A lightweight menu-bar-only macOS app that translates selected text or clipboard contents with a single global hotkey via the DeepL API. The translated result appears in a floating panel above your current window — press Esc to dismiss and keep working. The panel is resizable and remembers your last size between translations.
- One-tap translation. Hotkey → DeepL → floating result. No window switching, no tab juggling.
- Selected-text priority. Reads what's highlighted in any app via Accessibility; falls back to the clipboard when nothing is selected.
- Auto-detect source. DeepL identifies the source language for you; pick only the target.
- Secure key storage. The DeepL API key lives in your login Keychain, not
in
UserDefaults. - No dependencies. Only stock Apple frameworks.
- macOS 14 Sonoma or newer (for SwiftUI
MenuBarExtra(.window)andonKeyPress). - Xcode 15 or newer to build.
- A DeepL API account. The free tier
(
:fx-suffixed key) is sufficient. - xcodegen —
project.ymlis the source of truth; the.xcodeprojis committed for convenience.
# Option A — open the committed project
open QuickTranslate.xcodeproj
# Option B — regenerate the project first
xcodegen generate
open QuickTranslate.xcodeproj
# Option C — pure CLI build
xcodebuild -project QuickTranslate.xcodeproj \
-scheme QuickTranslate \
-configuration Debug \
-destination 'platform=macOS' buildThe built .app lands in
~/Library/Developer/Xcode/DerivedData/QuickTranslate-*/Build/Products/Debug/QuickTranslate.app.
Run it with open and look for the ⌘ icon in your menu bar.
- Click the menu-bar ⌘ icon.
- Expand Translation Settings and paste your DeepL API key. Pick the
target language (default
EN-US). - Anywhere on your Mac, either select some text or copy it to the
clipboard, then press the global hotkey (default
⌃⌥⌘T). - A floating panel pops up with the translation (default 720×360, drag the corner to resize). Esc or the close button dismisses it.
The popover also offers:
- Copy Last — copies the most recent translation to the clipboard.
- Translation Settings — DeepL API key (Keychain-backed) and target language picker.
- Change hotkey — inline shortcut recorder; press a new combination, Esc cancels.
- Quit.
- Accessibility (optional). Lets Quick Translate read the currently selected text in any app. Without it the app still works, but only via the clipboard. The popover surfaces an inline banner with a Grant Access button the first time the popover opens; click it once to bring up the standard system prompt.
- No Screen Recording / Microphone / Apple Events permissions are requested or needed.
Global hotkeys use Carbon RegisterEventHotKey (not a CGEventTap), so
they keep working even when Accessibility is denied.
Language.allCases (QuickTranslate/Translate/Language.swift) ships with
every DeepL target language at the time of writing:
| Code | Display name |
|---|---|
EN-US |
English (US) |
EN-GB |
English (UK) |
DE |
German |
ES |
Spanish |
FR |
French |
IT |
Italian |
NL |
Dutch |
PL |
Polish |
PT-BR |
Portuguese (Brazil) |
PT-PT |
Portuguese (Portugal) |
RU |
Russian |
UK |
Ukrainian |
JA |
Japanese |
KO |
Korean |
ZH |
Chinese (Simplified) |
TR |
Turkish |
CS |
Czech |
DA |
Danish |
FI |
Finnish |
EL |
Greek |
HU |
Hungarian |
NB |
Norwegian |
RO |
Romanian |
SK |
Slovak |
SV |
Swedish |
BG |
Bulgarian |
ID |
Indonesian |
LT |
Lithuanian |
LV |
Latvian |
The source language is always auto-detected; DeepL surfaces its guess as a
small EN → UK-style badge in the floating panel.
QuickTranslateApp // @main, MenuBarExtra(.window)
└── AppCoordinator // @MainActor orchestrator
├── HotkeyManager // Carbon RegisterEventHotKey
├── (inline hotkey recorder) // NSEvent local monitor in the coordinator
├── SelectedTextService // AXUIElementCopyAttributeValue(...)
├── ClipboardService // NSPasteboard wrapper
├── DeepLService // POST api(-free).deepl.com/v2/translate
├── AppSettings // UserDefaults + Keychain @Published store
├── AccessibilityPermissionService
└── TranslationOverlayWindow // floating NSPanel HUD
- Hotkey-triggered translation flow lives in
AppCoordinator.runTranslateFlow(). Cascade is: selected text → clipboard. Result is sent toTranslationOverlayWindow. - Inline hotkey recorder is integrated directly into the menu-bar popover,
not a separate window (matches the sibling
TranscribrUX). - API key is persisted in the login Keychain via
KeychainAPIKeyStore(production) /InMemoryAPIKeyStore(tests). - Translation overlay is a floating
NSPanelat.floatinglevel with the standard window chrome — auto-adapts to system light/dark mode, opens at 720×360, and is freely resizable (the new size persists across subsequent translations in the same run).
xcodebuild -project QuickTranslate.xcodeproj \
-scheme QuickTranslate \
-configuration Debug \
-destination 'platform=macOS' test68 unit tests cover Hotkey / AppSettings / Clipboard / KeyCodeNames /
Language / DeepLService (request building, response parsing, end-to-end
via URLProtocol stub) / KeychainAPIKeyStore (round-trip against an
isolated test keychain service).
xcodegen generateproject.yml is the source of truth; the generated .xcodeproj is committed
so contributors without xcodegen can still build, but it should be
considered read-only — edit project.yml, then regenerate.
Because debug builds are ad-hoc-signed, macOS prompts for keychain access on every rebuild (the binary's signature changes each time). Click Always Allow to whitelist for the current build. Production / Developer-ID distribution would not see these prompts.
Quick Translate is part of a sibling family of menu-bar tools that share visual style and project conventions:
- ScreenshotOCR — drag a region, get the text on your clipboard.
- Transcribr — record system + microphone audio and transcribe via OpenAI.
MIT © 2026 Alex Garmatenko