Skip to content

About

Super efficient RSS Reader in Tauri.

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

RSS Reader

CI Latest release

A lightweight, local-first RSS/Atom reader for Windows, macOS, Linux, Android and the web. No account, no backend, no telemetry: subscriptions, read/starred state, rules, preferences and cached articles stay on your device. Built with React and Tauri, inspired by Fluent Reader.

Download

Windows desktop (64-bit): download the latest installer from Releases.

  • Requires Windows 10/11 with WebView2.
  • The installer is unsigned for now: SmartScreen → More info → Run anyway.
  • Installing over a previous version keeps feeds, read state, stars, rules and cache.

macOS (Apple Silicon): download the .dmg from Releases. It is unsigned, so right-click the app → Open the first time (or allow it in System Settings → Privacy & Security).

Linux: download the .AppImage, make it executable (chmod +x RSS.Reader_*.AppImage) and run it. It needs the distribution's WebKitGTK 4.1/GTK libraries (standard on Ubuntu 22.04+).

Android: download the .apk from Releases (Android 8+, arm64), allow installs from your browser/file manager and open it. The current APK is debug-signed for testing; a Play Store / stable signing key is not configured yet.

Web / PWA: build the app and install it from Chrome or Edge:

npm install
npm run build
npm run preview      # http://localhost:4173 → Install app

The installed PWA opens offline but needs the local preview/proxy server for feed refreshes. The desktop app fetches natively and needs no Node process at runtime.

Verify downloads

Each GitHub release includes SHA256SUMS.txt. After downloading an asset:

sha256sum -c SHA256SUMS.txt

On Windows PowerShell, use Get-FileHash and compare the SHA-256 value with the matching line. Builds are currently unsigned on Windows/macOS and the Android APK uses the development key; see docs/SIGNING.md for what is needed to add Authenticode, Apple notarization or Play Store signing.

Updates

About → Check for updates queries the latest GitHub release and offers the installer or APK for the current platform. Running it replaces the installed version; there is no need to uninstall first. Silent in-app installation is not enabled because it needs a Tauri updater signing key stored as a CI secret; the current build uses the simple download-and-install path.

Highlights

  • Four layouts — cards, list, magazine and compact. List keeps the article pane beside the rows; magazine and card open the reader as a blurred popup.
  • Filters and search — all/unread/starred, plus case-sensitive, full-text and regular-expression options attached to the search field.
  • Stars and rules — keep articles, or automatically mark/star new arrivals with contains or regex rules scoped to a source or group.
  • Reader tools — copy link, load the original full article text (cached for the session) and play podcast audio at 0.75–2× speed.
  • Local backups — OPML plus a compressed ZIP backup (JSON inside) with subscriptions, folders, read state, stars, rules, preferences and every cached article. Plain JSON backups remain importable. Desktop keeps seven daily snapshots, gzip-compressed (.json.gz) and still readable from older plain-JSON files.
  • Media — YouTube, Vimeo, Spotify, SoundCloud, Deezer and Apple Podcasts play inline without API keys.
  • Desktop extras — tray icon, close-to-tray, background refresh, native notifications and start-at-login.
  • English and Spanish — the whole interface follows the system language, or pick one in Settings → Preferences → Language. A missing translation falls back to English.

Features

Sources and groups. Subscribe by feed URL or website; the feed link is discovered automatically. Organize with A–Z folders/groups, resize the sidebar, collapse all, and bulk-select sources or groups in Settings for move/merge/delete. Sources includes an import action when the device has no subscriptions yet. Feed failures back off from 5 minutes to 6 hours; manual refresh retries immediately. ETag/Last-Modified validators keep unchanged feeds on a 304.

Telegram and Reddit. Subscribed t.me/<channel> sources are read from the public channel preview page and converted into articles; up to three older preview pages are fetched so a quiet channel still has a useful history. Reddit retired its public RSS feeds in November 2026. Subscribed reddit.com/r/<sub> sources are read through the public Arctic Shift archive and mapped into normal articles; the legacy RSS URL is still used as a fallback while it exists. Reddit posts also open in an inline card in the reader.

Reading. Card, list, magazine and compact layouts. Automatic feed refresh is off by default; choose 15 min, 30 min, 1 hour or 3 hours in Preferences, or refresh manually whenever you want. Wide windows use two panes for list/compact; magazine and card use an overlay with previous/next arrows. Article HTML is sanitized, relative URLs are resolved, and external links open safely in a new tab. Mark as read works per article, all visible, or older than 1/3/7 days.

