| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
Translations: 繁體中文 · 简体中文 · 日本語 · 한국어 · Español · Français · Deutsch
Margin Read is a privacy-first browser extension for bilingual webpage translation.
Privacy-first bilingual web translation that keeps the original text in place so you never lose context.
Margin keeps the original webpage text in place and inserts translated text below the matching source blocks, so readers can compare both versions without losing page context.
Repository: https://github.com/withmargin/margin-read
Margin is an early MVP for Chrome and Chromium browsers using Manifest V3.
The extension is usable for normal article pages, legacy text-heavy pages, and selected dynamic pages, but it is still under active development. Expect rough edges on highly interactive web apps, pages with unusual layout systems, and sites that aggressively rewrite their DOM.
Margin does not include PDF translation, EPUB translation, subtitle translation, OCR, input box translation, cloud sync, accounts, social features, default telemetry, or an official paid translation quota system.
Beta testers can install Margin from the Chrome Web Store beta listing when invited, from a GitHub Release ZIP, or from a local source build. See the Beta Testing Guide for the full setup and feedback workflow.
For local development, load Margin as an unpacked extension:
corepack enable
pnpm install
pnpm buildThen:
No API key is bundled with Margin. Users provide their own raw provider API key without a Bearer prefix.
Built-in providers use default endpoints:
OpenAI: https://api.openai.com/v1/chat/completions
Anthropic Claude: https://api.anthropic.com/v1/messages
Google Gemini: https://generativelanguage.googleapis.com/v1beta/models
The endpoint field is shown only for compatible / Local LLM setups, where the user is expected to choose or enter a local endpoint.
The Fetch models action reads available models from the selected provider:
Fetched models appear in the model selector. Margin keeps the currently configured model as an option when a provider default or previously saved model is not returned by the provider list.
Margin sends only selected text segments to the configured provider. It does not send full page HTML by default, does not require login, does not use cloud sync, and does not include telemetry by default.
Provider requests are made by the extension service worker using the endpoint and API key configured by the user. Provider privacy depends on the endpoint and model provider you choose.
API keys are stored in browser extension storage. Treat the browser profile as part of your trusted environment.
Margin includes an optional X-specific detector for timeline cards and longform article pages. When enabled, it targets tweetText content inside tweet articles and readable blocks inside X article views instead of scanning every visible text node.
Quoted posts are disabled by default and can be enabled from options. Posts that X already marks as translated are skipped by default to avoid duplicate translation.
Margin supports local LLM runtimes through compatible providers:
Both compatible providers allow an empty API key and use lower default translation concurrency for local inference. If an Anthropic-compatible gateway requires a key, Margin sends it as Authorization: Bearer ....
Common compatible endpoints:
LM Studio: http://localhost:1234/v1/chat/completions
Ollama: http://localhost:11434/v1/chat/completions
llama.cpp server: http://localhost:8080/v1/chat/completions
omlx: http://localhost:8000/v1/chat/completions
Generic Anthropic-compatible: http://localhost:8000/v1/messages
Ollama Anthropic compatibility: http://localhost:11434/v1/messages
To use a local runtime:
Runtime notes:
Local model quality, speed, context length, and JSON reliability depend on the model and runtime. Instruct models with strong multilingual ability are recommended for translation.
Install dependencies:
corepack enable
pnpm installRun the dev server with hot reloading (Vite + CRXJS). Load apps/extension/dist/ as an unpacked extension once, then edit source and the extension reloads automatically:
pnpm --filter @margin/extension devRun type checks:
pnpm checkRun lint:
pnpm lintRun extension manifest and security checks:
pnpm check:extensionRun tests with coverage:
pnpm testBuild the extension:
pnpm buildThe build uses Vite with the CRXJS plugin (Rolldown under the hood) and writes the unpacked extension to apps/extension/dist/.
apps/extension/src/background/ Service worker, provider requests, settings, and cache flow
apps/extension/src/content/ Page text detection, queueing, and translation insertion
apps/extension/src/options/ Extension options page
apps/extension/src/popup/ Popup UI and diagnostics
apps/extension/src/background/providers/ Provider adapters
apps/extension/src/shared/ Shared types, defaults, storage, and messages
apps/extension/public/ Static assets (icons) copied verbatim into the build
apps/extension/*.html Popup and options HTML entry points
apps/extension/scripts/ Build and extension validation scripts
docs/ Product, roadmap, principles, and threat model
Enable Debug mode in Margin options when a page appears enabled but no translations are inserted. The popup will show the current page detection count, queued blocks, running requests, pending translations, completed translations, error count, the latest error, and a sample detected text block.
Use those values to separate the main failure modes:
MIT
| Back | FazBrowse Home | New Git URL |