# rowkavdev/nowplaying architecture

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

- Interactive diagram: https://gitdiagram.com/rowkavdev/nowplaying
- Repository: https://github.com/rowkavdev/nowplaying

## Overview

NowPlaying is a Windows media-presence app: users configure one or more media servers, then the app polls playback and renders a local card and Discord Rich Presence. An optional privacy-filtered upload powers a public hosted README card; Spotify and a paired YouTube extension can supply card state. Setup, settings, diagnostics, artwork, and hosted-device management are supporting product workflows. The README documents the major capabilities; sampled source confirms card rendering, Discord publishing, provider polling, setup sign-in, and hosted-service handling, but does not expose every runtime wiring point.

Main entry points: [`src/presence.js`](https://github.com/rowkavdev/nowplaying/blob/main/src/presence.js) (Presence policy), [`src/card-pipeline.js`](https://github.com/rowkavdev/nowplaying/blob/main/src/card-pipeline.js) (Card pipeline), [`hosted/lib/service.js`](https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/service.js) (Hosted service), [`src/settings-page-handler.js`](https://github.com/rowkavdev/nowplaying/blob/main/src/settings-page-handler.js) (Settings page)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_setup["Setup and settings"]
  node_setup_ui["Setup wizard"]
  node_setup_api["Setup handlers<br/>[setup.js]"]
  node_signin["Provider sign-in"]
  node_settings["Settings page"]
end

subgraph group_presence["Playback and media"]
  node_providers["Provider adapters"]
  node_polling["Multi-server polling<br/>[multi-server.js]"]
  node_presence_state["Presence policy<br/>[presence.js]"]
  node_spotify["Spotify source<br/>[spotify-source.js]"]
  node_youtube["YouTube bridge<br/>[youtube-bridge.js]"]
  node_artwork["Artwork service<br/>[artwork-service.js]"]
end

subgraph group_outputs["Cards and Discord"]
  node_card_pipeline["Card pipeline<br/>[card-pipeline.js]"]
  node_renderer["SVG renderer<br/>[card.js]"]
  node_local_http["Local HTTP server<br/>[http-server.js]"]
  node_discord_controller["Discord controller"]
end

subgraph group_hosted["Hosted cards"]
  node_hosted_uploader["Hosted uploader<br/>[hosted-uploader.js]"]
  node_hosted_service["Hosted service<br/>[service.js]"]
  node_redis[("Redis state<br/>[redis.js]")]
  node_hosted_card["Hosted card handler<br/>[app.js]"]
end

subgraph group_operations["Local operations"]
  node_tray["System tray<br/>[tray-session.js]"]
  node_status["Status and diagnostics"]
  node_logs["Logs page"]
  node_updater["App updater<br/>[auto-updater.js]"]
end

node_user(("User"))
node_media(("Media servers"))
node_discord_app(("Discord desktop app"))
node_github(("GitHub sign-in"))

node_user -->|"configures"| node_setup_ui
node_setup_ui -->|"saves draft"| node_setup_api
node_setup_api -->|"starts sign-in"| node_signin
node_signin -->|"authenticates"| node_media
node_settings -->|"presents controls"| node_user
node_user -->|"changes settings"| node_settings
node_media -->|"serves sessions"| node_providers
node_polling -->|"polls playback"| node_providers
node_polling -->|"updates state"| node_presence_state
node_spotify -.->|"supplies playback"| node_presence_state
node_youtube -.->|"supplies playback"| node_presence_state
node_presence_state -->|"provides presence"| node_card_pipeline
node_card_pipeline -->|"resolves artwork"| node_artwork
node_card_pipeline -->|"renders card"| node_renderer
node_local_http -->|"serves local card"| node_card_pipeline
node_presence_state -->|"provides presence"| node_discord_controller
node_discord_controller -->|"publishes activity"| node_discord_app
node_hosted_uploader -->|"pushes filtered state"| node_hosted_service
node_hosted_service -->|"reads and writes"| node_redis
node_hosted_card -->|"reads card state"| node_hosted_service
node_github -->|"authorizes account"| node_hosted_service
node_tray -->|"opens settings"| node_settings
node_user -->|"checks status"| node_status
node_user -->|"views logs"| node_logs
node_updater -->|"offers updates"| node_user

click node_setup_ui "https://github.com/rowkavdev/nowplaying/blob/main/src/setup-page-handler.js"
click node_setup_api "https://github.com/rowkavdev/nowplaying/blob/main/src/setup.js"
click node_signin "https://github.com/rowkavdev/nowplaying/blob/main/src/setup-signin-handler.js"
click node_settings "https://github.com/rowkavdev/nowplaying/blob/main/src/settings-page-handler.js"
click node_providers "https://github.com/rowkavdev/nowplaying/tree/main/src/providers"
click node_polling "https://github.com/rowkavdev/nowplaying/blob/main/src/multi-server.js"
click node_presence_state "https://github.com/rowkavdev/nowplaying/blob/main/src/presence.js"
click node_spotify "https://github.com/rowkavdev/nowplaying/blob/main/src/spotify-source.js"
click node_youtube "https://github.com/rowkavdev/nowplaying/blob/main/src/youtube-bridge.js"
click node_artwork "https://github.com/rowkavdev/nowplaying/blob/main/src/artwork-service.js"
click node_card_pipeline "https://github.com/rowkavdev/nowplaying/blob/main/src/card-pipeline.js"
click node_renderer "https://github.com/rowkavdev/nowplaying/blob/main/src/card.js"
click node_local_http "https://github.com/rowkavdev/nowplaying/blob/main/src/http-server.js"
click node_discord_controller "https://github.com/rowkavdev/nowplaying/blob/main/src/discord-controller.js"
click node_hosted_uploader "https://github.com/rowkavdev/nowplaying/blob/main/src/hosted-uploader.js"
click node_hosted_service "https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/service.js"
click node_redis "https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/redis.js"
click node_hosted_card "https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/app.js"
click node_tray "https://github.com/rowkavdev/nowplaying/blob/main/src/tray-session.js"
click node_status "https://github.com/rowkavdev/nowplaying/blob/main/src/status-page-handler.js"
click node_logs "https://github.com/rowkavdev/nowplaying/blob/main/src/logs-page-handler.js"
click node_updater "https://github.com/rowkavdev/nowplaying/blob/main/src/auto-updater.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_setup_ui,node_setup_api,node_signin,node_settings,node_user toneBlue
class node_providers,node_polling,node_presence_state,node_spotify,node_youtube,node_artwork toneAmber
class node_card_pipeline,node_renderer,node_local_http,node_discord_controller,node_media toneMint
class node_hosted_uploader,node_hosted_service,node_redis,node_hosted_card toneRose
class node_tray,node_status,node_logs,node_updater,node_discord_app,node_github toneIndigo
```

## Components

### Setup and settings

- [Setup wizard](https://github.com/rowkavdev/nowplaying/blob/main/src/setup-page-handler.js): `src/setup-page-handler.js`
- [Setup handlers](https://github.com/rowkavdev/nowplaying/blob/main/src/setup.js): `src/setup.js`
- [Provider sign-in](https://github.com/rowkavdev/nowplaying/blob/main/src/setup-signin-handler.js): `src/setup-signin-handler.js`
- [Settings page](https://github.com/rowkavdev/nowplaying/blob/main/src/settings-page-handler.js): `src/settings-page-handler.js`

### Playback and media

- [Provider adapters](https://github.com/rowkavdev/nowplaying/tree/main/src/providers): `src/providers`
- [Multi-server polling](https://github.com/rowkavdev/nowplaying/blob/main/src/multi-server.js): `src/multi-server.js`
- [Presence policy](https://github.com/rowkavdev/nowplaying/blob/main/src/presence.js): `src/presence.js`
- [Spotify source](https://github.com/rowkavdev/nowplaying/blob/main/src/spotify-source.js): `src/spotify-source.js`
- [YouTube bridge](https://github.com/rowkavdev/nowplaying/blob/main/src/youtube-bridge.js): `src/youtube-bridge.js`
- [Artwork service](https://github.com/rowkavdev/nowplaying/blob/main/src/artwork-service.js): `src/artwork-service.js`

### Cards and Discord

- [Card pipeline](https://github.com/rowkavdev/nowplaying/blob/main/src/card-pipeline.js): `src/card-pipeline.js`
- [SVG renderer](https://github.com/rowkavdev/nowplaying/blob/main/src/card.js): `src/card.js`
- [Local HTTP server](https://github.com/rowkavdev/nowplaying/blob/main/src/http-server.js): `src/http-server.js`
- [Discord controller](https://github.com/rowkavdev/nowplaying/blob/main/src/discord-controller.js): `src/discord-controller.js`

### Hosted cards

- [Hosted uploader](https://github.com/rowkavdev/nowplaying/blob/main/src/hosted-uploader.js): `src/hosted-uploader.js`
- [Hosted service](https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/service.js): `hosted/lib/service.js`
- [Redis state](https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/redis.js): `hosted/lib/redis.js`
- [Hosted card handler](https://github.com/rowkavdev/nowplaying/blob/main/hosted/lib/app.js): `hosted/lib/app.js`

### Local operations

- [System tray](https://github.com/rowkavdev/nowplaying/blob/main/src/tray-session.js): `src/tray-session.js`
- [Status and diagnostics](https://github.com/rowkavdev/nowplaying/blob/main/src/status-page-handler.js): `src/status-page-handler.js`
- [Logs page](https://github.com/rowkavdev/nowplaying/blob/main/src/logs-page-handler.js): `src/logs-page-handler.js`
- [App updater](https://github.com/rowkavdev/nowplaying/blob/main/src/auto-updater.js): `src/auto-updater.js`

### Other components

- **User**
- **Media servers**
- **Discord desktop app**
- **GitHub sign-in**

## Connections

- User → Setup wizard: configures
- Setup wizard → Setup handlers: saves draft
- Setup handlers → Provider sign-in: starts sign-in
- Provider sign-in → Media servers: authenticates
- Settings page → User: presents controls
- User → Settings page: changes settings
- Media servers → Provider adapters: serves sessions
- Multi-server polling → Provider adapters: polls playback
- Multi-server polling → Presence policy: updates state
- Spotify source → Presence policy: supplies playback
- YouTube bridge → Presence policy: supplies playback
- Presence policy → Card pipeline: provides presence
- Card pipeline → Artwork service: resolves artwork
- Card pipeline → SVG renderer: renders card
- Local HTTP server → Card pipeline: serves local card
- Presence policy → Discord controller: provides presence
- Discord controller → Discord desktop app: publishes activity
- Hosted uploader → Hosted service: pushes filtered state
- Hosted service → Redis state: reads and writes
- Hosted card handler → Hosted service: reads card state
- GitHub sign-in → Hosted service: authorizes account
- System tray → Settings page: opens settings
- User → Status and diagnostics: checks status
- User → Logs page: views logs
- App updater → User: offers updates
