# seigh-sword/anisow architecture

> Architecture diagram of the GitHub repository seigh-sword/anisow, 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/seigh-sword/anisow
- Repository: https://github.com/seigh-sword/anisow

## Overview

AniSpots is a cross-platform anime discovery, streaming, and offline-library client. Users browse or search titles, open details and episode lists, then watch through an embedded player; they can also save episodes for offline playback and manage watchlists and progress. The web and mobile apps share the core API client and parsers, while maintaining platform-specific navigation, storage, and downloads. The README documents the upstream API and player chain; several app screens and integrations were not sampled, so uncertain internal links are omitted.

Main entry points: [`apps/web/src/pages/Watch.tsx`](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/pages/Watch.tsx) (Watch player), [`apps/mobile/src/screens/WatchScreen.tsx`](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/screens/WatchScreen.tsx) (Mobile watch player), [`apps/web/src/App.tsx`](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/App.tsx) (Web routes), [`apps/web/src/lib/downloads.ts`](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/downloads.ts) (Web download queue)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_web["Web app"]
  node_web_routes["Web routes<br/>[App.tsx]"]
  node_web_discovery["Discovery screens"]
  node_web_detail["Anime details<br/>[Detail.tsx]"]
  node_web_watch["Watch player<br/>[Watch.tsx]"]
  node_web_sheets["Episode and download sheets"]
  node_web_data["Catalog data<br/>[data.ts]"]
  node_web_api["Web API adapter<br/>[api.ts]"]
  node_web_proxy["API proxy<br/>[proxy.mjs]"]
  node_web_library["Web library metadata<br/>[library.ts]"]
  node_web_downloads["Web download queue<br/>[downloads.ts]"]
  node_web_bridge["Web player bridge<br/>[playerBridge.ts]"]
end

subgraph group_mobile["Mobile app"]
  node_mobile_nav["Mobile navigation<br/>[Root.tsx]"]
  node_mobile_screens["Mobile screens"]
  node_mobile_search["Mobile search<br/>[SearchScreen.tsx]"]
  node_mobile_data["Mobile catalog data<br/>[data.ts]"]
  node_mobile_watch["Mobile watch player<br/>[WatchScreen.tsx]"]
  node_mobile_downloads["Mobile downloads<br/>[downloads.ts]"]
  node_mobile_storage[("Mobile library storage<br/>[storage.ts]")]
end

subgraph group_core["Shared core"]
  node_core_client["AniWatch client<br/>[client.ts]"]
  node_core_parse["HTML and fragment parsers"]
  node_core_models["Domain models<br/>[model.ts]"]
end

subgraph group_services["Upstream and storage"]
  node_upstream["AniWatch service"]
  node_player_service["Embedded player hosts"]
  node_web_blob_store[("IndexedDB files")]
  node_mobile_files[("Device file system")]
end

node_user(("Viewer"))

node_user -->|"uses"| node_web_routes
node_web_routes -->|"routes to"| node_web_discovery
node_web_routes -->|"routes to"| node_web_detail
node_web_routes -->|"routes to"| node_web_watch
node_web_discovery -->|"loads catalog"| node_web_data
node_web_data -->|"calls"| node_web_api
node_web_api -.->|"requests API"| node_web_proxy
node_web_proxy -->|"proxies requests"| node_upstream
node_web_detail -.->|"opens sheets"| node_web_sheets
node_web_watch -->|"loads episodes"| node_web_data
node_web_watch -->|"opens sheets"| node_web_sheets
node_web_watch -->|"drives player"| node_web_bridge
node_web_watch -->|"reads progress"| node_web_library
node_web_watch -->|"embeds player"| node_player_service
node_web_sheets -->|"starts downloads"| node_web_downloads
node_web_downloads -->|"updates metadata"| node_web_library
node_web_downloads -->|"stores files"| node_web_blob_store
node_user -->|"uses"| node_mobile_nav
node_mobile_nav -->|"routes to"| node_mobile_screens
node_mobile_screens -->|"includes search"| node_mobile_search
node_mobile_search -->|"searches"| node_mobile_data
node_mobile_data -->|"uses client"| node_core_client
node_mobile_watch -->|"loads catalog"| node_mobile_data
node_mobile_watch -->|"stores progress"| node_mobile_storage
node_mobile_watch -->|"starts downloads"| node_mobile_downloads
node_mobile_downloads -.->|"updates entries"| node_mobile_storage
node_mobile_downloads -.->|"writes files"| node_mobile_files
node_mobile_watch -->|"embeds player"| node_player_service
node_core_client -->|"calls routes"| node_upstream
node_core_client -->|"parses responses"| node_core_parse
node_core_parse -->|"creates models"| node_core_models

