gnehs/subtitle-translator-electron: an Electron desktop app that translates .srt, .ass, .ssa and .vtt files with an LLM
↔️ Translate subtitle using LLM
At a glance
- What is it?
- A local Electron GUI that sends subtitle cues to ChatGPT and writes translated files back to disk, with JSON checkpoints so long jobs can resume. It is aimed at people translating whole subtitle files, not at real-time captioning.
- Who is it for?
- Adopt it if you already hold an API key for an OpenAI-compatible endpoint and want a GUI that reads .srt, .ass, .ssa and .vtt files and writes translated output back to disk, with JSON checkpoints for resuming. Skip it if you need a hosted web service, a CLI for scripted batch runs, or a free translator with no account.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 61 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Subtitle Translator solves, and who ends up using it
Subtitle files are not plain text. A .srt cue carries an index, a start and end timestamp, and one or more lines of dialogue. An .ass or .ssa file carries a styles block, positioning tags and override codes around the text. Translating one by hand means editing inside that structure without breaking the timing, and a machine translation pasted over the whole file tends to destroy it. Subtitle Translator exists to do that edit in place: the README describes the app as "Translate subtitle using LLM" and lists .ass, .srt, .ssa, .vtt and its own .json checkpoints as the accepted inputs.
The audience is narrow and practical. Someone with a folder of English .srt files and a target language, who is willing to pay for model calls and would rather click through a desktop window than write a script around an API. The repository is an Electron app written in TypeScript, so the deliverable is an installable binary, not a library you import. If your workflow is a CI job that pulls subtitles and pushes translations to a CDN, this is the wrong shape of tool.
How the translation loop actually works
The mechanism visible from the repository is a chunking pipeline. A test file named subtitle-chunks.test.mts and another named subtitle-sampling.test.mts sit alongside translation-checkpoint.test.mts and request-rate-limiter.test.mts, which tells you the app splits a subtitle file into chunks, samples context around each chunk, and throttles outgoing requests. The README states the translation is done "according to the preceding and following sentences", so each request carries neighbouring cues rather than one isolated line. That is the design decision that matters: a line like "I told you so" is ambiguous alone and far less so with the two cues before it.
Checkpointing is the second half. The README says checkpoints are saved as JSON "so an interrupted translation can be resumed by dragging the JSON file back into the app". A long file translated in chunks can fail partway through on a rate limit or a network drop, and the checkpoint is what stops you paying for the same chunks twice. The presence of retry-after.test.mts and request-rate-limiter.test.mts suggests the client reads retry hints from the API rather than hammering it.
Output handling is covered by subtitle-output-format.test.mts and ass-bilingual.test.mts. The latter name points at bilingual ASS output, where the original and the translation coexist in one file, which is a common requirement for fansub releases and not something a generic text translator does.
Installing Subtitle Translator with Homebrew or from Releases
The README gives two install paths. On macOS the Homebrew cask is the short one:
brew install --cask gnehs/tap/subtitle-translator-electronThat pulls the app from the gnehs tap. On other platforms, or if you prefer a manual install, the README points at the GitHub Releases page: "Download the latest stable version from the Releases page". The recent release list shows 2.1.0 from 2026-07-28, with 2.0.2 and 2.0.1 earlier in July 2026. Pick the asset matching your OS and architecture; the README does not enumerate them.
For a first real use, drag a subtitle file into the window. The README's feature list is the operating manual here: choose the source and target languages, and start the translation. What you should see is progress through the file and, on completion, a translated subtitle file plus a JSON checkpoint. If the run is interrupted, drag that JSON file back into the app and it resumes from the saved position instead of starting over.
Building from source is a separate exercise. The package scripts show a pnpm workspace:
pnpm install
pnpm run devThe dev server is configured at http://127.0.0.1:7777/ in the debug block of package.json. A production build runs the checks first:
pnpm run buildThat script chains typecheck, the node test suite and electron-builder. Expect the first build to be slow; Electron and the builder are both large dependencies.
Where it breaks down: cost, rate limits and file formats
The translation is done by a hosted model, so every run costs money and depends on a network connection. The README does not document pricing, quota behaviour or what happens when the account runs out of credit. The rate limiter and retry-after handling in the test suite show the authors thought about throttling, but the README does not document rollback, and it does not say what the app does with a chunk that fails repeatedly after retries are exhausted.
Format handling is the second soft spot. The README lists .ass, .srt, .ssa and .vtt as supported, and one test file is named ass-bilingual.test.mts, but the README does not explain how ASS style overrides, karaoke tags or drawing commands survive a round trip through a language model. Anyone working with heavily styled .ass files should treat that as unverified until they check it on their own material.
There is also a scope limit worth naming. This is a file-based translator. It does not do real-time captioning, it does not generate subtitles from audio, and it does not sync timings. If you have a video and no subtitle file, this app has nothing to work on. The README's supported-extension list is the boundary of what it will accept.
How it differs from a hosted subtitle translation service
Docutranslate is the closest thing in the related searches, and the difference is architectural rather than cosmetic. A hosted service takes your file through a web upload form and returns a translated file; you do not control which model runs, you cannot point it at your own endpoint, and your subtitles leave your machine for someone else's server. Subtitle Translator is an Electron desktop application. The file is opened locally, the chunks are assembled locally, and the only thing that leaves the machine is the text sent to the model endpoint you configured. The checkpoint JSON lives on your disk too.
The trade-off runs the other way as well. A hosted service installs nothing and works from a browser on any machine, including one where you cannot install software. The Homebrew cask and the Releases page both require a desktop OS and, for the cask, a working Homebrew setup. There is no documented web version and no documented CLI. If your constraint is "no installs", the desktop app loses. If your constraint is "the subtitle files must not sit on a third party's server beyond the model call itself", it wins.
Maintenance, licence and what a fork would cost you
The repository is not archived, and the last push was on 2026-08-01. The most recent release, 2.1.0, is dated 2026-07-28, so the release cadence and the commit activity are close together. That is a reasonable signal for a project of this size, though it says nothing about how quickly a broken API integration would be fixed.
The licence is MIT, which is permissive: you can use, modify and redistribute the code, including in commercial products, provided the copyright notice and licence text are kept. That is a statement about the licence text, not legal advice, and it does not cover the model provider's terms of service, which govern the translation calls themselves and are a separate agreement you enter into when you supply an API key.
If you decide to fork, the cost is concentrated in the Electron shell and the i18n setup. The package uses Lingui for translations, with lingui extract and lingui compile scripts, and Playwright for end-to-end tests against a test-mode Vite build. There is also a prompt.txt at the repository root, which is where the model instructions live. Changing translation behaviour means editing that file rather than the TypeScript, which is a friendlier arrangement than prompts buried in source.
Editorial conclusion
Adopt it if you already hold an API key for an OpenAI-compatible endpoint and want a GUI that reads .srt, .ass, .ssa and .vtt files and writes translated output back to disk, with JSON checkpoints for resuming. Skip it if you need a hosted web service, a CLI for scripted batch runs, or a free translator with no account. Before committing, open a folder of your own subtitles and check what the app does with ASS styling tags, since the README documents which extensions are accepted but not how styling is preserved.
Frequently asked questions
Which subtitle translator is the best?
There is no way to answer that from this repository. Subtitle Translator translates .ass, .srt, .ssa and .vtt files using an LLM and saves JSON checkpoints so an interrupted run can resume, but the README makes no accuracy comparison against any other tool.
Can you translate subtitles automatically with Subtitle Translator?
Yes, that is the whole function. The README describes translating subtitles using ChatGPT, with support for multiple languages and translation that takes the preceding and following sentences into account.
How do I install Subtitle Translator on macOS?
The README gives a Homebrew cask command, brew install --cask gnehs/tap/subtitle-translator-electron. For other platforms it directs you to the latest stable release on the GitHub Releases page.
What happens if a Subtitle Translator run is interrupted?
The app saves translation checkpoints as JSON, and the README states that an interrupted translation can be resumed by dragging the JSON file back into the app.
Does Subtitle Translator work on .ass files with styling?
The README lists .ass as a supported extension and the test suite includes an ass-bilingual test, but the README does not document how ASS style overrides or positioning tags are preserved through translation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gnehs-subtitle-translator-electron)