Select text in any app, press a hotkey, get a small popup with translations.
swtrans is a Rust desktop translator for macOS, Windows, and Linux. It is written from scratch (GPUI, not Electron), and licensed MIT.
- Global hotkey (default Ctrl+Alt+D) — capture the current selection and translate
- Floating query window: source text, language bar, stacked provider cards
- Providers (run in parallel): Youdao Dictionary, Apple Dictionary (macOS), DeepL, OpenAI-compatible, LibreTranslate, unofficial Google (off by default)
- Speech-to-text (mic → Whisper
/v1/audio/transcriptions) - Text-to-speech (system voice:
say/ SAPI / espeak) - Save words to a local SQLite list and review them later
- Settings window: hotkey, start at login, languages, keys, IPC port
- Tray menu: Translate selection, Settings, Saved words, Quit
- Local trigger for Wayland and scripts (
swtrans translate-selection)
GitHub Actions packages installers when you push a v*.*.* tag, or from Actions → Package:
| Platform | Artifact |
|---|---|
| macOS Apple Silicon / Intel | .dmg |
| Windows x64 / ARM64 | NSIS .exe |
| Linux x64 / ARM64 | .AppImage or .deb |
macOS builds are ad-hoc signed, not notarized. Apple Silicon otherwise reports the app as damaged. After you copy it to /Applications:
xattr -cr "/Applications/Small Window Translator.app"Then open it. Right-click → Open also works once the bundle is ad-hoc signed. Notarization needs an Apple Developer ID.
Windows SmartScreen or Defender may call the unsigned NSIS installer malware. That is a false positive: the build is not signed, and the app uses a global hotkey plus selected-text capture. Allow it with More info → Run anyway, or add an exclusion in Windows Security. Submit the file to Microsoft if you want the reputation cleared: https://www.microsoft.com/wdsi/filesubmission. A lasting fix is an Authenticode certificate (package.metadata.packager.windows.certificate-thumbprint).
Needs a recent stable Rust (edition 2024).
git clone https://github.com/<you>/small-window-translator.git
cd small-window-translator
cargo run --releaseThe binary is swtrans.
On Linux, install build deps first:
sudo apt-get install -y build-essential pkg-config clang \
libx11-dev libxkbcommon-dev libxkbcommon-x11-dev \
libxcb-shape0-dev libxcb-xfixes0-dev libxdo-dev \
libasound2-dev libayatana-appindicator3-dev \
libwayland-dev libfontconfig1-devOn macOS, gpui is built with the macos-blade backend so you do not need a full Xcode Metal toolchain.
- Start
swtrans. Settings opens on first launch; the app stays in the tray. Enable Start at login in General if you want it after reboot. - Youdao is on by default. Add other provider keys, or enable unofficial Google, if you want them.
- Select text in another app and press Ctrl+Alt+D (or the hotkey you recorded).
- In the popup: edit the query, pick languages, copy, speak, dictate, or star a word to save it.
- Review saved words from the popup 📖, the tray Saved words item, or
swtrans words.
| Control | Action |
|---|---|
| 🔊 | Speak source or a translation |
| 🎤 | Speech-to-text (needs an OpenAI-compatible key or a local Whisper URL) |
| ☆ / ★ | Save or remove the current word |
| 📖 | Saved words (list + review) |
| ☰ | Settings (same window) |
| 📌 | Pin — keep the popup open |
| Esc | Close (or go back from Settings / Saved words) |
- macOS: System Settings → Privacy & Security → Accessibility (read selection) and Microphone (dictation). Enable swtrans.
- Windows: UI Automation is used when the focused control exposes a text pattern.
- Linux: AT-SPI when available. On Wayland, in-app global hotkeys do not work — bind a compositor shortcut to
swtrans translate-selection.
If Accessibility is missing, swtrans falls back to a clipboard snapshot (copy / restore).
Enable any combination. Empty keys are skipped.
| Provider | Notes |
|---|---|
| Youdao Dictionary | Unofficial dict.youdao.com lookup. No key. Word entries plus sentence translation. |
| Apple Dictionary | macOS only. Local Dictionary.app data via Dictionary Services. No key. Best for single words. |
| DeepL | API key. Optional Pro endpoint. |
| OpenAI-compatible | /v1/chat/completions for translate; /v1/audio/transcriptions for STT. Works with OpenAI, OpenRouter, Ollama, etc. |
| LibreTranslate | Self-hosted or public instance URL. |
| Google (unofficial) | No key. Off by default — can break and may violate Google ToS. |
swtrans Start the app
swtrans settings Open Settings on a running instance
swtrans words Open saved words on a running instance
swtrans translate-selection Trigger select-translate
swtrans --help
The running app listens on 127.0.0.1:18765 (configurable):
curl http://127.0.0.1:18765/selection_translate
curl http://127.0.0.1:18765/settings
curl http://127.0.0.1:18765/wordsSaved as TOML via the directories crate (swtrans/config.toml):
- macOS:
~/Library/Application Support/dev.swtrans.swtrans/config.toml - Linux:
~/.config/swtrans/config.toml - Windows:
%APPDATA%\swtrans\swtrans\config.toml
Saved words live in SQLite next to that directory (vocab.db under the app data dir).
If you already used the old sw-dict name, the previous config file is still read until you Save (then it writes the new path).
Defaults: hotkey Ctrl+Alt+D, source auto, target zh, IPC port 18765.
cargo install cargo-packager --locked
cargo packager --release --formats app,dmg # macOS
cargo packager --release --formats nsis # Windows
cargo packager --release --formats appimage,debOutput: target/packager/. Icons: python3 scripts/gen-icon.py.
MIT