click node_web_routes "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/App.tsx"
click node_web_discovery "https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/apps/web/src/pages"
click node_web_detail "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/pages/Detail.tsx"
click node_web_watch "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/pages/Watch.tsx"
click node_web_sheets "https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/apps/web/src/components"
click node_web_data "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/data.ts"
click node_web_api "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/api.ts"
click node_web_proxy "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/server/proxy.mjs"
click node_web_library "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/library.ts"
click node_web_downloads "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/downloads.ts"
click node_web_bridge "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/playerBridge.ts"
click node_mobile_nav "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/navigation/Root.tsx"
click node_mobile_screens "https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/apps/mobile/src/screens"
click node_mobile_search "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/screens/SearchScreen.tsx"
click node_mobile_data "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/lib/data.ts"
click node_mobile_watch "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/screens/WatchScreen.tsx"
click node_mobile_downloads "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/lib/downloads.ts"
click node_mobile_storage "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/lib/storage.ts"
click node_core_client "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/packages/core/src/api/client.ts"
click node_core_parse "https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/packages/core/src/parse"
click node_core_models "https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/packages/core/src/model.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_web_routes,node_web_discovery,node_web_detail,node_web_watch,node_web_sheets,node_web_data,node_web_api,node_web_proxy,node_web_library,node_web_downloads,node_web_bridge,node_user toneBlue
class node_mobile_nav,node_mobile_screens,node_mobile_search,node_mobile_data,node_mobile_watch,node_mobile_downloads,node_mobile_storage toneAmber
class node_core_client,node_core_parse,node_core_models toneMint
class node_upstream,node_player_service,node_web_blob_store,node_mobile_files toneRose
```

## Components

### Web app

- [Web routes](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/App.tsx): `apps/web/src/App.tsx`
- [Discovery screens](https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/apps/web/src/pages): `apps/web/src/pages`
- [Anime details](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/pages/Detail.tsx): `apps/web/src/pages/Detail.tsx`
- [Watch player](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/pages/Watch.tsx): `apps/web/src/pages/Watch.tsx`
- [Episode and download sheets](https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/apps/web/src/components): `apps/web/src/components`
- [Catalog data](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/data.ts): `apps/web/src/lib/data.ts`
- [Web API adapter](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/api.ts): `apps/web/src/lib/api.ts`
- [API proxy](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/server/proxy.mjs): `apps/web/server/proxy.mjs`
- [Web library metadata](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/library.ts): `apps/web/src/lib/library.ts`
- [Web download queue](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/downloads.ts): `apps/web/src/lib/downloads.ts`
- [Web player bridge](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/web/src/lib/playerBridge.ts): `apps/web/src/lib/playerBridge.ts`

### Mobile app

- [Mobile navigation](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/navigation/Root.tsx): `apps/mobile/src/navigation/Root.tsx`
- [Mobile screens](https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/apps/mobile/src/screens): `apps/mobile/src/screens`
- [Mobile search](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/screens/SearchScreen.tsx): `apps/mobile/src/screens/SearchScreen.tsx`
- [Mobile catalog data](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/lib/data.ts): `apps/mobile/src/lib/data.ts`
- [Mobile watch player](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/screens/WatchScreen.tsx): `apps/mobile/src/screens/WatchScreen.tsx`
- [Mobile downloads](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/lib/downloads.ts): `apps/mobile/src/lib/downloads.ts`
- [Mobile library storage](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/apps/mobile/src/lib/storage.ts): `apps/mobile/src/lib/storage.ts`

### Shared core

- [AniWatch client](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/packages/core/src/api/client.ts): `packages/core/src/api/client.ts`
- [HTML and fragment parsers](https://github.com/seigh-sword/anisow/tree/arena/eb1f41c1-anisow/packages/core/src/parse): `packages/core/src/parse`
- [Domain models](https://github.com/seigh-sword/anisow/blob/arena/eb1f41c1-anisow/packages/core/src/model.ts): `packages/core/src/model.ts`

### Upstream and storage

- **AniWatch service**
- **Embedded player hosts**
- **IndexedDB files**
- **Device file system**

### Other components

- **Viewer**

## Connections

- Viewer → Web routes: uses (evidence: `apps/web/src/App.tsx`)
- Web routes → Discovery screens: routes to (evidence: `apps/web/src/App.tsx`)
- Web routes → Anime details: routes to (evidence: `apps/web/src/App.tsx`)
- Web routes → Watch player: routes to (evidence: `apps/web/src/App.tsx`)
- Discovery screens → Catalog data: loads catalog (evidence: `apps/web/src/pages/Search.tsx`)
- Catalog data → Web API adapter: calls (evidence: `apps/web/src/lib/data.ts`)
- Web API adapter → API proxy: requests API
- API proxy → AniWatch service: proxies requests
- Anime details → Episode and download sheets: opens sheets
- Watch player → Catalog data: loads episodes (evidence: `apps/web/src/pages/Watch.tsx`)
- Watch player → Episode and download sheets: opens sheets (evidence: `apps/web/src/pages/Watch.tsx`)
- Watch player → Web player bridge: drives player (evidence: `apps/web/src/pages/Watch.tsx`)
- Watch player → Web library metadata: reads progress (evidence: `apps/web/src/pages/Watch.tsx`)
- Watch player → Embedded player hosts: embeds player
- Episode and download sheets → Web download queue: starts downloads (evidence: `apps/web/src/components/DownloadSheet.tsx`)
- Web download queue → Web library metadata: updates metadata (evidence: `apps/web/src/lib/downloads.ts`)
- Web download queue → IndexedDB files: stores files (evidence: `apps/web/src/lib/downloads.ts`)
- Viewer → Mobile navigation: uses (evidence: `apps/mobile/src/navigation/Root.tsx`)
- Mobile navigation → Mobile screens: routes to (evidence: `apps/mobile/src/navigation/Root.tsx`)
- Mobile screens → Mobile search: includes search (evidence: `apps/mobile/src/navigation/Root.tsx`)
- Mobile search → Mobile catalog data: searches (evidence: `apps/mobile/src/screens/SearchScreen.tsx`)
- Mobile catalog data → AniWatch client: uses client (evidence: `apps/mobile/src/lib/data.ts`)
- Mobile watch player → Mobile catalog data: loads catalog (evidence: `apps/mobile/src/screens/WatchScreen.tsx`)
- Mobile watch player → Mobile library storage: stores progress (evidence: `apps/mobile/src/screens/WatchScreen.tsx`)
- Mobile watch player → Mobile downloads: starts downloads (evidence: `apps/mobile/src/screens/WatchScreen.tsx`)
- Mobile downloads → Mobile library storage: updates entries
- Mobile downloads → Device file system: writes files
- Mobile watch player → Embedded player hosts: embeds player
- AniWatch client → AniWatch service: calls routes
- AniWatch client → HTML and fragment parsers: parses responses (evidence: `packages/core/src/api/client.ts`)
- HTML and fragment parsers → Domain models: creates models (evidence: `packages/core/src/parse/fragments.ts`)
