# anshm42/translatify architecture

> Architecture diagram of the GitHub repository anshm42/translatify, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/anshm42/translatify
- Repository: https://github.com/anshm42/translatify

## Overview

Translatify follows Spotify playback through lyric retrieval and translation to a time-synced karaoke display. The main-process Controller owns that workflow, including cache lookups, language-change refreshes, and renderer updates; Spotify, LRCLIB, and DeepL are separate integrations. The renderer handles setup and presentation through a typed preload/IPC boundary. The README documents local persistence, but the sampled source does not show how config, store, and cache are wired internally, so those relationships are left out.

Main entry points: [`src/main/controller.ts`](https://github.com/anshm42/translatify/blob/main/src/main/controller.ts) (Workflow controller), [`src/renderer/src/App.tsx`](https://github.com/anshm42/translatify/blob/main/src/renderer/src/App.tsx) (App shell), [`src/preload/index.ts`](https://github.com/anshm42/translatify/blob/main/src/preload/index.ts) (Preload bridge), [`src/main/spotify.ts`](https://github.com/anshm42/translatify/blob/main/src/main/spotify.ts) (Spotify client)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui["Renderer interface"]
  node_app["App shell<br/>[App.tsx]"]
  node_settings["Settings<br/>[Settings.tsx]"]
  node_language["Language selector"]
  node_karaoke["Karaoke view<br/>[KaraokeView.tsx]"]
end

subgraph group_boundary["Electron boundary"]
  node_preload["Preload bridge<br/>[index.ts]"]
  node_ipc["IPC contract<br/>[ipc.ts]"]
end

subgraph group_workflow["Main workflow"]
  node_main["Electron main<br/>[index.ts]"]
  node_controller["Workflow controller<br/>[controller.ts]"]
  node_lrc["LRC parser<br/>[lrc.ts]"]
  node_cache[("Result cache<br/>[cache.ts]")]
  node_config["Settings config<br/>[config.ts]"]
  node_store[("Local store<br/>[store.ts]")]
end

subgraph group_integrations["External services"]
  node_spotify["Spotify client<br/>[spotify.ts]"]
  node_lyrics["Lyrics lookup<br/>[lyrics.ts]"]
  node_translate["Translation client<br/>[translate.ts]"]
end

node_listener(("Listener"))
node_spotify_service["Spotify API"]
node_lrclib["LRCLIB"]
node_deepl["DeepL API"]
node_browser["System browser"]

node_listener -->|"uses"| node_app
node_app -->|"renders"| node_settings
node_app -->|"renders"| node_language
node_app -->|"renders"| node_karaoke
node_app -->|"invokes, subscribes"| node_preload
node_preload -->|"IPC requests"| node_main
node_main -->|"dispatches"| node_controller
node_main -->|"reads, writes"| node_config
node_controller -->|"connects, resumes"| node_spotify
node_spotify -->|"authenticates, polls"| node_spotify_service
node_spotify -->|"opens auth"| node_browser
node_spotify -->|"emits track, playback"| node_controller
node_controller -->|"reads, writes"| node_cache
node_controller -->|"fetches lyrics"| node_lyrics
node_lyrics -->|"searches"| node_lrclib
node_controller -->|"parses LRC"| node_lrc
node_controller -->|"translates lines"| node_translate
node_translate -->|"sends batches"| node_deepl
node_controller -->|"reads settings"| node_config
node_controller -->|"pushes updates"| node_preload
node_preload -->|"delivers events"| node_app
node_karaoke -->|"finds active line"| node_lrc
node_settings -->|"requests settings, connection"| node_preload
node_language -->|"changes target"| node_app

click node_app "https://github.com/anshm42/translatify/blob/main/src/renderer/src/App.tsx"
click node_settings "https://github.com/anshm42/translatify/blob/main/src/renderer/src/components/Settings.tsx"
click node_language "https://github.com/anshm42/translatify/blob/main/src/renderer/src/components/LanguageSelector.tsx"
click node_karaoke "https://github.com/anshm42/translatify/blob/main/src/renderer/src/components/KaraokeView.tsx"
click node_preload "https://github.com/anshm42/translatify/blob/main/src/preload/index.ts"
click node_ipc "https://github.com/anshm42/translatify/blob/main/src/shared/ipc.ts"
click node_main "https://github.com/anshm42/translatify/blob/main/src/main/index.ts"
click node_controller "https://github.com/anshm42/translatify/blob/main/src/main/controller.ts"
click node_spotify "https://github.com/anshm42/translatify/blob/main/src/main/spotify.ts"
click node_lyrics "https://github.com/anshm42/translatify/blob/main/src/main/lyrics.ts"
click node_translate "https://github.com/anshm42/translatify/blob/main/src/main/translate.ts"
click node_lrc "https://github.com/anshm42/translatify/blob/main/src/shared/lrc.ts"
click node_cache "https://github.com/anshm42/translatify/blob/main/src/main/cache.ts"
click node_config "https://github.com/anshm42/translatify/blob/main/src/main/config.ts"
click node_store "https://github.com/anshm42/translatify/blob/main/src/main/store.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_settings,node_language,node_karaoke,node_browser toneBlue
class node_preload,node_ipc toneAmber
class node_main,node_controller,node_lrc,node_cache,node_config,node_store,node_spotify_service,node_deepl toneMint
class node_spotify,node_lyrics,node_translate toneRose
class node_listener,node_lrclib toneIndigo
```

## Components

### Renderer interface

- [App shell](https://github.com/anshm42/translatify/blob/main/src/renderer/src/App.tsx): `src/renderer/src/App.tsx`
- [Settings](https://github.com/anshm42/translatify/blob/main/src/renderer/src/components/Settings.tsx): `src/renderer/src/components/Settings.tsx`
- [Language selector](https://github.com/anshm42/translatify/blob/main/src/renderer/src/components/LanguageSelector.tsx): `src/renderer/src/components/LanguageSelector.tsx`
- [Karaoke view](https://github.com/anshm42/translatify/blob/main/src/renderer/src/components/KaraokeView.tsx): `src/renderer/src/components/KaraokeView.tsx`

### Electron boundary

- [Preload bridge](https://github.com/anshm42/translatify/blob/main/src/preload/index.ts): `src/preload/index.ts`
- [IPC contract](https://github.com/anshm42/translatify/blob/main/src/shared/ipc.ts): `src/shared/ipc.ts`

### Main workflow

- [Electron main](https://github.com/anshm42/translatify/blob/main/src/main/index.ts): `src/main/index.ts`
- [Workflow controller](https://github.com/anshm42/translatify/blob/main/src/main/controller.ts): `src/main/controller.ts`
- [LRC parser](https://github.com/anshm42/translatify/blob/main/src/shared/lrc.ts): `src/shared/lrc.ts`
- [Result cache](https://github.com/anshm42/translatify/blob/main/src/main/cache.ts): `src/main/cache.ts`
- [Settings config](https://github.com/anshm42/translatify/blob/main/src/main/config.ts): `src/main/config.ts`
- [Local store](https://github.com/anshm42/translatify/blob/main/src/main/store.ts): `src/main/store.ts`

### External services

- [Spotify client](https://github.com/anshm42/translatify/blob/main/src/main/spotify.ts): `src/main/spotify.ts`
- [Lyrics lookup](https://github.com/anshm42/translatify/blob/main/src/main/lyrics.ts): `src/main/lyrics.ts`
- [Translation client](https://github.com/anshm42/translatify/blob/main/src/main/translate.ts): `src/main/translate.ts`

### Other components

- **Listener**
- **Spotify API**
- **LRCLIB**
- **DeepL API**
- **System browser**

## Connections

- Listener → App shell: uses
- App shell → Settings: renders
- App shell → Language selector: renders
- App shell → Karaoke view: renders
- App shell → Preload bridge: invokes, subscribes
- Preload bridge → Electron main: IPC requests
- Electron main → Workflow controller: dispatches
- Electron main → Settings config: reads, writes
- Workflow controller → Spotify client: connects, resumes
- Spotify client → Spotify API: authenticates, polls
- Spotify client → System browser: opens auth
- Spotify client → Workflow controller: emits track, playback
- Workflow controller → Result cache: reads, writes
- Workflow controller → Lyrics lookup: fetches lyrics
- Lyrics lookup → LRCLIB: searches
- Workflow controller → LRC parser: parses LRC
- Workflow controller → Translation client: translates lines
- Translation client → DeepL API: sends batches
- Workflow controller → Settings config: reads settings
- Workflow controller → Preload bridge: pushes updates
- Preload bridge → App shell: delivers events
- Karaoke view → LRC parser: finds active line
- Settings → Preload bridge: requests settings, connection
- Language selector → App shell: changes target
