Architecture Overview
High-level architecture of the Ingglish project.
Project Structure
ingglish/
βββ packages/
β βββ normalize/ # Text cleanup, case handling, tokenization, word patterns
β βββ phonemes/ # Phoneme data + conversion
β βββ dictionary/ # CMU dict, lookup, frequency
β βββ g2p/ # Rule-based grapheme-to-phoneme
β βββ ipa/ # IPA β ARPAbet conversion
β βββ shavian/ # Shavian alphabet conversion
β βββ deseret/ # Deseret alphabet conversion
β βββ fallback/ # Unknown word strategies
β βββ core/ # Translation API (translate + reverse)
β βββ dom/ # DOM translation utilities
β βββ website/ # React web application
β βββ extension/ # Chrome extension
β βββ cors-proxy/ # Cloudflare Worker proxy
βββ docs/ # Documentation
βββ .github/ # CI/CD workflows
Package Dependencies
@ingglish/normalize (0 deps)
@ingglish/phonemes (0 deps) ββ
@ingglish/dictionary (0 deps) ββ€
@ingglish/g2p βββΊ phonemes ββΌββ @ingglish/fallback
β
@ingglish/ipa βββΊ phonemes β
@ingglish/shavian βββΊ phonemes + dictionary
@ingglish/deseret βββΊ phonemes + dictionary
β
ingglish βββ all above packages
β²
@ingglish/dom βββΊ @ingglish/normalize (peer: core)
β²
@ingglish/website βββΊ @ingglish/dom + ingglish
@ingglish/extension βββΊ ingglish
Library Packages
@ingglish/normalize - Text cleanup, case handling, tokenization
src/
βββ index.ts # Barrel exports
βββ case.ts # Case pattern detection/application, splitCamelCase
βββ text.ts # normalizeApostrophes, stripDiacritics, URL/email preservation
βββ tokenize.ts # WORD_SPLIT_REGEX, WORD_TEST_REGEX, tokenizeText, tokenizeIPA, etc.
@ingglish/phonemes - Phoneme data + conversion
src/
βββ index.ts # Barrel exports
βββ arpabet.ts # ARPAbet phoneme definitions
βββ phonotactics.ts # English sound rules for stress
βββ types.ts # OutputFormat type
βββ to-ingglish.ts # ARPAbet β Ingglish
βββ from-ingglish.ts # Ingglish β ARPAbet
βββ ingglish-maps.ts # Phoneme mapping tables
βββ custom-format.ts # Custom format registration
βββ format-registry.ts # Format registry for extensible output
@ingglish/dictionary - CMU dict, lookup, frequency
src/
βββ index.ts # Barrel exports
βββ loader.ts # Load and cache CMU dictionary
βββ lookup.ts # Word pronunciation lookup
βββ reverse.ts # Build reverse index (phoneme β words)
βββ frequency.ts # Word frequency ranking
βββ custom-words.ts # Custom pronunciations (tech terms)
βββ data/ # Generated dictionary and frequency data
@ingglish/g2p - Rule-based grapheme-to-phoneme
src/
βββ index.ts # Public API
βββ g2p-rules.ts # Core G2P conversion rules
βββ stress.ts # Stress assignment
βββ stress.test.ts # Stress prediction tests
@ingglish/ipa - IPA β ARPAbet conversion
src/
βββ index.ts # Barrel exports
βββ to-ipa.ts # ARPAbet β IPA with stress
βββ from-ipa.ts # IPA β ARPAbet
@ingglish/shavian - Shavian alphabet conversion
src/
βββ index.ts # Barrel exports
βββ to-shavian.ts # ARPAbet β Shavian
βββ from-shavian.ts # Shavian β ARPAbet
βββ shavian-maps.ts # Shavian mapping tables
βββ tokenize.ts # Shavian tokenization
@ingglish/deseret - Deseret alphabet conversion
src/
βββ index.ts # Barrel exports
βββ to-deseret.ts # ARPAbet β Deseret
βββ from-deseret.ts # Deseret β ARPAbet
βββ deseret-maps.ts # Deseret mapping tables
βββ tokenize.ts # Deseret tokenization
@ingglish/fallback - Unknown word strategies
src/
βββ index.ts # Fallback orchestration
βββ acronyms.ts # Acronym/initialism handling
βββ compounds.ts # Compound word splitting
βββ stemming.ts # Base word + suffix matching
βββ british.ts # British spelling variants
ingglish - Translation API
The core package is a thin orchestration layer. It imports from the packages above and exports the public translation API.
src/
βββ index.ts # Public API: translate, reverseTranslate, Sync variants
βββ dict-loader.ts # Per-language dictionary registration/loading
βββ register-english.ts # Registers the English dictionary loader
βββ translate/ # Translation logic
βββ index.ts # Re-exports the translate/reverse API
βββ forward.ts # English β Ingglish/IPA (incl. contractions)
βββ reverse.ts # Ingglish/IPA β English (incl. contractions)
βββ pipeline.ts # Shared tokenize β map β render stages
βββ preserved.ts # URL/email preservation during translation
Contraction handling ("don't", "I'm") lives inline in forward.ts/reverse.ts;
there is no separate contractions or language-detection module.
Translation Flow
English Text
β
βΌ
βββββββββββββββββββ
β translateText β (format: 'ingglish' | 'ipa')
ββββββββββ¬βββββββββ
β tokenize
βΌ
βββββββββββββββββββ ββββββββββββββββββββββββ
β translateWord βββββ>β lookupPronunciation β
ββββββββββ¬βββββββββ ββββββββββ¬ββββββββββββββ
β β
β found? β CMU Dictionary
β β
ββββββ΄βββββ β
β β βΌ
βΌ βΌ ββββββββββββββββ
phonemes unknown β phonemes β
β β ββββββββ¬ββββββββ
β β β
β ββββββ΄βββββ β
β β stemmingβ β
β β rules β β
β ββββββ¬βββββ β
β β β
ββββββ¬βββββ β
β β
βΌ β
ββββββββββββββββββββββ β
β Output Format? β<βββββββββββ
ββββββββββ¬ββββββββββββ
β
ββββββ΄βββββ
β β
βΌ βΌ
Ingglish IPA
β β
βΌ βΌ
βββββββββββββ βββββββββββββ
β phonemes β βphonemesTo β
βToIngglish β β IPA β
βββββββ¬ββββββ βββββββ¬ββββββ
β β
βΌ βΌ
"haloh" "/hΙΛloΚ/"
Reverse Translation Flow
Supports both Ingglish and IPA input:
Ingglish Text IPA Text
β β
βΌ βΌ
βββββββββββββββββββ ββββββββββββββββββββββ
βreverseTranslate β β reverseTranslate β
β Text β β IPAText β
ββββββββββ¬βββββββββ βββββββββββ¬βββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββββ ββββββββββββββββββββββ
βingglishToPhonemes β β ipaToArpabet β
βββββββββββ¬βββββββββββ βββββββββββ¬βββββββββββ
β β
βββββββββββββ¬ββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β lookupByPhonemes β Reverse dictionary lookup
ββββββββββ¬βββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β sortByFrequency β Rank homophones
ββββββββββ¬βββββββββββββ
β
βΌ
English Text (most common match)
Key Data Structures
CMU Dictionary
// Word β Phoneme array (pre-split at build time)
{
"hello": ["HH", "AH0", "L", "OW1"],
"world": ["W", "ER1", "L", "D"],
...
}
Reverse Dictionary (built at runtime)
// Phoneme key β English words (sorted by frequency)
Map<string, string[]>
{
"T UW": ["to", "too", "two"],
"DH EH R": ["there", "their", "they're"],
...
}
Phoneme Map
// ARPAbet β Ingglish spelling
{
"HH": "h",
"AH": "uh",
"L": "l",
"OW": "oh",
...
}
DOM Library (@ingglish/dom)
Browser-only utilities for translating DOM content.
Module Structure
src/
βββ index.ts # Public API exports
βββ types.ts # DOMTranslatorOptions interface
βββ translate/ # DOM translation logic
β βββ index.ts # translateDOM orchestration
β βββ translator.ts # Core DOM translation algorithm
β βββ apply-map.ts # Apply pre-computed translations
β βββ chunked.ts # requestAnimationFrame chunked processing
β βββ restore.ts # Restore original text
β βββ tooltip-fragment.ts # Hover tooltip HTML generation
βββ traversal/ # DOM traversal
βββ index.ts # Traversal exports
βββ browser.ts # Browser detection
βββ extract.ts # Word extraction from text nodes
βββ skip-rules.ts # Skip logic for tags/classes
βββ text-nodes.ts # TreeWalker and text node utilities
βββ tooltip.ts # Tooltip styling utilities
Public API: translateDOM / translateDOMSync, restoreDOM, and
applyTranslationsMap, plus traversal helpers (collectTextNodes,
extractWordsFromNodes, injectTooltipStyles, injectTooltipBehavior).
Key Features
- Chunked translation: Uses
requestAnimationFramefor smooth rendering on large pages - Tooltip support: Wraps translated words in spans with original text on hover
- Attribute translation: Handles
title,alt,placeholder,aria-label - Skip logic: Respects
<code>,<pre>,.no-translate,contenteditable - Pre-computed translations:
applyTranslationsMap()for external translation sources
Live MutationObserver handling (auto-translating dynamically added content) is implemented in the Chrome extension's content script, not in this package.
Website (@ingglish/website)
React single-page application with three main features:
Components
src/
βββ components/
β βββ TextTranslator.tsx # Bidirectional text translation
β βββ UrlTranslator.tsx # Web page translation
β βββ SpellingGuide.tsx # Phoneme mapping reference
β βββ Extension.tsx # Chrome extension info page
β βββ Docs.tsx # Documentation viewer
βββ contexts/
β βββ FormatContext.tsx # Output format state (Ingglish/IPA)
βββ hooks/
β βββ useUrlTranslator.ts # URL fetching & translation logic
βββ App.tsx # Tab navigation & routing
URL Translation Architecture
βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β Browser βββββ>β CORS Proxy βββββ>β Target Site β
β (iframe) β β (Worker) β β β
βββββββββββββββ βββββββββββββββ ββββββββββββββββ
β
βΌ
βββββββββββββββ
β translateDOMβ In-place DOM modification
βββββββββββββββ
- User enters URL
- Website fetches via CORS proxy
- HTML is written to sandboxed iframe
translateDOMfrom@ingglish/domwalks text nodes and translates- Links are intercepted for navigation within iframe
Chrome Extension (@ingglish/extension)
Components
src/
βββ manifest.json # Extension configuration
βββ content-script.ts # Content script (DOM walking + message passing)
βββ background.ts # Service worker (holds dictionary ~5MB)
βββ popup.ts # Popup UI
Architecture
The extension uses a message-passing architecture to keep the content script lightweight:
- Background service worker: Loads the full CMU dictionary (~5MB) once
- Content script: Lightweight (~11KB), walks DOM and sends words to background for translation
- Translation cache: 50K entry in-memory cache in background for fast repeated lookups
Flow
ββββββββββββββββ ββββββββββββββββ
β Popup UI βββββ>β Message β
β (popup.ts) β β Passing β
ββββββββββββββββ ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Content Script (content-script.ts) β
β β’ Walks DOM, collects text nodes β
β β’ Sends batches of words to background β
β β’ Applies translations in chunks (RAF) β
β β’ Debounced MutationObserver (100ms) β
β β’ In-place span updates for format switching β
ββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββ
β chrome.runtime.sendMessage
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Background (background.ts) β
β β’ Loads CMU dictionary on startup β
β β’ Caches translations (50K entries, FIFO) β
β β’ Returns translated words β
β β’ Manages tab-specific translation state β
ββββββββββββββββββββββββββββββββββββββββββββββββββββ
Performance Optimizations
Debounced MutationObserver: Waits 100ms for mutations to settle before processing, preventing freezes on sites with rapid DOM updates (e.g., infinite scroll)
In-place format switching: When switching between Ingglish and IPA, updates existing spans directly instead of restoring and re-translating the entire page
Chunked DOM updates: Uses
requestAnimationFrameto apply translations in chunks of 50 elements, keeping the main thread responsivePre-collected text nodes: Passes pre-collected nodes to
applyTranslationsMap()to avoid double DOM traversal
CORS Proxy (@ingglish/cors-proxy)
Cloudflare Worker that proxies requests to bypass CORS restrictions.
ββββββββββββββ βββββββββββββββββββββ βββββββββββββββ
β Website βββββ>β Cloudflare Worker βββββ>β Target URL β
β β β β β β
β β<βββββ + CORS headers β<βββββ β
ββββββββββββββ βββββββββββββββββββββ βββββββββββββββ
Security features:
- Origin allowlist validation
- SSRF prevention (blocks private IP ranges: 127., 10., 172.16-31., 192.168., ::1)
- Protocol restriction (HTTP/HTTPS only)
- Content-Type checking (HTML only)
- Cache control headers (minimum 5 minutes)
Data Flow Summary
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Build Time β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β CMU Dictionary (126K words) ββ> bundled with @ingglish/dictionaryβ
β SUBTLEX Frequencies (74K) ββ> bundled with @ingglish/dictionary β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Runtime β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β loadDictionary() ββ> parse & cache dictionary β
β translateText() ββ> O(n) word lookup + phoneme conversion β
β reverseTranslate() ββ> O(1) phoneme key lookup + frequency β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
All paths are linear (no quadratic or exponential complexity). Dictionary data is loaded on-demand via dynamic imports.
See Performance for complexity tables, profiling scripts, and optimization guidelines.