The Problem
Users need real‑time speech translation on desktop or in‑browser without juggling separate capture, AI, and UI components. Existing tools are either closed‑source, platform‑restricted, or require manual wiring of audio pipelines and API keys.
What This Does
sokuji ships six self‑contained projects that together deliver live translation via OpenAI, Google Gemini, Palabra.ai, and Kizuna AI.
- The Electron app (
electron/main.js) boots a Chromium window that loadssrc/index.html, which mounts the React tree undersrc/components/MainPanel/MainPanel.tsx. - The browser extension lives in
extension/, built with Webpack (extension/webpack.config.js) and packaged for Chrome/Edge. - Eval scripts (
evals/runner/cli.ts,evals/runner/index.ts) provide a CLI harness for automated testing of audio‑service integrations. - Shared utilities (
src/lib/analytics.ts,src/utils/environment.ts) and type definitions (src/types/Provider.ts) are reused across all projects.
How It Is Wired
Execution starts in electron/main.js (or docs/index.html for the web demo). The main process creates a BrowserWindow, then the renderer loads src/index.html, which runs the bundled React entry (src/main.tsx). React renders MainPanel – the UI hub that orchestrates audio capture, AI client selection, and result display.
- Audio flow –
src/lib/modern-audio/ModernBrowserAudioServiceis instantiated bysrc/services/ServiceFactory.ts(viacreateAudioService). The service emits raw PCM to the selected AI client (src/services/clients/*Client.ts). - AI clients implement
src/services/interfaces/IClient. The concrete classes (GeminiClient,OpenAIClient, etc.) are selected based onsrc/types/Provider.tsand user settings stored insrc/stores/settingsStore.ts. - Analytics –
src/lib/analytics.tssubscribes to events fromsettingsStore,audioStore, and UI components, sending data to PostHog. This module is a hub (22 inbound imports) and participates in a circular import withaudioStoreandServiceFactory. - State management – Redux‑style stores (
src/stores/*Store.ts) expose observable state;MainPanelreadssettingsStoreandaudioStoreto drive UI updates. - Extension –
extension/background.tsmirrors the same service factory logic but runs in a service worker, communicating with content scripts via Chrome messaging.
Circular dependencies (35 edges) involve analytics.ts, audioStore.ts, and ServiceFactory.ts; they increase change‑impact risk because a modification can trigger recompilation of multiple bundles. The most fan‑in module (src/types/Provider.ts) is a stability anchor – keep its API minimal.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/sokuji.git
cd sokuji
# Install all npm workspaces
npm ci
# Copy example env and fill in your API keys
cp .env.example .env
# edit .env → set OPENAI_API_KEY, GEMINI_API_KEY, etc.
# Run the desktop app (development mode)
npm run dev # defined in package.json, invokes electron/main.js via vite
# Build the browser extension
npm run build:extension # uses extension/webpack.config.js, outputs to dist/
The Electron app reads .env at startup; the extension expects the same variables injected at build time (see docs/README.md for details). No additional database or server is required.
Real‑World Use
A remote‑learning platform can embed the extension in its web UI. When a teacher speaks, ModernBrowserAudioService captures the microphone stream, forwards it to OpenAIClient via the Realtime API, and the translated subtitles are injected into the video element by the content script (extension/contentScript.ts). The same flow works in the desktop app for standalone meetings.
Code Health & Issues
- High – Pin third‑party GitHub Actions to commit SHAs (
.github/workflows/*). - Medium – Add Dependabot (
.github/dependabot.yml). - Medium – Gate PRs with a dependency‑vulnerability scan (
dependency-review-actionorosv-scanner). - Medium – Move large binary
screenshots/demo.mp4(5.8 MiB) to Git LFS. - Medium – Set
persist-credentials: falseon checkout steps (.github/workflows/build.yml). - Medium – Expand test coverage; only 1 test file covers 131 source files (ratio 0.008).
- Low – Define
timeout-minuteson CI jobs. - Low – Add convention files (
.editorconfig,.gitattributes, formatter config).
Static analysis also flagged 40 import‑cycle members, six oversized files (e.g., src/components/MainPanel/MainPanel.tsx at 740 lines), and deep nesting (max depth 8) in UI components. These patterns inflate cognitive load and increase the blast radius of changes.
The Bottom Line
sokuji provides a functional, cross‑platform live translation stack with clear entry points and reusable service factories, but the codebase suffers from import cycles, large monolithic modules, and modest test coverage. It is suitable for teams that need a quick prototype or are willing to invest in refactoring the identified hotspots.