# jmperez/spotify-dedup architecture

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

- Interactive diagram: https://gitdiagram.com/jmperez/spotify-dedup
- Repository: https://github.com/jmperez/spotify-dedup

## Overview

Spotify Deduplicator is a web app that authenticates with Spotify, scans a user’s playlists and liked songs for duplicates, and lets the user remove them without replacing playlists. The graph follows the evidenced login-to-scan workflow and includes the documented duplicate-removal capability, plus the product’s localized landing-page content. The scan internals and refresh endpoint were not excerpted, so their detailed calls are omitted; the README supports the broader Spotify-library workflow.

Main entry points: [`components/pages/index.tsx`](https://github.com/jmperez/spotify-dedup/blob/master/components/pages/index.tsx) (Landing page), [`dedup/deduplicator.ts`](https://github.com/jmperez/spotify-dedup/blob/master/dedup/deduplicator.ts) (Duplicate detection), [`dedup/spotifyApi.ts`](https://github.com/jmperez/spotify-dedup/blob/master/dedup/spotifyApi.ts) (Spotify API client), [`pages/fr/index.tsx`](https://github.com/jmperez/spotify-dedup/blob/master/pages/fr/index.tsx) (Language pages)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web experience"]
  node_landing["Landing page<br/>[index.tsx]"]
  node_main["Scan interface<br/>[main.tsx]"]
  node_analytics["Analytics events<br/>[analytics.ts]"]
end

subgraph group_auth["Spotify authentication"]
  node_oauth["OAuth window<br/>[index.ts]"]
  node_authmanager["Authentication manager"]
  node_tokenmanager["Token manager<br/>[TokenManager.ts]"]
  node_exchange["Code exchange<br/>[route.ts]"]
end

subgraph group_dedup["Library deduplication"]
  node_process["Library processing<br/>[process.ts]"]
  node_deduplicator["Duplicate detection<br/>[deduplicator.ts]"]
  node_paging["Paged requests<br/>[promiseForPages.ts]"]
  node_spotifyapi["Spotify API client<br/>[spotifyApi.ts]"]
  node_fetch["API fetch<br/>[customFetch.ts]"]
end

subgraph group_content["Localized content"]
  node_translations["Translations<br/>[i18n.ts]"]
  node_languagepages["Language pages<br/>[index.tsx]"]
  node_features["Product features<br/>[features.tsx]"]
  node_reviews["User reviews<br/>[reviews.tsx]"]
  node_footer["Site footer<br/>[footer.tsx]"]
end

node_user(("User"))
node_spotifyauth["Spotify accounts"]
node_spotify["Spotify Web API"]

node_user -->|"opens"| node_landing
node_landing -->|"starts login"| node_oauth
node_authmanager -->|"exchanges code"| node_tokenmanager
node_tokenmanager -->|"posts code"| node_exchange
node_exchange -->|"requests tokens"| node_spotifyauth
node_landing -->|"renders after login"| node_main
node_main -->|"starts scan"| node_process
node_process -.->|"scans library"| node_deduplicator
node_deduplicator -->|"requests data"| node_spotifyapi
node_deduplicator -->|"uses pagination"| node_paging
node_spotifyapi -->|"uses fetch"| node_fetch
node_spotifyapi -.->|"calls"| node_spotify
node_user -->|"opens locale"| node_languagepages
node_languagepages -->|"loads translations"| node_translations
node_languagepages -->|"renders"| node_landing
node_landing -->|"renders"| node_features
node_landing -->|"renders"| node_reviews
node_footer -->|"logs events"| node_analytics

click node_landing "https://github.com/jmperez/spotify-dedup/blob/master/components/pages/index.tsx"
click node_main "https://github.com/jmperez/spotify-dedup/blob/master/components/main.tsx"
click node_oauth "https://github.com/jmperez/spotify-dedup/blob/master/src/auth/oauth2window/index.ts"
click node_authmanager "https://github.com/jmperez/spotify-dedup/blob/master/src/auth/AuthenticationManager.ts"
click node_tokenmanager "https://github.com/jmperez/spotify-dedup/blob/master/src/auth/token/TokenManager.ts"
click node_exchange "https://github.com/jmperez/spotify-dedup/blob/master/app/api/auth/exchange/route.ts"
click node_process "https://github.com/jmperez/spotify-dedup/blob/master/dedup/process.ts"
click node_deduplicator "https://github.com/jmperez/spotify-dedup/blob/master/dedup/deduplicator.ts"
click node_paging "https://github.com/jmperez/spotify-dedup/blob/master/dedup/promiseForPages.ts"
click node_spotifyapi "https://github.com/jmperez/spotify-dedup/blob/master/dedup/spotifyApi.ts"
click node_fetch "https://github.com/jmperez/spotify-dedup/blob/master/dedup/customFetch.ts"
click node_translations "https://github.com/jmperez/spotify-dedup/blob/master/i18n.ts"
click node_languagepages "https://github.com/jmperez/spotify-dedup/blob/master/pages/fr/index.tsx"
click node_features "https://github.com/jmperez/spotify-dedup/blob/master/components/features.tsx"
click node_reviews "https://github.com/jmperez/spotify-dedup/blob/master/components/reviews.tsx"
click node_footer "https://github.com/jmperez/spotify-dedup/blob/master/components/footer.tsx"
click node_analytics "https://github.com/jmperez/spotify-dedup/blob/master/utils/analytics.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_landing,node_main,node_analytics,node_user toneBlue
class node_oauth,node_authmanager,node_tokenmanager,node_exchange toneAmber
class node_process,node_deduplicator,node_paging,node_spotifyapi,node_fetch,node_spotify toneMint
class node_translations,node_languagepages,node_features,node_reviews,node_footer toneRose
class node_spotifyauth toneIndigo
```

## Components

### Web experience

- [Landing page](https://github.com/jmperez/spotify-dedup/blob/master/components/pages/index.tsx): `components/pages/index.tsx`
- [Scan interface](https://github.com/jmperez/spotify-dedup/blob/master/components/main.tsx): `components/main.tsx`
- [Analytics events](https://github.com/jmperez/spotify-dedup/blob/master/utils/analytics.ts): `utils/analytics.ts`

### Spotify authentication

- [OAuth window](https://github.com/jmperez/spotify-dedup/blob/master/src/auth/oauth2window/index.ts): `src/auth/oauth2window/index.ts`
- [Authentication manager](https://github.com/jmperez/spotify-dedup/blob/master/src/auth/AuthenticationManager.ts): `src/auth/AuthenticationManager.ts`
- [Token manager](https://github.com/jmperez/spotify-dedup/blob/master/src/auth/token/TokenManager.ts): `src/auth/token/TokenManager.ts`
- [Code exchange](https://github.com/jmperez/spotify-dedup/blob/master/app/api/auth/exchange/route.ts): `app/api/auth/exchange/route.ts`

### Library deduplication

- [Library processing](https://github.com/jmperez/spotify-dedup/blob/master/dedup/process.ts): `dedup/process.ts`
- [Duplicate detection](https://github.com/jmperez/spotify-dedup/blob/master/dedup/deduplicator.ts): `dedup/deduplicator.ts`
- [Paged requests](https://github.com/jmperez/spotify-dedup/blob/master/dedup/promiseForPages.ts): `dedup/promiseForPages.ts`
- [Spotify API client](https://github.com/jmperez/spotify-dedup/blob/master/dedup/spotifyApi.ts): `dedup/spotifyApi.ts`
- [API fetch](https://github.com/jmperez/spotify-dedup/blob/master/dedup/customFetch.ts): `dedup/customFetch.ts`

### Localized content

- [Translations](https://github.com/jmperez/spotify-dedup/blob/master/i18n.ts): `i18n.ts`
- [Language pages](https://github.com/jmperez/spotify-dedup/blob/master/pages/fr/index.tsx): `pages/fr/index.tsx`
- [Product features](https://github.com/jmperez/spotify-dedup/blob/master/components/features.tsx): `components/features.tsx`
- [User reviews](https://github.com/jmperez/spotify-dedup/blob/master/components/reviews.tsx): `components/reviews.tsx`
- [Site footer](https://github.com/jmperez/spotify-dedup/blob/master/components/footer.tsx): `components/footer.tsx`

### Other components

- **User**
- **Spotify accounts**
- **Spotify Web API**

## Connections

- User → Landing page: opens (evidence: `components/pages/index.tsx`)
- Landing page → OAuth window: starts login (evidence: `components/pages/index.tsx`)
- Authentication manager → Token manager: exchanges code (evidence: `src/auth/AuthenticationManager.ts`)
- Token manager → Code exchange: posts code (evidence: `src/auth/token/TokenManager.ts`)
- Code exchange → Spotify accounts: requests tokens (evidence: `app/api/auth/exchange/route.ts`)
- Landing page → Scan interface: renders after login (evidence: `components/pages/index.tsx`)
- Scan interface → Library processing: starts scan (evidence: `components/main.tsx`)
- Library processing → Duplicate detection: scans library
- Duplicate detection → Spotify API client: requests data (evidence: `dedup/deduplicator.ts`)
- Duplicate detection → Paged requests: uses pagination (evidence: `dedup/deduplicator.ts`)
- Spotify API client → API fetch: uses fetch (evidence: `dedup/spotifyApi.ts`)
- Spotify API client → Spotify Web API: calls
- User → Language pages: opens locale (evidence: `pages/fr/index.tsx`)
- Language pages → Translations: loads translations (evidence: `pages/fr/index.tsx`)
- Language pages → Landing page: renders (evidence: `pages/fr/index.tsx`)
- Landing page → Product features: renders (evidence: `components/pages/index.tsx`)
- Landing page → User reviews: renders (evidence: `components/pages/index.tsx`)
- Site footer → Analytics events: logs events (evidence: `components/footer.tsx`)
