Lingo: Translation
Translate text entirely in the browser. 21–55 MB per language pair, 58 languages to and from English, plus pairs like Spanish → Italian or Japanese → French through English. Private, offline after the first load, and free of per-character pricing.
Try Lingo
Runs in this tab · nothing uploaded
What it does
Translate text without a server.
- Marian NMT students distilled from a larger teacher, run through the Bergamot WASM runtime (int8 GEMM, single worker, no COOP/COEP headers needed).
base-memorywhen available (≈37 MB, on par with cloud translators within ~5% COMET),tinyfor the rest (≈22 MB).PAIRSlists every pair with size and COMET score.- Pairs without a direct model pivot through English:
es → frloadses-enanden-fr. - Pass
html: trueto translate markup while keeping the tags in place. - Codes are BCP 47:
zhis Simplified Chinese,zh-HantTraditional. OneTranslatorcan serve many pairs; new pairs download on demand. - Prefer one model for 100 languages? Pass
model: "Xenova/m2m100_418M"(MIT, ~640 MB, Transformers.js, slower).
Specifications
- Package
- runonweb/translate
- License
- MPL-2.0
- Weights
- midudev/firefox-translations
- Download
- ~22 MB (tiny)~37 MB (base-memory)~50–55 MB (ja, ko, zh)
- Quantization
- int8 on WASM (Bergamot)
- Backend
- WASM only
- Input
- Text
Get started with runonweb/translate
pnpm add runonwebimport { Translator, PAIRS } from 'runonweb/translate'
// en → es: base-memory, ~37 MB
const translator = new Translator({ from: 'en', to: 'es' })
await translator.load()
const { text } = await translator.translate('Hello world')
// "Hola mundo"
// same instance, another pair (downloaded on demand)
await translator.translate('Bonjour', { from: 'fr', to: 'en' })
// no direct es-it model: pivots through English (es-en + en-it)
await translator.translate('¿Dónde está la estación?', { from: 'es', to: 'it' })
// keep the markup, translate the text nodes
await translator.translate('<b>Hello</b> world', { html: true })
translator.dispose()
PAIRS['en-ja'] // { architecture: 'base-memory', bytes: 43849787, comet: 0.90, … }Same shape everywhere: construct, load(), run, dispose(). Pass onProgressto show download progress on first use.
Questions about Lingo
Does Lingo run on device?
Yes. Weights download once and stay in the browser. Nothing is sent to a server.
Which model does Lingo use?
Firefox Translations (Marian NMT) by Mozilla, under MPL-2.0. runonweb loads the midudev/firefox-translations weights and runs int8 on WASM (Bergamot).
How big is the Lingo download?
~22 MB (tiny) · ~37 MB (base-memory) · ~50–55 MB (ja, ko, zh), fetched once on first use. The browser caches the weights, so later loads skip the network and keep working offline.
What does Lingo cost?
Nothing. runonweb is free and MIT-licensed, with no device limits, tokens or sign-in. The weights keep their own license: MPL-2.0.
Which browsers support Lingo?
Any modern browser with WebAssembly. This model does not use WebGPU yet: it fails at session creation in ONNX Runtime Web, so runonweb pins it to WASM.
Can I use a different model with runonweb/translate?
Yes. See each module’s docs for the options it accepts (model, size, language…). Check the license and test both backends before shipping.