KISS Translator: Rules, Services and Sync in a Browser Extension
A simple, open-source bilingual translation extension and Greasemonkey script.
At a glance
- What is it?
- KISS Translator is a bilingual reading extension and userscript whose interesting engineering lives in a CSS rule engine, a pluggable translation service layer and a sync model you can host yourself.
- Who is it for?
- KISS Translator is a good study in how little a page-translation tool actually needs. There is no translation model in the repository, no server to run for the core feature and a dependency list short enough to audit: React for the panel, a selector parser, DOMPurify, a streaming JSON parser and a WebDAV client.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the project actually is
KISS Translator ships as both a browser extension and a userscript, and the author is direct about which one to prefer. The extension gets the more complete feature set, including local language detection and a context menu, while the userscript form runs into cross-origin request problems and script conflicts on some sites. The project describes itself as a minimalist, open source bilingual translation tool, and the repository reflects that: JavaScript, GPL-3.0, a `dev` default branch, and roughly 12,500 stars against a feature list that is long but not speculative.
The distribution targets are broad, covering Chrome, Edge, Firefox, Kiwi on Android, Orion on iOS, Safari and Thunderbird, plus a Tampermonkey or Violentmonkey script for desktop browsers and a Userscripts Safari build for iOS. That spread explains the build setup, which compiles the same source into each target rather than maintaining separate codebases.
The translation service layer
No translation model ships in the repository. Instead the extension talks to whatever services you configure, and the built-in list is broad: Google and Microsoft, Tencent and Volcengine, DeepL and DeepLX, AzureAI and CloudflareAI, the browser's own built-in translation, and a family of AI endpoints including OpenAI, Gemini, Claude, Ollama, DeepSeek and OpenRouter.
The interesting part is what sits around those services. Text can be batched into aggregated requests, which cuts call counts and cost when a page has hundreds of fragments. Responses can stream, so translations appear as they arrive rather than after the last sentence. AI services get a conversation memory feature so later sentences on a page have context, and a custom terminology glossary for the words a general model gets wrong. Every interface also supports hooks and custom parameters, which is how a service with an unusual request shape is made to fit without patching the extension.
Troubleshooting notes in the project documentation are honest about where this breaks. A local model server needs its OpenAI-compatible endpoint rather than its native one, some models reject batched requests outright, and a local server answering with 403 usually needs an allowed-origins setting raised before the extension can reach it at all.
The rule engine is the real product
Automatic text detection is the default, and it covers most pages without any configuration. Sites that need more get the manual mode, where rules describe the translation targets, the areas to exclude, the root container to scan, and whether to keep the original text and paragraph boundaries. The documented priority order is personal rules over subscribed rules over global rules, with the global layer acting as the fallback floor, which is a simple design that happens to make community rule collections usable without giving them authority over your own choices.
The rule editor is the part that shows real care about state. You open the translation panel, edit rules for the current site, pick an element on the page, walk up the ancestor path to compare candidate selectors and their match counts, then confirm. Everything you do updates a draft and a live preview, and only an explicit save writes to local storage and triggers sync. Undo and redo stay inside the current editing session, closing the editor with unsaved changes prompts you, and a save that conflicts with an external change keeps the draft rather than discarding it. There is also a scope preview that highlights what would be translated without sending any request at all.
The limits are stated just as plainly. The visual picker works on ordinary desktop DOM pages and their dynamic content, and does not cover iframes, Shadow DOM internals, canvas text or touch-only interaction. For userscript installs on the same origin, writes are coordinated through a browser lock, while shared storage across different origins has no equivalent atomic guarantee, so the editor warns when it detects an outside change.
Interaction surfaces beyond the page
Reading pages is one mode, and the project covers several more. Input boxes can be translated with a shortcut, selection popups can compare the same phrase across several services at once, an English dictionary lookup sits in the same popup with vocabulary saving, and hovering a paragraph can trigger a translation on the spot. Shortcuts are documented individually, with combinations for toggling translation, opening a standalone translation window, opening settings, translating the current selection and translating an input box.
Video subtitles get the most involved treatment. Captions can be translated by any configured service and shown bilingually, with built-in merging and sentence segmentation to improve the quality of what reaches the translator, an AI-assisted segmentation option on top of that, and custom styling for the subtitle display. Segmentation matters more than it sounds: subtitle lines are short, contextless fragments, and merging them into whole sentences before translating is what stops the output from reading like word salad.
Sync, rule subscriptions and owning your data
Settings can be shared across browsers through either a companion sync service or WebDAV. The companion service runs on Cloudflare Workers or in a Docker container, and the project describes it as self-hosted and self-managed so your rule lists stay private. It doubles as a way to share personal rule collections without publishing them.
Rule subscriptions come from a separate community repository that collects and maintains a wider list of site rules, with a dedicated place to ask for help when a rule misbehaves. Since subscribed rules sit below personal rules in the priority order, you can take a subscription wholesale and then override only the sites that need it. The trade is that a subscription whose content changes can alter what you see on a site until your own rule takes precedence, which is a reasonable bargain given that the alternative is writing selectors for every documentation site you read.
Building, triggering and the road ahead
Development uses pnpm with a straightforward sequence, and pull requests are asked to target the `dev` branch rather than the default one:
cd kiss-translator
pnpm install
pnpm buildThe package scripts show how one source tree fans out into per-target artifacts, and the extension and userscript clients are selected with an environment variable rather than a fork:
"start": "cross-env REACT_APP_CLIENT=web react-app-rewired start",
"start:userscript": "cross-env REACT_APP_CLIENT=userscript react-app-rewired start",
"build:chrome": "zx src/scripts/build-task.mjs --target=chrome",
"build:edge": "zx src/scripts/build-task.mjs --target=edge",
"build:firefox": "zx src/scripts/build-task.mjs --target=firefox",
"build:thunderbird": "zx src/scripts/build-task.mjs --target=thunderbird",Other integrations drive the extension from outside the page through a custom window event, which is how a menu command or another script can ask for a translation without touching the internal API:
window.dispatchEvent(new CustomEvent("kiss_translator", {detail: { action: "toggle_translate" }}));The roadmap mixes finished work with intentions. Streaming, context memory, stronger rich-text handling and improved subtitle segmentation are listed as done, while local models for speech and text, document translation for PDFs and images, and a rewrite of the module layout are still open. The project states plainly that it is built in spare time with no fixed schedule, so the last commit dated September 21, 2026 is a better signal of pace than any milestone list.
Editorial conclusion
KISS Translator is a good study in how little a page-translation tool actually needs. There is no translation model in the repository, no server to run for the core feature and a dependency list short enough to audit: React for the panel, a selector parser, DOMPurify, a streaming JSON parser and a WebDAV client. Everything clever sits in two places. The rule engine decides what counts as translatable text, with personal rules overriding subscribed ones and global rules acting as a floor, and a visual picker that writes selectors without leaving the page. The service layer decides how text reaches a translator, with a custom API format, request hooks and batched or streamed delivery that let a self-hosted Ollama or DeepSeek endpoint behave like a hosted one. If you are evaluating it, the honest caveat is the scope of the visual editor: it works on ordinary desktop DOM pages and skips iframes, Shadow DOM internals and canvas text, so sites built that way need hand-written selectors instead.
Frequently asked questions
Can KISS Translator translate YouTube subtitles into English?
Yes. Captions can be translated with any configured service and displayed bilingually, with built-in merging and segmentation plus an AI segmentation option and custom subtitle styling.
Does the KISS Translator extension work on Safari?
The installation list still marks Safari entries as pending, with separate Mac and iOS lines. On iOS, the userscript build is the practical route, installed through the Userscripts extension.
How do I use a local model such as Ollama with KISS Translator?
Point the custom interface at the model's OpenAI-compatible endpoint rather than its native one. If requests fail with a 403, the local server usually needs its allowed-origins setting opened, since the extension makes requests from the page context.
Which takes priority, my own site rules or a subscribed rule list?
Personal rules win over subscribed rules, and both win over global rules, which exist as a fallback floor. A subscription can therefore be applied broadly and overridden only on the sites you care about.
Can KISS Translator sync settings across browsers without a vendor account?
Yes. Settings can sync through WebDAV or through the companion sync service, which runs on Cloudflare Workers or in a Docker container that you host and manage yourself.
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/fishjar-kiss-translator)