FreshRSS has an excellent engine: solid, self-hosted, great at fetching and storing feeds. Its built-in interface just wasn't for me, and none of the alternatives fit what I wanted — so I built my own. FriRSS sits on top of FreshRSS through its Google Reader API and replaces only the interface.
A note in the interest of honesty: this is a personal project and I'm not a developer. FriRSS was built largely by "vibe coding" — describing what I wanted to an AI assistant and iterating. Use it in that spirit.
- Three-pane reader on desktop; an installable PWA on mobile with swipe navigation, swipe actions and pull-to-refresh.
- Full-text extraction (Readability) when a feed only ships a summary, cached so re-reads are instant.
- Offline reading (installable PWA): articles — text and images — stay readable without a connection. Favorites and read-later are kept offline automatically, plus a one-tap Prepare offline sweep (last 30 days, all feeds) and optional auto-refresh on open.
- Favorites, read-later, mark read/unread, filters (all / unread / favorites), search and infinite scroll.
Almost everything is yours to tweak:
- Themes — full control over every color and font; create, save, export and import your own themes.
- Element colors — recolor the sidebar, accents, panels, links, article text and more, individually.
- Font sizes — independent sizes for article titles, summaries, source names and the reading body.
- Layout — resizable columns, density and spacing options, date separators, toggles for the source label and top bar, and a desktop/mobile layout switch on tablets.
- Labels & sub-labels — a nestable tagging system: create, rename, color, drag-and-drop to organize, group under parents, with per-label article counts.
- Branding — set your own app name and logo.
- 9 languages — FR · EN · DE · ES · IT · PT · NL · PL · UK.
- Multi-user with admin/user roles — each person keeps their own feeds and settings.
- Single sign-on via OIDC (tested with Authentik); existing accounts are linked by email, and passkeys work through your provider.
- Multi-server — connect several FreshRSS instances and switch between them.
- Optional Redis cache (stale-while-revalidate) and a background pre-fetch worker for instant loads.
- FreshRSS tokens encrypted at rest; same-origin proxy (no CORS) with an anti-SSRF guard.
- Ships as a single Docker image (nginx + Node) with SQLite storage.
FriRSS is a frontend for FreshRSS, so you need a running FreshRSS instance with the Google Reader API enabled (Settings → Authentication → Allow API access).
mkdir -p frirss-data
docker run -d --name frirss \
-p 8080:80 \
-v "$PWD/frirss-data:/app/data" \
-e TZ=Europe/Zurich \
ghcr.io/fripix/frirss:latest($PWD is your current directory, so the database is stored in a frirss-data folder right where you run the command — back it up and you back up everything.)
Open http://localhost:8080, create the first account (it becomes admin), then connect your FreshRSS server: its URL, your FreshRSS username, and the API password (set in FreshRSS → Settings → Profile).
Prefer Compose? A ready-to-edit docker-compose.yml is included. The first launch generates the JWT secret and the token-encryption key and stores them in the SQLite database, so backing up the data volume backs up everything.
| Variable | Description | Default |
|---|---|---|
FRIRSS_BASE_URL |
Public base URL — recommended behind a reverse proxy; fixes OIDC redirect URIs | derived |
FRIRSS_DATA_DIR |
SQLite database directory | /app/data |
PROXY_REWRITES |
public→internal URL rewrites for the backend proxy (from=to, comma-separated) |
— |
PROXY_INTERNAL_HOSTS |
Anti-SSRF allowlist: internal hosts the proxy may reach directly | — |
REDIS_URL |
Enables the read cache (stale-while-revalidate); empty disables it | — |
CACHE_ARTICLES_PER_FEED |
Articles kept per feed in the cache | 50 |
CACHE_TTL |
Cache key expiry, in seconds | 86400 |
CACHE_SYNC_INTERVAL |
Background pre-fetch interval in minutes (0 disables; needs REDIS_URL) |
0 |
CORS_ORIGIN |
Allowed CORS origin(s) — only for split front/back deployments | — |
Single sign-on is configured at runtime in Preferences → Admin → SSO (issuer, client ID, client secret).