Unified media management dashboard for your *arr stack, qBittorrent, Jellyfin & Overseerr
2.0K
A unified media management dashboard that connects to your *arr stack (Sonarr, Radarr, Lidarr, Readarr, Prowlarr), qBittorrent, Jellyfin, and Overseerr. Browse, manage, analyze, and automate your media library from a single authenticated interface with multi-user support, analytics, quality management, and scheduled automation.
| Layer | Technology |
|---|---|
| Backend | Python 3.12+, FastAPI, SQLAlchemy (async), APScheduler, httpx |
| Auth | passlib (bcrypt), python-jose (JWT) |
| Frontend | React 19, TypeScript, Vite 7, Tailwind CSS 4 |
| Drag & Drop | @dnd-kit (core, sortable, utilities) |
| Charts | Recharts |
| State | TanStack Query |
| Icons | Lucide React |
| Database | SQLite (aiosqlite) |
| Container | Docker + docker-compose |
# Clone and configure
git clone https://github.com/salmutt/MuLibrary.git
cd MuLibrary
cp .env.example .env # Edit with your service URLs and API keys
# Backend
cd backend
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
alembic upgrade head # Run database migrations
uvicorn app.main:app --reload --port 8000
# Frontend (separate terminal)
cd frontend
npm install
npm run dev
# Backend
cd backend && source .venv/bin/activate
ruff check app/ tests/ # Lint Python code
ruff format app/ tests/ # Format Python code
pytest # Run all tests
pytest --cov=app # Run tests with coverage
# Frontend
cd frontend
npm run lint # ESLint
npx tsc --noEmit # Type check
A Makefile is provided for convenience — run make test, make lint, or make format.
docker compose up -d
The app will be available at http://localhost:8000.
On first visit, you'll be guided through the setup wizard to create an admin account and configure service connections.
Service connections can be configured through the web UI (Settings page) or via environment variables. Copy .env.example to .env and fill in your values:
| Variable | Description | Default |
|---|---|---|
DATABASE_URL | SQLite connection string | sqlite+aiosqlite:///./mulibrary.db |
SECRET_KEY | JWT signing key (change in production) | change-me |
MEDIA_POOL_PATH | Root path for media pool browser | /mnt/media |
SONARR_URL | Sonarr server URL | http://localhost:8989 |
SONARR_API_KEY | Sonarr API key | |
RADARR_URL | Radarr server URL | http://localhost:7878 |
RADARR_API_KEY | Radarr API key | |
LIDARR_URL | Lidarr server URL | http://localhost:8686 |
LIDARR_API_KEY | Lidarr API key | |
READARR_URL | Readarr server URL | http://localhost:8787 |
READARR_API_KEY | Readarr API key | |
PROWLARR_URL | Prowlarr server URL | http://localhost:9696 |
PROWLARR_API_KEY | Prowlarr API key | |
QBITTORRENT_URL | qBittorrent WebUI URL | http://localhost:8080 |
QBITTORRENT_USERNAME | qBittorrent username | admin |
QBITTORRENT_PASSWORD | qBittorrent password | |
JELLYFIN_URL | Jellyfin server URL | http://localhost:8096 |
JELLYFIN_API_KEY | Jellyfin API key | |
OVERSEERR_URL | Overseerr/Jellyseerr URL | http://localhost:5055 |
OVERSEERR_API_KEY | Overseerr API key | |
DEFAULT_ADMIN_USERNAME | Auto-create admin on startup (headless/Docker) | |
DEFAULT_ADMIN_PASSWORD | Password for auto-created admin |
backend/
app/
main.py # FastAPI app with lifespan, CORS, middleware
config.py # Pydantic settings (22 environment variables)
dependencies.py # Auth dependencies (get_current_user, require_admin)
db/ # Async SQLAlchemy setup
models/
database.py # 13 SQLAlchemy models
schemas.py # Pydantic request/response schemas
cleanup_schemas.py # Cleanup-specific schemas
routers/ # 35 API routers
auth.py # Login, setup wizard, user management
sonarr.py, radarr.py, lidarr.py, readarr.py, prowlarr.py
qbittorrent.py # Torrent management
jellyfin.py # Media server integration
requests.py # Overseerr requests
cleanup.py # Cleanup rules and activity
unwatched_cleanup.py # Unwatched media cleanup (Jellyfin-based)
dashboard.py # Dashboard aggregation
dashboard_layout.py # Per-user dashboard widget layout
analytics.py # Library analytics
media_stats.py # Genre/decade/network stats
quality_profiles.py # Quality cutoff analysis
bandwidth.py # Bandwidth scheduling
notification_rules.py # Notification rule engine
notifications.py # Notification channels
snapshots.py # Config backup/restore
sessions.py # Session management
data_export.py # CSV/JSON export
duplicates.py # Duplicate detection + resolution
hardlinks.py # Hardlink health scanning
media_health.py # Media file health checks
orphans.py # Orphan file detection
storage.py # Storage forecast
failed_downloads.py # Failed download tracking
media_pool.py # Filesystem browser
bulk.py # Bulk operations
calendar.py # Upcoming releases
search.py # Cross-service search
logs.py # In-app log viewer
system_stats.py # System info
config.py # Connection CRUD
health.py # Health check
ws.py # WebSocket
services/ # 24 service modules
arr_client.py # Base *arr API client with retry
sonarr.py, radarr.py, lidarr.py, readarr.py, prowlarr.py
qbittorrent.py, jellyfin.py, overseerr.py
auth.py # JWT + bcrypt
cleanup.py # Cleanup rule engine
unwatched_cleanup.py # Unwatched media cleanup service
torrent_matcher.py # Torrent matching + cleanup (hash/title/path)
log_buffer.py # In-memory log ring buffer
media_pool.py # Filesystem operations
analytics.py # Analytics aggregation
notifications.py # Channel dispatch
bulk_operations.py # Cross-service bulk delete
orphan_detection.py # Orphan scanner
duplicate_detection.py # Duplicate finder
hardlink_scanner.py # Hardlink/inode analysis
media_health.py # Video file health checks (ffprobe)
storage_forecast.py # Disk prediction
failed_downloads.py # Failed download service
connection_resolver.py # Dynamic connection lookup
tasks/
scheduler.py # APScheduler (cleanup, backups, notification checks)
cleanup_tasks.py # Cleanup job logic
tests/ # 11 test files, 79 tests (pytest-asyncio + respx)
frontend/
src/
api/
client.ts # Fetch wrapper with auth headers, 401 handling
auth.ts # Auth hooks and localStorage helpers
components/ # 14 shared components + 8 widget components
Layout.tsx # Sidebar navigation with user display + logout
CommandPalette.tsx # Ctrl+K fuzzy search palette
RuleBuilder.tsx # Drag-and-drop cleanup rule builder (@dnd-kit)
WidgetPicker.tsx # Dashboard widget add/remove modal
DataTable.tsx # Sortable, searchable, selectable table
LogViewer.tsx # Per-service in-app log viewer
Card.tsx, ConfirmDialog.tsx, ErrorAlert.tsx, LoadingSpinner.tsx
StatusBadge.tsx, ToastProvider.tsx, ThemeProvider.tsx, InlineEdit.tsx
widgets/ # 8 self-contained dashboard widgets
ServiceHealthWidget, DiskUsageWidget, RecentActivityWidget,
LibraryCountsWidget, DownloadSpeedsWidget, UpcomingReleasesWidget,
ActiveTorrentsWidget, StorageForecastWidget
pages/ # 19 route pages (consolidated with tabs)
Dashboard.tsx # Customizable widget-based dashboard with drag-to-reorder
LoginPage.tsx, SetupPage.tsx, SettingsPage.tsx
SonarrPage.tsx, RadarrPage.tsx, LidarrPage.tsx, ReadarrPage.tsx
ProwlarrPage.tsx, QBittorrentPage.tsx
JellyfinPage.tsx # Overview + Watch History tabs
AnalyticsPage.tsx # Overview + Media Stats + Storage tabs
DownloadsPage.tsx # Active + Failed tabs
CleanupPage.tsx # Rules + Unwatched tabs
LibraryHealthPage.tsx # Orphans + Duplicates + Hardlinks + Media Health tabs
QualityPage.tsx, CalendarPage.tsx
ActivityPage.tsx, MediaPoolPage.tsx
RequestsPage.tsx, SearchPage.tsx, SystemPage.tsx
lib/
utils.ts # formatBytes, formatDate, cn
App.tsx # Auth-gated routing
FastAPI automatically generates interactive API documentation:
All API endpoints are under /api/ and require JWT authentication (except /api/auth/status, /api/auth/setup, /api/auth/login, and /api/health).
| Category | Prefix | Description |
|---|---|---|
| Auth | /api/auth | Login, setup, user management, sessions |
| Sonarr | /api/sonarr | Series, episodes, queue |
| Radarr | /api/radarr | Movies, queue |
| Lidarr | /api/lidarr | Artists, albums |
| Readarr | /api/readarr | Authors, books |
| Prowlarr | /api/prowlarr | Indexers, search, push to arr |
| qBittorrent | /api/qbittorrent | Torrents, categories, bandwidth |
| Jellyfin | /api/jellyfin | Libraries, activity, watch history |
| Dashboard | /api/dashboard | Widget layout per user |
| Cleanup | /api/cleanup | Rules, activity log |
| Analytics | /api/analytics | Charts, media stats |
| Quality | /api/quality | Profiles, cutoff analysis |
| Export | /api/export | CSV/JSON downloads |
| Config | /api/config | Service connections |
| Notifications | /api/notifications, /api/notification-rules | Channels and rules |
| Snapshots | /api/config/snapshots | Backup and restore |
| Hardlinks | /api/hardlinks | Hardlink scan, summary |
| Media Health | /api/media-health | File health scan, results, per-file re-scan |
| System | /api/system, /api/health | Stats and health |
cd backend
source .venv/bin/activate
pytest # Run all 79 tests
pytest -v # Verbose output
pytest --cov=app # With coverage report
pytest tests/test_sonarr_service.py # Run specific test file
Contributions are welcome! Please read CONTRIBUTING.md for development setup, code style guidelines, and the pull request process.
To report security vulnerabilities, please see SECURITY.md. Do not open public issues for security reports.
This project is licensed under the GNU General Public License v3.0. You are free to use, modify, and distribute this software, provided that any derivative works are also distributed under the same license.
Content type
Image
Digest
sha256:f061ab7b3…
Size
79.3 MB
Last updated
7 months ago
docker pull salmutt/mulibrary