Language. The interface ships in English and Spanish with a system default. Every label, dialog, toast and error message goes through the same tiny catalog, so new strings fall back to English instead of breaking the UI.

Settings. Six sections: Preferences, Manage, Rules, Services, Data and About. Theme, density, reading typeface (sans, serif, mono) and font size live in Preferences. Manage holds the Sources and Groups tabs. Data owns import/export, backups and the local cache. Services includes a sync-provider selector (Fever, Feedbin, Inoreader, Miniflux, Nextcloud News, NewsBlur) and the optional YouTube API key. Server and username are stored locally; the password/token is session-only. Two-way sync remains future work — use OPML or a full backup today. The feed context menu can edit a source's name, group and feed link in one dialog; changing the link resets that source's cached articles and read state.

Privacy. No sync service, account or telemetry. Everything is stored in localStorage and IndexedDB on this device. The web/PWA build only contacts feeds and the configured proxy; the desktop build fetches feeds from Rust with HTTPS-first, SSRF/private-host blocking and a 5 MB response cap.

Keyboard shortcuts

Key Action
j / k or ↓ / ↑ Move through articles
← / → Previous / next article
Enter / o Open the selected article
m Toggle read/unread
r Refresh all feeds
/ Focus search
a Add feed
Esc Close article, drawer or dialog
Alt+← / Alt+→ Back / forward through views

Development

Requirements: Node 20+; Rust and WebView2 for the desktop build.

npm install
npm start              # build if stale, serve :4173 and open the app
npm run dev            # http://localhost:5173 with hot reload

npm run build          # production bundle in dist/
npm run preview        # serve dist/ with the local feed proxy

npm run test:unit      # Vitest
npm run test:e2e       # Playwright smoke suite (needs npm run dev running)
npm run test:pwa       # installability + offline check (needs npm run preview)
npm run check          # typecheck + unit tests + Rust fmt/clippy/tests

npm run desktop:dev    # Tauri dev window
npm run desktop:build  # native bundle → src-tauri/target/release/bundle/

# Per-platform bundles:
npm run desktop:build -- --bundles nsis      # Windows installer
npm run desktop:build -- --bundles appimage  # Linux AppImage
npm run desktop:build -- --bundles dmg       # macOS disk image
npm run android:build                        # Android APK (needs Android SDK/NDK)

CI runs the web suite on Ubuntu and the Rust checks plus Windows installer build on Windows. See .github/workflows/ci.yml. The release process is documented in docs/RELEASING.md.

How it works

  • Storage: localStorage for preferences, subscriptions, read/starred IDs and rules; IndexedDB for cached articles, with a quota guard that evicts cache before state.
  • Fetching: the web build tries a direct fetch, then the local /proxy (or VITE_PROXY_URL), then public proxies as a last resort. The desktop build makes one native Rust request with validators and retry backoff.
  • Security: feed HTML crosses a DOMPurify allow-list boundary with relative-URL resolution and forced safe external links. The proxy and desktop fetcher enforce HTTPS-first, block private/loopback hosts and cap responses.
  • Offline shell: a production service worker precaches the app shell; feed responses and /proxy are never cached.

Key folders:

src/components/    UI, settings managers and dialogs
src/lib/           fetching, parsing, sanitization, backups, rules, storage
src/store/         framework-agnostic app store and selectors
src-tauri/         Tauri shell, native fetch, tray and snapshots
server/            shared local feed proxy

Known limitations

  • State is per device. Use the full ZIP backup to move it.
  • The Spanish catalog is hand-written; native-speaker review is welcome.
  • Feed refresh is manual by default; Settings → Preferences can enable 15 min, 30 min, 1 hour or 3 hours while the window is visible.
  • Below 1100 px the article view becomes single-pane and the sidebar becomes a compressed left-side drawer.
  • The Windows installer and macOS disk image are unsigned; macOS needs a first-run right-click → Open. The Android APK is debug-signed.
  • Android file import/export uses the WebView download flow; the desktop save dialog and daily snapshots remain desktop-only.
  • The Android APK is arm64 debug-signed with a committed keystore so updates install over earlier builds; Play Store signing is not configured.
  • Services has a sync-provider selector, but two-way sync is not implemented yet; the server and username are stored locally (the password/token is session-only) and excluded from backups.
  • “Load full content” depends on the page structure and on the proxy being reachable.

License

MIT. See LICENSE.

About

Super efficient RSS Reader in Tauri.

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages