# onizuka-sh/streamplex architecture

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

- Interactive diagram: https://gitdiagram.com/onizuka-sh/streamplex
- Repository: https://github.com/onizuka-sh/streamplex

## Overview

StreamPlex is a local-first media library and streaming server, presented through a React interface and optionally wrapped in an Electron desktop runtime. The main workflow is sign-in or first-time setup, discover media, analyze files and enrich metadata, then browse and stream the resulting library. The graph preserves the documented scan, metadata, playback, history, settings, and desktop capabilities. Some controller and frontend wiring is inferred only at the route/API boundary because those source excerpts were not supplied.

Main entry points: [`backend/src/app.js`](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/app.js) (Express App), [`backend/src/pipeline/enrich.pipeline.js`](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/pipeline/enrich.pipeline.js) (Metadata Enrichment), [`backend/src/services/scanner.service.js`](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/scanner.service.js) (Media Discovery), [`backend/src/pipeline/analyze.pipeline.js`](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/pipeline/analyze.pipeline.js) (File Analysis)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_desktop["Desktop Runtime"]
  node_electron["Electron Shell<br/>[main.js]"]
  node_preload["IPC Bridge<br/>[preload.js]"]
end

subgraph group_experience["User Experience"]
  node_react["React App<br/>[App.jsx]"]
  node_api_client["API Client<br/>[api.js]"]
  node_auth_ui["Auth Context<br/>[AuthContext.jsx]"]
  node_media_ui["Library Screens<br/>[Home.jsx]"]
end

subgraph group_api["API and Access"]
  node_server["Express App<br/>[app.js]"]
  node_auth_routes["Auth Routes<br/>[auth.routes.js]"]
  node_scan_routes["Scan Routes<br/>[scan.routes.js]"]
  node_video_routes["Video Routes<br/>[video.routes.js]"]
  node_stream_routes["Stream Routes<br/>[stream.routes.js]"]
  node_history_routes["History Routes"]
  node_auth_controller["Authentication<br/>[auth.controller.js]"]
  node_stream_controller["Media Streaming"]
end

subgraph group_library["Library Processing"]
  node_scanner["Media Discovery<br/>[scanner.service.js]"]
  node_analysis["File Analysis"]
  node_enrichment["Metadata Enrichment<br/>[enrich.pipeline.js]"]
  node_filename_parser["Filename Parser"]
  node_tmdb["TMDB Metadata<br/>[tmdb.service.js]"]
end

subgraph group_state["Persistent State"]
  node_video_model["Video Records<br/>[video.model.js]"]
  node_scan_model["Scan Records<br/>[scan.model.js]"]
  node_genre_model["Genre Records<br/>[genre.model.js]"]
  node_sqlite[("SQLite Database<br/>[db.js]")]
end

node_user(("Viewer / Admin"))
node_media_files[("Media Folder")]
node_tmdb_service(("TMDB Service"))

node_user -->|"uses"| node_react
node_electron -->|"exposes IPC"| node_preload
node_electron -->|"starts backend"| node_server
node_electron -->|"loads desktop UI"| node_react
node_react -->|"uses auth"| node_auth_ui
node_react -->|"routes to"| node_media_ui
node_auth_ui -->|"requests auth"| node_api_client
node_media_ui -->|"requests library"| node_api_client
node_api_client -->|"sends API requests"| node_server
node_server -->|"mounts routes"| node_auth_routes
node_server -->|"mounts routes"| node_scan_routes
node_server -->|"mounts routes"| node_video_routes
node_server -->|"mounts routes"| node_stream_routes
node_server -->|"mounts routes"| node_history_routes
node_auth_routes -->|"dispatches"| node_auth_controller
node_stream_routes -->|"dispatches"| node_stream_controller
node_scan_routes -->|"dispatches scan"| node_scanner
node_scanner -->|"discovers files"| node_media_files
node_scanner -->|"updates scan state"| node_scan_model
node_scanner -->|"starts analysis"| node_analysis
node_analysis -->|"loads and updates"| node_video_model
node_analysis -->|"increments progress"| node_scan_model
node_analysis -->|"starts enrichment"| node_enrichment
node_enrichment -->|"loads and updates"| node_video_model
node_enrichment -->|"parses names"| node_filename_parser
node_enrichment -->|"fetches metadata"| node_tmdb
node_enrichment -->|"syncs genres"| node_genre_model
node_enrichment -->|"increments progress"| node_scan_model
node_tmdb -.->|"looks up metadata"| node_tmdb_service
node_stream_controller -->|"loads video record"| node_video_model
node_stream_controller -->|"streams file bytes"| node_media_files
node_video_model -->|"reads and writes"| node_sqlite
node_scan_model -->|"reads and writes"| node_sqlite
node_genre_model -->|"reads and writes"| node_sqlite

