electron-live-i18n
Allows live-translating the UI of packaged Electron apps by patching the app.asar archive and serving a runtime translation layer.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@electron-live-i18nTranslate the UI of /Applications/Some App.app to Spanish"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
electron-live-i18n
English | 繁體中文 | 简体中文 | 日本語 | 한국어 | Español | Français | Deutsch | Português | Русский
Translations below were produced by this tool itself (
eli locales/eli tr) and lightly reviewed. PRs welcome if a phrase reads wrong in your language.
Live-translate any packaged Electron app — no rebuild, no source code, no API key.
Most i18n tooling assumes you own the app and can edit its locale files. This one is for
the other case: a shipped, signed, app.asar-packed Electron app that shows English you
cannot read, and you just want it in your language today.
It works by writing a ~900 byte loader into one existing entry inside app.asar
(padded to the exact original size, integrity hashes rewritten), and serving the actual
translation layer from a tiny local HTTP server. After that first patch you never touch
the app bundle again — iterate on the translation layer and press ⌘R.
app.asar ──(loader stub)──► http://127.0.0.1:7799/payload.js ──► DOM sweeper + dictionaryDemo
$ eli inspect "/Applications/Some App.app"
archive : /Applications/Some App.app/Contents/Resources/app.asar
header : 161743 bytes, data starts at 161760
plist : /Applications/Some App.app/Contents/Info.plist
largest front-end entries (good loader slots):
1284231 dist/assets/index-abc123.js
7020 dist/vendor-analytics.js
601 dist/index.html
$ eli serve --target zh-TW --dict ./mydict.json &
electron-live-i18n serving on http://127.0.0.1:7799 (dict: ./mydict.json)
$ eli patch "/Applications/Some App.app" --entry dist/vendor-analytics.js
{
"patched": {
"entry": "dist/vendor-analytics.js",
"slot_size": 7020,
"payload": 905,
"file_hash": "401f5f19...",
"header_hash": "6dc99001..."
},
"backups": [
"./eli-backups/app.asar.bak-20260812-021132",
"./eli-backups/Info.plist.bak-20260812-021132"
]
}
Restart the app. It will now pull the translation layer from http://127.0.0.1:7799/payload.jsAfter the restart, English UI text is replaced as it appears, and every new string
lands in mydict.json:
$ cat mydict.json
{
"Manager will assign tasks to the right agents.": "主管會把任務分派給對的員工。",
"Send a message to get started": "傳個訊息開始吧",
"Settings saved successfully": "設定儲存成功"
}Changed your mind about a translation? Edit that file and press ⌘R in the app.
Related MCP server: electron-mcp
Why not just edit the locale files?
Many Electron apps hard-code English in JSX/TSX; there is no locale file to edit.
The app is already built and signed; rebuilding means setting up its whole toolchain.
You want to keep translating new strings as the app updates, not fork it.
If you do have locale JSON files, eli locales translates those too.
Install
pip install electron-live-i18n # or: pipx install electron-live-i18nPython 3.9+, standard library only. No dependencies, no API key, no account.
Quick start
# 1. look inside the app and pick an entry to host the loader
eli inspect "/Applications/Some App.app"
# 1284231 dist/assets/index-abc123.js
# 7020 dist/vendor-analytics.js <-- a good slot: big enough, non-critical
# 601 dist/index.html
# 2. start the translation server (keep it running)
eli serve --target zh-TW --dict ./mydict.json --skip "#my-own-overlay" &
# 3. patch the app once
eli patch "/Applications/Some App.app" --entry dist/vendor-analytics.js
# 4. restart the app — English turns into your language as you use itUndo at any time:
eli revert "/Applications/Some App.app"How it translates
A
MutationObserverwalks text nodes and replaces anything already in the dictionary — instant, zero network.Unknown strings that look foreign (≥8 letters, <12% target-script characters) are sent to the local server.
The server translates via the public, key-less
translate.googleapis.comendpoint, caches the result on disk, and appends it to your dictionary file.
So the dictionary is a plain JSON file you can hand-edit. Machine translation gets you 95% of the way in seconds; fix the awkward ten strings by hand and they stay fixed.
{
"Send a message to get started": "傳個訊息開始吧",
"Manager will assign tasks to the right agents.": "主管會把任務分派給對的員工。"
}Let an AI agent do it for you
If you use an assistant that can run commands and edit files on your machine — Claude Code, Cursor, Codex CLI, Cline, Windsurf, Copilot CLI — paste this and it will handle the whole flow, including picking the entry to patch:
Install and use https://github.com/dee0917/electron-live-i18n to translate the UI of
"<APP PATH>" into <LANGUAGE>.
Steps:
1. pipx install electron-live-i18n (or: pip install electron-live-i18n)
2. Run `eli inspect "<APP PATH>"` and pick a front-end .js entry that is large enough
(> 1 KB) and non-critical — analytics/vendor bundles are ideal. Tell me which one you
picked and why.
3. Start `eli serve --target <LANG CODE> --dict ./mydict.json` in the background.
4. Run `eli patch "<APP PATH>" --entry <THE ENTRY>`, then restart the app.
5. Confirm the backups exist, and remind me that `eli revert "<APP PATH>"` undoes everything.Replace <APP PATH> (e.g. /Applications/Slack.app, C:\Users\me\AppData\Local\Slack),
<LANGUAGE> and <LANG CODE> (zh-TW, zh-CN, ja, ko, es, fr, de, pt, ru, ...).
Or wire it up as an MCP server (see below) and just say "translate this app's UI into Japanese".
Choosing an entry to patch
eli inspect lists front-end entries by size. Pick one that is:
large enough — the loader is ~900 bytes and gets padded up to the slot size,
loaded by the renderer — check that
index.htmlreferences it,non-critical — telemetry/analytics bundles are ideal; the original content is replaced.
If you want to keep the original code, host it from your own server and append it to the
payload with eli serve --extra-js original.js. That is what the loader indirection is for.
Platforms
OS | Bundle layout it looks for | Integrity fixup |
macOS |
| archive header hash and |
Windows |
| archive header hash |
Linux |
| archive header hash |
You can always pass the app.asar path directly instead of the bundle folder.
Windows notes: run the shell as the user who owns the install directory (per-user installs
under %LOCALAPPDATA% need no elevation; Program Files does). Squirrel-based apps create
a new app-<version> folder on update, so re-run eli patch after an upgrade — the
dictionary and the local server are untouched.
Gotchas this project already solved
CSP — Electron's default
script-src 'self' blob:blockseval(). The loader executes fetched code through aBlobURL instead.Asar integrity — macOS bundles carry
ElectronAsarIntegrityinInfo.plist, plus a per-file SHA256 inside the archive header. Both are rewritten, and because hashes are fixed-length hex the header size never changes, so every file offset stays valid.Silent truncation — the free translate endpoint quietly cuts long input. Text is split on paragraph/sentence boundaries and stitched back together.
Self-translation loops — pass
--skipselectors for your own injected UI so it does not translate itself.
Use it from an AI agent (MCP)
eli mcp speaks the Model Context Protocol over stdio, so an assistant can inspect a
bundle, patch it, translate strings or locale files and revert — all without you leaving
the chat.
{
"mcpServers": {
"electron-live-i18n": {
"type": "stdio",
"command": "eli",
"args": ["mcp"]
}
}
}Tools exposed: inspect_app, patch_app, revert_app, translate_text,
translate_locale_file.
Example conversation:
You: This app's menu is in English, make it Traditional Chinese. Agent: (inspect_app → picks a 7 KB non-critical bundle → patch_app → tells you to restart)
Locale files on disk
eli locales locales/en.json locales/zh-TW.json --target zh-TWOnly untranslated strings are sent; existing translations in the destination file win, so
your manual fixes survive re-runs. Writes are atomic (tmp file + os.replace).
Translating whole Markdown docs
eli md README.md README.ja.md --target jaCode blocks, inline code, URLs and table rules are preserved; only prose is translated. The localized READMEs in this repo were produced this way.
Library use
from eli.translate import Translator
from eli.asar import read_header, patch_entry
tr = Translator(target="ja", cache_path=".cache.json")
print(tr.translate("Settings saved successfully"))
header, header_str, size, base = read_header("/path/to/app.asar")Scope and honesty
Developed and tested on macOS. Windows and Linux bundles use the same asar layout and are supported (see Platforms); the
Info.pliststep simply does not apply there.Patching a signed bundle invalidates its signature. On macOS an ad-hoc/unsigned app keeps working; a hardened, notarized app may refuse to launch. Test, and keep the backup.
This is a tool for your own machine and your own copy of an app. Respect the licence of whatever you are translating.
Licence
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityCmaintenanceAn MCP server that lets AI agents read and write locale JSON translation files directly from the conversation without loading the whole catalog into context.81ISC
- AlicenseAqualityCmaintenanceMCP server for interacting with and debugging Electron apps, providing tools for window automation, IPC, logs, and main-process state via CDP and Node inspector.208MIT
- AlicenseAqualityAmaintenanceMCP server for managing i18n translation files — gives your AI agent full control over your app's translations without dumping entire locale files into context.1325110MIT
- FlicenseBqualityAmaintenanceChatGPT-compatible MCP server and Electron launcher for controlled local project-file access, providing read-only and approval-gated write tools over STDIO or HTTP with optional OAuth and HTTPS tunneling.19
Related MCP Connectors
Translate MCP — wraps LibreTranslate API (https://libretranslate.com/)
An MCP server that gives your AI access to the source code and docs of all public github repos
MCP server for AI dialogue using various LLM models via AceDataCloud
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/dee0917/electron-live-i18n'
If you have feedback or need assistance with the MCP directory API, please join our Discord server