Hyprfeed is a self-hosted, multi-user RSS reader that turns the sites you follow into an elegant magazine. Paste any website URL — Hyprfeed discovers its feed, and if the site doesn't publish one, it can watch the page itself and turn new articles into stories. One Flask container, SQLite storage, no external services.
Features
- Three view modes — magazine (lead story + mixed grid), cards, and a compact list; switch from the topbar, and each user's preference is remembered
- Feed auto-discovery — paste
example.comand Hyprfeed finds the RSS or Atom feed for you - Page watcher — follow sites with no feed at all: Hyprfeed detects new article links on the page and enriches each story with the article's own title, image, description, and publish date
- Built-in reader — clean, sanitized article view with a reading-time estimate and
j/kkeyboard navigation - Multi-user — private subscriptions, read state, and saved stories per account; email-based sign-in, and the first registered account becomes the admin
- Admin panel — manage users, reset passwords, promote admins, and open or close registration at runtime
- Cloudflare Turnstile — optional bot protection on sign-in and sign-up
- Light & dark themes — follows your system or your choice, instant toggle
- Self-contained — the Inter typeface is embedded, no CDNs, no external services required, and no telemetry; Hyprfeed talks only to the feeds and sites you follow
Install with Docker Compose
No clone needed — the image is on Docker Hub. Save this as docker-compose.yml in an empty directory:
services:
hyprfeed:
image: hyprlab/hyprfeed:latest
container_name: hyprfeed
ports:
# host:container — change the left side if 8098 is taken on your host
- "8098:8000"
environment:
# Session signing key. If unset, one is generated and kept in the data volume.
- SECRET_KEY=${SECRET_KEY:-}
# Cloudflare Turnstile (optional — leave empty to disable the challenge)
- TURNSTILE_SITE_KEY=${TURNSTILE_SITE_KEY:-}
- TURNSTILE_SECRET_KEY=${TURNSTILE_SECRET_KEY:-}
# Set to 0 to close sign-ups (the admin panel can also toggle this at runtime)
- ALLOW_REGISTRATION=${ALLOW_REGISTRATION:-1}
# How often feeds refresh in the background, in minutes
- REFRESH_MINUTES=${REFRESH_MINUTES:-15}
# How many stories each feed keeps; older ones are pruned
- MAX_ENTRIES_PER_FEED=${MAX_ENTRIES_PER_FEED:-300}
volumes:
- hyprfeed-data:/data
restart: unless-stopped
volumes:
hyprfeed-data:
Start it and open http://localhost:8098:
docker compose up -d
Create your account — the first account registered becomes the admin — so register yourself before opening the instance to others (or set ALLOW_REGISTRATION=0 once you're in, or flip the toggle in Settings → Admin).
You can also build from source (git clone + docker compose up -d --build) or run it directly with Python: pip install -r requirements.txt && python run.py.
How the page watcher works
When you add a site and no RSS/Atom feed can be discovered, Hyprfeed offers "Follow without a feed." It then scans the page for article-looking links (navigation, tag, and author pages are filtered out), fetches each new article once — at most 8 per refresh cycle — and reads its Open Graph metadata for the title, lead image, description, and publish date. Those stories then behave like any other feed: unread counts, saving, and the reader all work the same. Watched feeds are labeled with a "watcher" chip, and the reader shows the article's summary with a link out to the site, out of respect for publishers.
Configuration
Most day-to-day settings (registration, refresh cadence, story retention) are managed in the app under Settings → Admin. Environment variables provide secrets and fresh-install defaults:
| Variable | Default | Purpose |
|---|---|---|
SECRET_KEY | auto-generated in /data | Session signing key — set one explicitly if you run replicas |
TURNSTILE_SITE_KEY / TURNSTILE_SECRET_KEY | empty (disabled) | Cloudflare Turnstile bot protection |
ALLOW_REGISTRATION | 1 | Allow new sign-ups; the admin panel overrides at runtime |
REFRESH_MINUTES | 15 | Background refresh interval; 0 pauses |
MAX_ENTRIES_PER_FEED | 300 | Stories kept per feed; older ones are pruned |
DATA_DIR | /data | Where SQLite and the secret key live |
Plain HTTP on one port — any reverse proxy (Caddy, Traefik, nginx) can front it. Put it behind HTTPS if exposed beyond your LAN.
Updating & backups
docker compose pull && docker compose up -d
Schema migrations run automatically on startup. Everything — database and generated secret key — lives in the hyprfeed-data volume, so back that up and you have everything, and your data survives updates.
AI notice
Hyprfeed is built by a human maintainer working with generative AI as a development tool:
- Code — the large majority of the Python, JavaScript, and CSS in the repository was written with Anthropic's Claude (via Claude Code), working from the maintainer's direction. The maintainer decides what gets built, reviews the results, tests every release, and signs off on everything that ships.
- Text — documentation, release notes, and in-app copy are largely AI-drafted and human-edited.
- Artwork — the flat bolt logo and the app's visual design were created with the same AI assistance; the dimensional app icon artwork was provided by the maintainer.
- The app itself contains no AI. Hyprfeed has no AI features, makes no requests to AI services, and never sends your reading data anywhere — it talks only to the feeds and sites you choose to follow. AI was used to build the app, not to run it.
Bug reports and pull requests are welcome from humans and their AI tools alike; everything merged gets the same human review.
Tech stack & license
Flask · SQLAlchemy · Flask-Login · feedparser · SQLite · gunicorn — no frontend framework and no CDN dependencies. Free and open source under the GNU AGPL-3.0. Full docs and releases on GitHub, images on Docker Hub.