Linguist is a translation extension you can point at your own backend, or at no backend at all
Translate web pages, highlighted text, Netflix subtitles, private messages, speak the translated text, and save important translations to your personal dictionary to learn words even offline
At a glance
- What is it?
- A browser extension for translating pages, selected text, subtitles and messages, with 130 languages, a pluggable translator system and an embedded Bergamot translator for offline use. The project positions itself as a replacement for commercial translation services, with no data collection and no account.
- Who is it for?
- Adopt Linguist if you want page and text translation without sending your reading to a commercial service, and if you are willing to configure a translator backend or accept the limits of the offline engine. Do not adopt it expecting every language pair and every commercial service's quality, because the offline path and the network path are different systems with different coverage.
- Can I use it commercially?
- Yes. BSD-3-Clause 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 45 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 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The positioning is a replacement, not a wrapper
Linguist is described as a powerful browser extension built to replace commercial translation services, private, fast and under your control. It translates web pages, highlighted text, subtitles including Netflix, and private messages, it can speak the translated text through text to speech, and it saves entries to a personal dictionary so you can learn words even offline. It supports 130 languages.
The key sentence in the Why section is that Linguist is a standalone translation system, not a thin wrapper around a commercial widget. That distinction is the entire argument, and it is testable: a thin wrapper would send your page to a service and show you what came back, while a standalone system has a translator interface you can point at anything.
And the options are wide. You can use any translation service like Google, Yandex, Bing, DeepL, ChatGPT, and so on, through the modular translators system. You can write your own translator module, documented separately as custom translators, with a separate repository listing popular bindings. And you can go fully offline, with the embedded Bergamot translator, which lets you translate texts right on your device.
The project is free, open source, and collects no personal data, and the donations section asks for money to prioritise fixes, commission features and speed up work. The privacy claim is architectural rather than a policy promise: if the translation happens in your browser, there is nothing to collect.
The homepage is linguister.io, the licence in the repository metadata is BSD-3-Clause, and the last push to the repository was on 2026-09-08 with the repository not archived. The recent releases are v7.1.0 from 2026-08-07, v7.0.5 from 2026-03-22 and v7.0.4 from 2025-08-28.
The feature list is really a list of surfaces to translate
The features section is organised by what part of the browser you are translating, and that tells you how the extension is architected.
Full-page translation comes with flexible auto-translation configuration, so you can decide which sites to translate automatically and which to leave alone. Highlighted text translation is the select and translate path, which is the one you use constantly. And there is translation of any text input, which covers a form field, a comment box or a search box.
On top of that there is a dictionary with saved translations, and a translations history to remember recently translated words. Text to speech is listed as a feature, and the repository description phrases it as speak the translated text.
The dictionary and the history are what turn the extension from a one-shot tool into a vocabulary system, and they are local. The saved entries are the personal dictionary, and the project description says they let you learn words even offline.
The subtitle support is the least obvious capability and probably the most useful. Translating Netflix subtitles is a different problem from translating a page, because the text arrives in a timed stream that has to be captured, segmented and re-rendered in sync, and because the timing metadata is as important as the text. Supporting it means the extension is doing more than a DOM pass.
Private messages are the third unusual one, and it is the case that most motivated the privacy stance. Translating a private message is precisely the case where sending the text to a third party service is least acceptable, and it is the case where the offline path is most valuable.
Two structural details from the package manifest are worth noting. The `domtranslator` dependency at 1.3.1 is a separate library for translating the document, which is the right way to structure that, since the DOM walking logic is hard to maintain inside an extension. And the `idb` dependency at 8.0.3 is IndexedDB, which is where the dictionary and the history live.
Building the offline translator needs a native toolchain
The Bergamot translator is the reason the Docker setup in this repository exists, and it is the part of the build that is not JavaScript.
The compose file has two services. The `bergamot` service builds from a context of `./thirdparty/bergamot` on `linux/amd64` as the user `node`, and the `linguist` service builds the extension itself, mounting the bergamot build and source directories into it.
version: "3"
services:
linguist:
user: node
build:
context: .
volumes:
- ./build:/mnt/builder/build
- ./thirdparty/bergamot/build:/mnt/builder/thirdparty/bergamot/build
- ./thirdparty/bergamot/src:/mnt/builder/thirdparty/bergamot/src
bergamot:
user: node
platform: linux/amd64
build:
context: ./thirdparty/bergamot
volumes:
- ./thirdparty/bergamot/build:/mnt/bergamot/build
- bergamot-translator:/mnt/bergamot/bergamot-translator
volumes:
# Persistent cache for fast builds in dev environment
bergamot-translator:
driver: localThe named volume is a build cache for the translator, which is the expensive part of the build because it compiles a native library.
The Dockerfile shows the toolchain that requires.
FROM node:26
WORKDIR /mnt/builder
RUN apt-get update
RUN apt-get install -y zip gzip tar cmake
RUN apt-get install -y sudo && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN usermod -aG sudo node
COPY . .
RUN mkdir -p thirdparty/bergamot/build
RUN chown -R node:node .
USER node
RUN npm installSo cmake, a compiler toolchain and zip are needed, and the container runs as a non-root user with passwordless sudo, which is the standard arrangement for a native build in a container. The `FAST_BUILD=off` flag in the `.env.example`, alongside `SHELL` and `ADB_DEVICE_TO_DEBUG`, points at a development workflow with an attached Android device, which matches the README's note that the extension can be used on mobile browsers with Firefox Nightly or any chromium browser that supports extensions.
The extension build itself is webpack, with a separate target for Firefox.
"build:dev": "EXT_TARGET=firefox webpack-cli -wc ./webpack.config.js"And the `build:tokens` script runs `themekit build -c themekit.config.json` for the design tokens, with a `words.txt` file at the repository root for the spell checker and a `themekit.config.json` for the token pipeline.
The dependency list is a React 17 extension with modern state tooling
The package manifest describes a browser addon, named `browser-addon` in the manifest, at version 7.1.0, and the stack is worth reading because some of it is dated and some of it is not.
React is at 17.0.1 and react-dom at 17.0.2, which puts the extension on the older React runtime.
The state management is `effector` at 22.4.1, with `patronum` at 1.12.3 alongside it for the derived state combinators, and `fp-ts` at 2.12.1 with `io-ts` at 2.2.16 for the typed functional error handling. That pairing is a coherent choice: Effector for a small reactive store, io-ts for decoding untyped data at the boundaries, which is exactly where a translation extension touches untrusted input.
The manifest lists `anylang` at 4.0.0, and the README's donations section asks for help translating the UI with a link to the internationalization guide.
The interface layer is `react-elegant-ui` at 0.3.3, with `@bem-react/core` and `@bem-react/classname` for the class name convention, `@react-aria/interactions` and `@react-aria/utils` for the accessible interaction primitives, `@popperjs/core` for the popover positioning, and `react-shadow` for the style encapsulation that an extension injecting into other pages needs.
The heavier pieces are there for the harder features. `monaco-editor-core` at 0.39.0 is a code editor, which is what a custom translator module needs to be editable in the settings. `papaparse` at 5.3.2 parses CSV, which is what a dictionary import needs. `idb` at 8.0.3 is the IndexedDB wrapper for the dictionary and history. `react-infinite-scroller` and `use-debounce` are for the history and search interfaces. And `webextension-polyfill` at 0.12.0 is what makes one codebase run on both Firefox and chromium.
The test and lint stack is modern: Vitest for the tests, ESLint 9 with a flat config, stylelint for the CSS, Prettier for the formatting, commitlint with the conventional config, and husky for the hooks. The engine requirement is Node 20 or newer.
Two things to check before you rely on it
The licence deserves a note, because the two sources in this repository do not agree.
The repository metadata reports BSD-3-Clause, and the LICENSE file at the root is the authoritative text for that claim. But the package manifest in the repository declares the licence as GPL-3.0 for the `browser-addon` package. Two different licences are named in the same tree.
That is a small discrepancy, and it may well be a leftover from a change of licence that was not fully applied, but it is exactly the kind of thing that a legal review will ask about and that you should resolve before you install the extension in an environment where it matters. The file to read is the LICENSE file at the root, and the question to ask is which of the two applies to the published artefact.
The second thing to check is the offline path, because it is the part of the extension that is genuinely different from the commercial services it replaces. The Bergamot translator is a machine translation engine embedded in the extension, running on your device rather than on a remote service.
The extension's answer is the custom translators list, where you can pick a network backend for the pairs you care about and keep Bergamot for the rest.
The third practical note is about the update model. The extension is published to the Chrome Web Store and to the Firefox add-ons site, and for other browsers the GitHub releases page has the packages to install manually in development mode. Store extensions update themselves, and a privacy tool that wants to see what changed in a new version is easier to reason about when the source is on GitHub and the release notes are public.
The label for high impact tasks and the label for reproducing unconfirmed bug reports are both there, and the last one is a nice touch for a project where a large share of the reports are about translations of specific text.
Editorial conclusion
Adopt Linguist if you want page and text translation without sending your reading to a commercial service, and if you are willing to configure a translator backend or accept the limits of the offline engine. Do not adopt it expecting every language pair and every commercial service's quality, because the offline path and the network path are different systems with different coverage. Verify first that the translator you want to use is available in the custom translators list, that the embedded Bergamot translator is available if you plan to translate without a network, and that the licence of the extension as published matches the one the repository declares, since the two differ.
Frequently asked questions
What is the Linguist browser extension?
It is a free, open source extension for translating web pages, highlighted text, subtitles including Netflix, and private messages, with text to speech, a personal dictionary and a translations history. It supports 130 languages and collects no personal data.
Can Linguist translate offline?
Yes. It embeds the Bergamot translator, which lets you translate texts right on your device with no network. The translation runs on your device, so the text is not sent to a remote service.
Which translation services does Linguist support?
The modular translators system can use any translation service such as Google, Yandex, Bing, DeepL or ChatGPT. You can also write your own translator module, and a separate repository lists bindings for popular ones.
How do I build Linguist from source?
The build needs Node, plus cmake and a native toolchain for the Bergamot translator, and the Docker Compose file provides both services. The extension itself is built with webpack, with EXT_TARGET=firefox for the Firefox build and a themekit step for the design tokens.
What licence is Linguist released under?
The repository metadata reports BSD-3-Clause and the LICENSE file is at the repository root, while the package manifest inside the repository declares GPL-3.0 for the browser-addon package, so the two disagree and the authoritative file is worth checking before you rely on it.
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/translate-tools-linguist)Was this useful?