click node_electron "https://github.com/onizuka-sh/streamplex/blob/main/electron/main.js"
click node_preload "https://github.com/onizuka-sh/streamplex/blob/main/electron/preload.js"
click node_react "https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/App.jsx"
click node_api_client "https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/services/api.js"
click node_auth_ui "https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/context/AuthContext.jsx"
click node_media_ui "https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/pages/Home.jsx"
click node_server "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/app.js"
click node_auth_routes "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/auth.routes.js"
click node_scan_routes "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/scan.routes.js"
click node_video_routes "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/video.routes.js"
click node_stream_routes "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/stream.routes.js"
click node_history_routes "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/watchHistory.routes.js"
click node_auth_controller "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/controllers/auth.controller.js"
click node_stream_controller "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/controllers/stream.controller.js"
click node_scanner "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/scanner.service.js"
click node_analysis "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/pipeline/analyze.pipeline.js"
click node_enrichment "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/pipeline/enrich.pipeline.js"
click node_filename_parser "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/filenameParser.service.js"
click node_tmdb "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/tmdb.service.js"
click node_video_model "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/models/video.model.js"
click node_scan_model "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/models/scan.model.js"
click node_genre_model "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/models/genre.model.js"
click node_sqlite "https://github.com/onizuka-sh/streamplex/blob/main/backend/src/database/db.js"

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_electron,node_preload,node_user toneBlue
class node_react,node_api_client,node_auth_ui,node_media_ui,node_media_files toneAmber
class node_server,node_auth_routes,node_scan_routes,node_video_routes,node_stream_routes,node_history_routes,node_auth_controller,node_stream_controller toneMint
class node_scanner,node_analysis,node_enrichment,node_filename_parser,node_tmdb toneRose
class node_video_model,node_scan_model,node_genre_model,node_sqlite,node_tmdb_service toneIndigo
```

## Components

### Desktop Runtime

- [Electron Shell](https://github.com/onizuka-sh/streamplex/blob/main/electron/main.js): `electron/main.js`
- [IPC Bridge](https://github.com/onizuka-sh/streamplex/blob/main/electron/preload.js): `electron/preload.js`

### User Experience

- [React App](https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/App.jsx): `frontend/src/App.jsx`
- [API Client](https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/services/api.js): `frontend/src/services/api.js`
- [Auth Context](https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/context/AuthContext.jsx): `frontend/src/context/AuthContext.jsx`
- [Library Screens](https://github.com/onizuka-sh/streamplex/blob/main/frontend/src/pages/Home.jsx): `frontend/src/pages/Home.jsx`

### API and Access

- [Express App](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/app.js): `backend/src/app.js`
- [Auth Routes](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/auth.routes.js): `backend/src/routes/auth.routes.js`
- [Scan Routes](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/scan.routes.js): `backend/src/routes/scan.routes.js`
- [Video Routes](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/video.routes.js): `backend/src/routes/video.routes.js`
- [Stream Routes](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/stream.routes.js): `backend/src/routes/stream.routes.js`
- [History Routes](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/routes/watchHistory.routes.js): `backend/src/routes/watchHistory.routes.js`
- [Authentication](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/controllers/auth.controller.js): `backend/src/controllers/auth.controller.js`
- [Media Streaming](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/controllers/stream.controller.js): `backend/src/controllers/stream.controller.js`

### Library Processing

- [Media Discovery](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/scanner.service.js): `backend/src/services/scanner.service.js`
- [File Analysis](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/pipeline/analyze.pipeline.js): `backend/src/pipeline/analyze.pipeline.js`
- [Metadata Enrichment](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/pipeline/enrich.pipeline.js): `backend/src/pipeline/enrich.pipeline.js`
- [Filename Parser](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/filenameParser.service.js): `backend/src/services/filenameParser.service.js`
- [TMDB Metadata](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/services/tmdb.service.js): `backend/src/services/tmdb.service.js`

### Persistent State

- [Video Records](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/models/video.model.js): `backend/src/models/video.model.js`
- [Scan Records](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/models/scan.model.js): `backend/src/models/scan.model.js`
- [Genre Records](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/models/genre.model.js): `backend/src/models/genre.model.js`
- [SQLite Database](https://github.com/onizuka-sh/streamplex/blob/main/backend/src/database/db.js): `backend/src/database/db.js`

### Other components

- **Viewer / Admin**
- **Media Folder**
- **TMDB Service**

## Connections

- Viewer / Admin → React App: uses
- Electron Shell → IPC Bridge: exposes IPC
- Electron Shell → Express App: starts backend
- Electron Shell → React App: loads desktop UI
- React App → Auth Context: uses auth
- React App → Library Screens: routes to
- Auth Context → API Client: requests auth
- Library Screens → API Client: requests library
- API Client → Express App: sends API requests
- Express App → Auth Routes: mounts routes
- Express App → Scan Routes: mounts routes
- Express App → Video Routes: mounts routes
- Express App → Stream Routes: mounts routes
- Express App → History Routes: mounts routes
- Auth Routes → Authentication: dispatches
- Stream Routes → Media Streaming: dispatches
- Scan Routes → Media Discovery: dispatches scan
- Media Discovery → Media Folder: discovers files
- Media Discovery → Scan Records: updates scan state
- Media Discovery → File Analysis: starts analysis
- File Analysis → Video Records: loads and updates
- File Analysis → Scan Records: increments progress
- File Analysis → Metadata Enrichment: starts enrichment
- Metadata Enrichment → Video Records: loads and updates
- Metadata Enrichment → Filename Parser: parses names
- Metadata Enrichment → TMDB Metadata: fetches metadata
- Metadata Enrichment → Genre Records: syncs genres
- Metadata Enrichment → Scan Records: increments progress
- TMDB Metadata → TMDB Service: looks up metadata
- Media Streaming → Video Records: loads video record
- Media Streaming → Media Folder: streams file bytes
- Video Records → SQLite Database: reads and writes
- Scan Records → SQLite Database: reads and writes
- Genre Records → SQLite Database: reads and writes
