How kyusetzu/karasu works
Purpose and Runtime
Karasu is a Windows/Linux desktop anime and manga tracker centered on AniList. It is a Tauri 2 application: a Rust native backend hosts a React/TypeScript WebView frontend. The backend executable starts through src-tauri/src/main.rs and app wiring lives in src-tauri/src/lib.rs; the frontend mounts from src/app/main.tsx into src/app/App.tsx.
UI, Navigation, and Client State
The React application presents dashboard, list, discovery, local-library, settings, statistics, and year-review screens. Pages consume API wrappers and maintain UI-local state through Zustand; server/list data is managed with TanStack Query. Core paths: src/pages/Dashboard.tsx, src/pages/MediaList.tsx, src/pages/Settings.tsx, src/stores/auth.ts, src/stores/nowPlaying.ts, and src/api/queries.ts. Virtualized list rendering is concentrated in src/components/list/VirtualGrid.tsx.
Frontend–Native Boundary
The UI calls Tauri-exposed Rust commands through frontend API modules rather than directly owning persistence, auth, playback, or OS integrations. The frontend boundary includes src/api/anilist.ts, src/api/library.ts, and src/api/diagnostics.ts; backend command groups are organized in src-tauri/src/commands/auth.rs, src-tauri/src/commands/list.rs, src-tauri/src/commands/playback.rs, and src-tauri/src/commands/system.rs. This boundary is the primary control path for mutations and platform-dependent features.
AniList, Local Lists, and Synchronization
AniList authentication and GraphQL/client behavior are backend-owned, with browser-based login plus token management. List operations support connected AniList data and local-only operation, backed by SQLite; failed remote writes are retained as an offline queue for later synchronization. Key paths: src-tauri/src/anilist/auth.rs, src-tauri/src/anilist/client.rs, src-tauri/src/db.rs, src-tauri/src/commands/list.rs, and src/api/anilist.ts. Tokens use the OS credential store except in portable-mode handling at src-tauri/src/portable.rs.
Playback Detection and Scrobbling Pipeline
Detection sources produce playback candidates, which are parsed and matched to AniList media, then evaluated for progress updates and scrobbled subject to thresholds, confirmation, gap protection, and anime relations. The orchestration is under src-tauri/src/playback/mod.rs; source adapters include Windows/Linux media sessions and Jellyfin in src-tauri/src/playback/detection/media_session/mod.rs and src-tauri/src/playback/detection/jellyfin.rs. Recognition and filename/title parsing are separated in src-tauri/src/playback/recognition/matcher.rs and src-tauri/src/playback/recognition/parser.rs; writes flow through src-tauri/src/playback/scrobbler.rs.
Native Services and Integrations
Rust owns desktop-specific behavior: system tray/window lifecycle, notifications, local filesystem library scanning/matching, Discord Rich Presence, diagnostics, logging, and update checks. Architectural modules are src-tauri/src/library.rs, src-tauri/src/alerts/mod.rs, src-tauri/src/discord.rs, src-tauri/src/diagnostics.rs, and src-tauri/src/commands/update.rs. External services are AniList, optional Jellyfin /Sessions, Discord, and OS media APIs: SMTC on Windows and MPRIS on Linux.
Build and Distribution
Vite builds the frontend while Tauri packages native installers/AppImages. Tauri capabilities and application settings are declared at src-tauri/capabilities/default.json and src-tauri/tauri.conf.json; Rust dependencies/build settings are in src-tauri/Cargo.toml. Release automation produces update artifacts via scripts/release/generate-update-manifest.ps1; CI/release workflows are .github/workflows/ci.yml and .github/workflows/release.yml.
Main entry points: list.rs Native command boundary · client.rs AniList GraphQL client · App.tsx App shell and screens · lib.rs Application wiring
Components 21
React frontend
- React mount
src/app/main.tsx - App shell and screens · Hosts dashboard, lists, discovery, library, settings, statistics, and review screens.
src/app/App.tsx - Client state and queries
src/api/queries.ts - Virtualized media grid
src/components/list/VirtualGrid.tsx - Frontend API wrappers · Keeps persistence, auth, playback, and OS integration behind the native boundary.
src/api/anilist.ts
Tauri native backend
- Tauri bootstrap · Starts the native host and wires application services.
src-tauri/src/main.rs - Application wiring
src-tauri/src/lib.rs - Native command boundary · Receives frontend requests for auth, lists, playback, and system features.
src-tauri/src/commands/list.rs - AniList authentication · Performs browser login and manages AniList tokens.
src-tauri/src/anilist/auth.rs - AniList GraphQL client
src-tauri/src/anilist/client.rs - SQLite lists and offline queue · Stores local-only lists and failed remote writes for later synchronization.
src-tauri/src/db.rs - Local library service · Scans and matches local media files.
src-tauri/src/library.rs - Desktop integrations · Provides tray, windows, notifications, Discord presence, diagnostics, and updates.
src-tauri/src/alerts/mod.rs
Playback pipeline
- Playback orchestration · Coordinates candidate detection, recognition, progress evaluation, and scrobbling.
src-tauri/src/playback/mod.rs - Playback sources · Consumes OS media sessions and optional Jellyfin sessions.
src-tauri/src/playback/detection/media_session/mod.rs - Media recognition · Parses filenames or titles and matches candidates to AniList media.
src-tauri/src/playback/recognition/matcher.rs - Progress scrobbler · Applies thresholds, confirmation, gap protection, and relations before updates.
src-tauri/src/playback/scrobbler.rs
External services
- AniList
- OS media APIs
- Jellyfin
- Discord
Connections 23
- Tauri bootstrap → Application wiring: starts
- Application wiring → React mount: hosts WebView
- React mount → App shell and screens: mounts
- App shell and screens → Client state and queries: uses
- App shell and screens → Virtualized media grid: renders lists with
- Client state and queries → Frontend API wrappers: fetches and mutates through
- Frontend API wrappers → Native command boundary: invokes
- Native command boundary → AniList authentication: auth commands
- Native command boundary → SQLite lists and offline queue: list persistence
- Native command boundary → Local library service: library operations
- Native command boundary → Playback orchestration: playback control
- Application wiring → Desktop integrations: initializes
- AniList authentication → AniList GraphQL client: authorizes
- AniList GraphQL client → AniList: GraphQL requests
- SQLite lists and offline queue → AniList GraphQL client: syncs queued writes
- Local library service → SQLite lists and offline queue: stores matches
- Playback sources → Playback orchestration: playback candidates
- OS media APIs → Playback sources: media sessions
- Jellyfin → Playback sources: sessions
- Playback orchestration → Media recognition: recognizes candidates
- Media recognition → Progress scrobbler: matched media
- Progress scrobbler → AniList GraphQL client: progress updates
- Desktop integrations → Discord: Rich Presence