A small cross-platform desktop app (Windows, macOS, Linux) that translates .srt
and .ass subtitle files with an LLM — local-first (LM Studio, llama.cpp, Ollama)
with optional cloud endpoints. It sends the dialogue a few lines at a time with prior
lines as context, keeps all timing and styling intact, and supports right-to-left
languages (Arabic, Persian, …).
- The app parses the subtitle file. The model only ever receives the spoken text — never timestamps or formatting.
- Styling (ASS
{\i1}tags,\Nbreaks,<i>etc.) is hidden behind placeholders, so only the words are translated, then the styling is put back. - Lines are translated in small batches with an id on each line; the app checks the model returned every line with its formatting intact, and automatically retries — falling back to one-line-at-a-time — so even small local models finish cleanly.
- Input files in any common encoding work — the app auto-detects the encoding (UTF-8, UTF-8/UTF-16 with BOM, Windows-1256 Arabic, …) and always writes UTF-8.
Grab the build for your OS from the latest release. Every build is portable — no installer required. To translate you'll also need an LLM endpoint (local or cloud); see For users.
Download SubLLMinal_<version>_x64-portable.exe and double-click it — nothing to
install, copy it anywhere. (An installer, SubLLMinal_<version>_x64-setup.exe, is also
provided if you'd rather have a Start-menu shortcut.) Needs the Microsoft Edge
WebView2 runtime, which ships with Windows 11 and recent Windows 10.
Download SubLLMinal_<version>_universal.zip — one build that runs on both Intel
and Apple Silicon. Double-click to unzip, then move SubLLMinal.app wherever you
like. It uses the system WebKit, so there's nothing else to install.
The app isn't code-signed, so on first launch macOS Gatekeeper blocks it ("can't be opened" / "unidentified developer"). Clear it once, then it opens normally by double-click. Use whichever applies to your macOS:
- macOS 15 Sequoia and newer: double-click the app (it gets blocked), then open
System Settings ▸ Privacy & Security, scroll to the message about
SubLLMinal, and click Open Anyway. - macOS 14 and earlier: right-click (or Control-click)
SubLLMinal.app▸ Open ▸ Open. - Any version (Terminal):
xattr -dr com.apple.quarantine /path/to/SubLLMinal.app— removes the download quarantine so it launches directly.
Download SubLLMinal_<version>_amd64.AppImage, make it executable, and run it:
chmod +x SubLLMinal_*_amd64.AppImage
./SubLLMinal_*_amd64.AppImageThe AppImage bundles its own WebKitGTK. On newer distros (e.g. Ubuntu 24.04) you may
need FUSE 2 once: sudo apt install libfuse2t64 (older distros: libfuse2).
- Run a local LLM (any one of these), or use a cloud endpoint with your own key:
- LM Studio — load a model, then Developer ▸ Start Server (
:1234). - llama.cpp — run
llama-serverwith your GGUF model (:8080). - Ollama — it serves an OpenAI-compatible API at
:11434.
- LM Studio — load a model, then Developer ▸ Start Server (
- Open the app, drag in a
.srt/.assfile (or Browse). - Pick the From and To languages.
- Open Model & connection, choose your endpoint preset, click Test connection (this also lists the available models), pick a model.
- Optionally adjust Translation options — Lines per batch (how many lines go to the model at once), Context lines (how many already-translated lines to show it for continuity), and Parallel requests (batches translated at once — a big speedup on cloud endpoints; keep it at 1 for local servers and best context continuity).
- Optionally fill in Context / notes for the model — a short description of the movie/show so the model uses the right terminology. e.g. for a chess film: "keep chess terms accurate (grandmaster, gambit) and leave move notation like Nf3, O-O unchanged." This is injected into the prompt for every batch.
- Click Translate, watch the side-by-side preview, then Save….
A capable, multilingual model gives much better results — especially for Arabic and other RTL languages. Bigger/instruction-tuned models follow the formatting rules more reliably.
- Edit any translation inline — click a line in the Translation column and type; edits are saved with the file.
- Retranslate one line — hover a line and click ↻ to redo just that line.
- Find & replace across all translated lines.
- Recent files dropdown to reopen quickly.
- Keyboard shortcuts:
Ctrl+Oopen ·Ctrl+Entertranslate ·Esccancel ·Ctrl+Ssave. - Open folder after saving reveals the file in your file manager (Explorer/Finder/…).
- The dot next to Model & connection turns green when your endpoint is reachable (auto-checked on launch).
- Input subtitles in any common encoding are auto-detected; output is UTF-8.
- Node.js 18+
- Rust (rustup) — to build the native shell
- Platform toolchain for the native shell:
- Windows — MSVC C++ Build Tools (the “Desktop development with C++” workload from the Visual Studio Build Tools; Rust uses its linker) + the WebView2 runtime (preinstalled on Windows 11).
- macOS — Xcode Command Line Tools (
xcode-select --install). Uses the built-in WebKit; no runtime to install. - Linux —
libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf(build on Ubuntu 22.04 / Debian 12 or newer for WebKitGTK 4.1).
npm install
npx vitest # unit tests (parsers, engine, client) — no Rust needed
npm run typecheck # tsc --noEmit
npm run dev # frontend only, in a browser (Tauri features inert)
npm run tauri dev # the real desktop app
npm run tauri build # native bundle under src-tauri/target/release/bundle/
npx vite-node scripts/live-translate.ts # end-to-end check vs a running local LLMPortable, no-installer builds per OS (the bundler emits these directly):
# Windows — the self-contained release exe is the portable build:
npm run tauri build # then scripts/make-portable.ps1 → portable/
# macOS — one universal .app for Intel + Apple Silicon (zip it for distribution):
npm run tauri build -- --target universal-apple-darwin --bundles app
# Linux — a single self-contained AppImage:
npm run tauri build -- --bundles appimagePushing a v* tag (e.g. git tag v0.2.0 && git push origin v0.2.0) runs
.github/workflows/release.yml: it builds all three
OSes and attaches the portable artifacts to a draft GitHub Release for review
before you publish. Mac/Linux can't be built from Windows, so CI is the path for them.
The src-tauri/ folder is generated once with npm run tauri init (after Rust is
installed), then the HTTP/dialog/store/opener plugins are registered and their
permissions added under src-tauri/capabilities/. File read/write is a pair of custom
Rust commands (read_text_file/write_text_file) rather than the fs plugin, and
read_text_file auto-detects the input encoding. The opener plugin is granted only
reveal-item-in-dir (the “Open folder” button), nothing broader.
src/lib/subtitle/ SRT/ASS parsing + serialization + tag masking
src/lib/llm/ OpenAI-compatible client + endpoint presets
src/lib/translate/ batching/context/alignment engine, prompts, language list
src/lib/io/ native open/save · src/lib/settings.ts persisted settings
src/main.ts UI wiring · index.html / src/styles.css the UI
tests/ Vitest specs + fixtures
Changes land via pull requests against main. See CONTRIBUTING.md
for the workflow and the engine invariants every change must preserve.
MIT © LockhartKZ


