Entire site was built using Claude code with Opus and Gemini. Using it daily, I haven’t found any issues in functionality so far, but I’ll update the README if I come across any bugs that I’m unable to fix. The UI is mobile-first, as I needed an Iphone app to control radarr, sonarr and qbittorrent with push notifications. I have only added features which I wanted to use myself to use from mobile, not all the options and features present in arr stack and qbittorrent is added.
Helprr is a self-hosted web dashboard (PWA) that connects to Sonarr, Radarr, and qBittorrent. It polls those services on an interval and can send Web Push notifications for common events (downloads starting/completing/failing, health warnings, upcoming releases, etc.).
- Password-protected UI (single shared app password)
- Connect/configure Sonarr, Radarr, qBittorrent from Settings
- Dashboard + Activity feed + Calendar views
- Notifications inbox + per-device notification preferences
- PWA service worker (Serwist in production; lightweight push-only worker in development)
- Next.js (App Router) on port 3050
- Prisma + PostgreSQL
- Web Push (
web-push) with VAPID keys
- Node.js 20+
- PostgreSQL 16+ (or Docker)
- Redis 7+ (or Docker)
Copy .env.example to .env.local (for local dev), or set these in your deployment environment:
| Variable | Required | Purpose |
|---|---|---|
DATABASE_URL |
yes | PostgreSQL connection string used by Prisma |
REDIS_URL |
yes | Redis connection string used for login rate limiting |
APP_PASSWORD |
yes | Password used on the /login screen |
JWT_SECRET |
recommended | Signs the auth cookie (set this in production) |
NEXT_PUBLIC_VAPID_PUBLIC_KEY |
optional | Public VAPID key (enables push notifications; must be available at build time for Docker builds) |
VAPID_PRIVATE_KEY |
optional | Private VAPID key (server-side) |
VAPID_SUBJECT |
optional | VAPID subject, e.g. mailto:you@example.com |
TZ |
optional | Timezone for displaying dates/times (defaults to UTC) |
If VAPID vars are not set, Helprr will still run, but push notifications are disabled.
- Install dependencies
npm ci- Start PostgreSQL and Redis (example using docker-compose)
docker compose up -d helprr-db helprr-redis- Configure
.env.local
Example (adjust credentials/host to match your Postgres setup):
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/helprr
REDIS_URL=redis://localhost:6379
APP_PASSWORD=change-me
JWT_SECRET=change-me-too
TZ=Asia/Kolkata
# Optional: enable push notifications
VAPID_SUBJECT=mailto:you@example.com
NEXT_PUBLIC_VAPID_PUBLIC_KEY=...
VAPID_PRIVATE_KEY=...- Initialize the database schema
npm run db:generate
npm run db:push- Run the dev server
npm run devThe repository includes a docker-compose.yml with a Postgres container and the Helprr app.
- Set environment variables (recommended via a local
.envfile that is not committed)
POSTGRES_PASSWORD(optional override; defaults topostgres)DATABASE_URL(optional override; defaults to the internal compose URL)REDIS_URL(optional override; defaults toredis://helprr-redis:6379)APP_PASSWORDTZ(optional override; defaults toUTC)JWT_SECRETNEXT_PUBLIC_VAPID_PUBLIC_KEY(build-time)VAPID_PRIVATE_KEYVAPID_SUBJECT
- Build and run
docker compose up --buildNotes:
- The image build expects
NEXT_PUBLIC_VAPID_PUBLIC_KEYto be available as a build arg. - The container entrypoint runs
npx prisma db push --skip-generatebefore starting Next.js.
You can generate a VAPID keypair with:
npx web-push generate-vapid-keysUse the public key as NEXT_PUBLIC_VAPID_PUBLIC_KEY and the private key as VAPID_PRIVATE_KEY.
In the app, go to Settings and set:
- Sonarr: base URL + API key
- Radarr: base URL + API key
- qBittorrent: base URL + password (stored as the connection
apiKey) + optional username (defaults toadmin)
Helprr’s polling service will skip any service that is not configured.
npm run dev
npm run build
npm run start
npm run db:generate
npm run db:push
npm run db:migrate
npm run lint- Set strong values for
APP_PASSWORDandJWT_SECRETin production.











