# angle-brackets/melomaniac architecture

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

- Interactive diagram: https://gitdiagram.com/angle-brackets/melomaniac
- Repository: https://github.com/angle-brackets/melomaniac
- Video tour (about a minute): https://gitdiagram.com/angle-brackets/melomaniac/video

## Overview

Melomaniac is a local-first music player whose central workflow is ingesting audio into a content-addressed library, organizing tracks into versioned playlists, and playing them across desktop and iOS. Playlist branches, commits, forks, and merges preserve history; LAN sync exchanges changes and media with paired devices. Spotify import, metadata editing, listening statistics, and storage management are complementary product branches. The README describes these capabilities; sampled Rust and UI excerpts support only selected storage, audio, startup, and UI-to-command links, so uncertain internal wiring is omitted.

Main entry points: [`src-tauri/src/storage.rs`](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/storage.rs) (Storage commands), [`src-tauri/crates/storage/src/db.rs`](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/db.rs) (Library database), [`src-tauri/crates/sync/src/lib.rs`](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/sync/src/lib.rs) (LAN sync), [`src/store/index.ts`](https://github.com/angle-brackets/melomaniac/blob/main/src/store/index.ts) (App state)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["Player experience"]
  node_app["App entry<br/>[App.tsx]"]
  node_desktop["Desktop UI<br/>[DesktopApp.tsx]"]
  node_mobile["Mobile UI<br/>[MobileApp.tsx]"]
  node_store["App state<br/>[index.ts]"]
  node_playback["Playback state<br/>[playbackSlice.ts]"]
  node_queue["Queue and shuffle<br/>[queueSlice.ts]"]
end

subgraph group_library["Library and playlists"]
  node_storage_cmd["Storage commands<br/>[storage.rs]"]
  node_ingest["Audio ingestion<br/>[ingest.rs]"]
  node_cas[("Blob store<br/>[cas.rs]")]
  node_database[("Library database<br/>[db.rs]")]
  node_playlist_tree["Playlist history<br/>[tree.rs]"]
  node_editor["Metadata editor<br/>[editor.rs]"]
  node_stats["Listening stats<br/>[stats.rs]"]
end

subgraph group_platform["Platform services"]
  node_audio_cmd["Audio commands<br/>[audio.rs]"]
  node_audio_bridge["Audio bridge<br/>[lib.rs]"]
  node_desktop_audio["Desktop audio<br/>[audio.rs]"]
  node_ios_audio["iOS audio<br/>[ios.rs]"]
end

subgraph group_connections["Import and sync"]
  node_downloader["Downloader<br/>[downloader.rs]"]
  node_spotify["Spotify integration<br/>[spotify.rs]"]
  node_matching["Track matching<br/>[matching.rs]"]
  node_sync_cmd["Sync commands<br/>[sync.rs]"]
  node_sync_core["LAN sync<br/>[lib.rs]"]
  node_sync_merge["Merge engine<br/>[merge.rs]"]
  node_oauth["OAuth bridge<br/>[lib.rs]"]
end

node_user(("Listener"))
node_spotify_service(("Spotify"))
node_peer(("Paired device"))
node_audio_output(("Audio output"))

node_user -->|"uses"| node_app
node_app -->|"selects platform"| node_desktop
node_app -->|"selects platform"| node_mobile
node_desktop -->|"updates state"| node_store
node_mobile -->|"updates state"| node_store
node_store -->|"holds state"| node_playback
node_store -->|"holds state"| node_queue
node_playback -->|"invokes"| node_audio_cmd
node_audio_cmd -->|"controls"| node_audio_bridge
node_audio_bridge -->|"selects desktop"| node_desktop_audio
node_audio_bridge -->|"selects iOS"| node_ios_audio
node_desktop_audio -->|"plays audio"| node_audio_output
node_ios_audio -->|"plays audio"| node_audio_output
node_desktop -->|"invokes"| node_storage_cmd
node_mobile -->|"invokes"| node_storage_cmd
node_storage_cmd -->|"ingests files"| node_ingest
node_ingest -->|"writes blobs"| node_cas
node_ingest -->|"indexes tracks"| node_database
node_storage_cmd -->|"reads and writes"| node_cas
node_storage_cmd -->|"reads and writes"| node_database
node_storage_cmd -->|"updates history"| node_playlist_tree
node_editor -->|"updates metadata"| node_database
node_editor -->|"writes artwork"| node_cas
node_downloader -->|"ingests download"| node_ingest
node_spotify -->|"authenticates"| node_oauth
node_spotify -->|"requests account data"| node_spotify_service
node_matching -->|"matches tracks"| node_database
node_sync_cmd -->|"dispatches sync"| node_sync_core
node_sync_core -->|"merges changes"| node_sync_merge
node_sync_core -->|"exchanges data"| node_peer
node_sync_core -->|"transfers blobs"| node_cas
node_sync_core -->|"updates records"| node_database
node_stats -->|"reads play history"| node_database

click node_app "https://github.com/angle-brackets/melomaniac/blob/main/src/App.tsx"
click node_desktop "https://github.com/angle-brackets/melomaniac/blob/main/src/desktop/DesktopApp.tsx"
click node_mobile "https://github.com/angle-brackets/melomaniac/blob/main/src/mobile/MobileApp.tsx"
click node_store "https://github.com/angle-brackets/melomaniac/blob/main/src/store/index.ts"
click node_playback "https://github.com/angle-brackets/melomaniac/blob/main/src/store/playbackSlice.ts"
click node_queue "https://github.com/angle-brackets/melomaniac/blob/main/src/store/queueSlice.ts"
click node_audio_cmd "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/audio.rs"
click node_audio_bridge "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/audio/src/lib.rs"
click node_desktop_audio "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/audio/src/desktop/audio.rs"
click node_ios_audio "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/audio/src/ios.rs"
click node_storage_cmd "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/storage.rs"
click node_ingest "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/ingest.rs"
click node_cas "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/cas.rs"
click node_database "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/db.rs"
click node_playlist_tree "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/tree.rs"
click node_editor "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/editor.rs"
click node_downloader "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/downloader.rs"
click node_spotify "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/spotify.rs"
click node_matching "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/matching.rs"
click node_sync_cmd "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/sync.rs"
click node_sync_core "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/sync/src/lib.rs"
click node_sync_merge "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/sync/src/merge.rs"
click node_stats "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/stats.rs"
click node_oauth "https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/oauth/src/lib.rs"

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_desktop,node_mobile,node_store,node_playback,node_queue toneBlue
class node_storage_cmd,node_ingest,node_cas,node_database,node_playlist_tree,node_editor,node_stats toneAmber
class node_audio_cmd,node_audio_bridge,node_desktop_audio,node_ios_audio toneMint
class node_downloader,node_spotify,node_matching,node_sync_cmd,node_sync_core,node_sync_merge,node_oauth toneRose
class node_user,node_spotify_service,node_peer,node_audio_output toneIndigo
```

## Components

### Player experience

- [App entry](https://github.com/angle-brackets/melomaniac/blob/main/src/App.tsx): `src/App.tsx`
- [Desktop UI](https://github.com/angle-brackets/melomaniac/blob/main/src/desktop/DesktopApp.tsx): `src/desktop/DesktopApp.tsx`
- [Mobile UI](https://github.com/angle-brackets/melomaniac/blob/main/src/mobile/MobileApp.tsx): `src/mobile/MobileApp.tsx`
- [App state](https://github.com/angle-brackets/melomaniac/blob/main/src/store/index.ts): `src/store/index.ts`
- [Playback state](https://github.com/angle-brackets/melomaniac/blob/main/src/store/playbackSlice.ts): `src/store/playbackSlice.ts`
- [Queue and shuffle](https://github.com/angle-brackets/melomaniac/blob/main/src/store/queueSlice.ts): `src/store/queueSlice.ts`

### Library and playlists

- [Storage commands](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/storage.rs): `src-tauri/src/storage.rs`
- [Audio ingestion](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/ingest.rs): `src-tauri/crates/storage/src/ingest.rs`
- [Blob store](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/cas.rs): `src-tauri/crates/storage/src/cas.rs`
- [Library database](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/db.rs): `src-tauri/crates/storage/src/db.rs`
- [Playlist history](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/storage/src/tree.rs): `src-tauri/crates/storage/src/tree.rs`
- [Metadata editor](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/editor.rs): `src-tauri/src/editor.rs`
- [Listening stats](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/stats.rs): `src-tauri/src/stats.rs`

### Platform services

- [Audio commands](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/audio.rs): `src-tauri/src/audio.rs`
- [Audio bridge](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/audio/src/lib.rs): `src-tauri/crates/audio/src/lib.rs`
- [Desktop audio](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/audio/src/desktop/audio.rs): `src-tauri/crates/audio/src/desktop/audio.rs`
- [iOS audio](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/audio/src/ios.rs): `src-tauri/crates/audio/src/ios.rs`

### Import and sync

- [Downloader](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/downloader.rs): `src-tauri/src/downloader.rs`
- [Spotify integration](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/spotify.rs): `src-tauri/src/spotify.rs`
- [Track matching](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/matching.rs): `src-tauri/src/matching.rs`
- [Sync commands](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/src/sync.rs): `src-tauri/src/sync.rs`
- [LAN sync](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/sync/src/lib.rs): `src-tauri/crates/sync/src/lib.rs`
- [Merge engine](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/sync/src/merge.rs): `src-tauri/crates/sync/src/merge.rs`
- [OAuth bridge](https://github.com/angle-brackets/melomaniac/blob/main/src-tauri/crates/oauth/src/lib.rs): `src-tauri/crates/oauth/src/lib.rs`

### Other components

- **Listener**
- **Spotify**
- **Paired device**
- **Audio output**

## Connections

- Listener → App entry: uses
- App entry → Desktop UI: selects platform
- App entry → Mobile UI: selects platform
- Desktop UI → App state: updates state
- Mobile UI → App state: updates state
- App state → Playback state: holds state
- App state → Queue and shuffle: holds state
- Playback state → Audio commands: invokes
- Audio commands → Audio bridge: controls
- Audio bridge → Desktop audio: selects desktop
- Audio bridge → iOS audio: selects iOS
- Desktop audio → Audio output: plays audio
- iOS audio → Audio output: plays audio
- Desktop UI → Storage commands: invokes
- Mobile UI → Storage commands: invokes
- Storage commands → Audio ingestion: ingests files
- Audio ingestion → Blob store: writes blobs
- Audio ingestion → Library database: indexes tracks
- Storage commands → Blob store: reads and writes
- Storage commands → Library database: reads and writes
- Storage commands → Playlist history: updates history
- Metadata editor → Library database: updates metadata
- Metadata editor → Blob store: writes artwork
- Downloader → Audio ingestion: ingests download
- Spotify integration → OAuth bridge: authenticates
- Spotify integration → Spotify: requests account data
- Track matching → Library database: matches tracks
- Sync commands → LAN sync: dispatches sync
- LAN sync → Merge engine: merges changes
- LAN sync → Paired device: exchanges data
- LAN sync → Blob store: transfers blobs
- LAN sync → Library database: updates records
- Listening stats → Library database: reads play history
