ReadFlux is a static, local-first Miniflux client. It uses Miniflux as the source for feeds and articles, records real reading behavior in the browser, and turns unread or newly updated articles into a personalized Today view. The complete synced history remains available in All.
- NetNewsWire-inspired three-column reading interface
- Today contains unread articles and previously read articles with new updates, ordered by time period, unread status, and local recommendations
- All contains the complete synced history in reverse publication order
- Updated tracks previously read articles whose content changed since they were last opened
- Read later keeps links you save from articles, outside Today
- An Unread only list filter replaces a separate unread destination
- Saved articles, source-scoped subscription groups, feed icons, and dynamic counts
- IndexedDB article cache, cache-first startup, and scheduled incremental sync
- Initial sync prioritizes unread articles, then all saved articles, then read articles, with paginated progress
- Full article history is cached locally through resumable paginated sync
- Stable list snapshots, so articles do not disappear while being read
- Read and saved state updates immediately; recommendation scores and ordering are recalculated when the list is refreshed or its context changes
- GitHub Pages-safe article permalinks using
#/article/:entryId - Day and night themes
- English, Simplified Chinese, and French interfaces selectable in Settings
- Per-server and per-feed image loading choices for original images with or without an Origin referrer, plus Miniflux proxy links when the server exposes them
- Continuous keyboard reading, adjustable column widths, and mobile navigation
- Inspection, editing, and deletion of reading events, feed preferences, and keyword preferences
- Optional AI summaries and translations through your own OpenAI-compatible or Anthropic provider, saved locally per article
ReadFlux has no application server:
- The Miniflux URL, API key, timezone, and preferences are stored only in
this browser's
localStorage. - Article content, article state, feed metadata, sync state, reading events, ranking exposures, and pending Miniflux writes are stored in IndexedDB.
- The browser sends requests directly to your Miniflux server.
- The repository and build output contain no credentials.
- Article text leaves the browser only when you click Summarize or Translate, and only to the AI provider you configured. See AI summaries and translations.
On a shared computer, leave Remember on this device unchecked. Create a dedicated Miniflux API key for ReadFlux so it can be revoked independently.
- Node.js 24 or later
- Miniflux 2.3.2 or later, accessible over HTTPS
- Miniflux, or its reverse proxy, configured to allow requests from the ReadFlux origin
- CORS rules that allow
X-Auth-Token,Content-Type, and theGET,PUT,POST, andOPTIONSmethods used by ReadFlux
Miniflux recommends a separate API key for each application. ReadFlux sends the
key in the X-Auth-Token header.
npm install
npm run devOpen the local address shown in the terminal, then enter your Miniflux URL and dedicated API key.
Run these checks before submitting changes:
npm run lint
npm test
npm run buildReadFlux uses i18next and separate JSON locale files. To improve an existing
translation, edit the corresponding file under src/locales/; automated tests
verify that every locale has the complete key set and preserves interpolation
placeholders.
See CONTRIBUTING.md for adding a language, working with placeholders and plurals, and submitting changes through GitHub's web editor. No React changes are needed for ordinary translation fixes.
The repository includes .github/workflows/deploy-pages.yml. After a push to
main, the workflow:
- Installs dependencies.
- Runs lint, tests, and the production build.
- Deploys
dist/to GitHub Pages.
For the first deployment, open Settings → Pages → Build and deployment in the GitHub repository and set Source to GitHub Actions. The default URL is:
https://allanzayne.github.io/readflux/
If a fork uses a different repository name, update the GitHub Pages base path
in vite.config.ts.
Clicking or tapping a link in an article opens a menu: Read later, Open link, and Copy link, plus Open in ReadFlux when the link is already a synced article. Ctrl/⌘-, Shift-, and middle-clicks open the link directly.
Read later adds the link to Miniflux as an unread article, and Miniflux fetches the page's content. Saved links appear under Read later, newest first, and stay out of Today. They sync to every device through Miniflux.
Read later works as a queue and shows only unread links by default. Opening a link marks it read, and it leaves the queue at the next list refresh. To keep an article, save it with the star; it then also appears in Saved. Miniflux deletes read, unsaved articles after its cleanup period (60 days by default). Turn off Unread only to see links you have already read.
The first saved link creates a disabled feed named ReadFlux · Read later
in a category of the same name. The feed points at the empty
readflux-read-later.xml file published with ReadFlux, and Miniflux fetches it
once when the feed is created. ReadFlux hides this feed and category from
Subscriptions. Open ReadFlux from its published address for the first
save; a local development server is not reachable from Miniflux.
The link goes only to your Miniflux server. Miniflux then requests the page itself, as it does for feed articles.
ReadFlux records the article, feed, title, keywords, open time, active foreground time, scroll depth, and entry path. Saved state remains managed by Miniflux. There are no like or dislike buttons: articles you skip, scroll past, or leave quickly already count against their feed.
Foreground time counts only while the page is visible and focused and no dialog is open, and only while the mouse is over the article or its card in the article list, or one of the article's videos is fullscreen.
Today ranks articles within each publication-time and read-status group using the feeds you read, the topics you follow, publication time, and saved state, with more weight on recent behavior. Topics you follow count more when you read articles about them. ReadFlux never learns topics you did not follow.
The end of each article explains why it is where it is, with the full score breakdown. Scores are not shown in the article list. A link saved for later ends instead with when and where you saved it, and buttons to save it or put it back in Read later.
The Recommendation data tab in Settings shows the derived feed and topic weights and the 30 most recent raw events by default. Local records can be edited or deleted, and search still covers the complete event history.
Export JSON in the same tab downloads an unencrypted local file. It contains all local and mirrored reading events, ranking exposures, the derived profile, diagnostics, feed and category names, and metadata for referenced, unread, updated, and saved articles: title, URL, publication time, state, the title-plus-excerpt text used for scoring, and the current score breakdown. It never includes full article content or Miniflux and WebDAV credentials. When WebDAV is configured, the tab shows its sync status and disables export while a sync is running.
Each Today list also records its top 100 articles and which of them you saw.
Candidate topics appear as hashtags after the article's byline. Topics you already follow are highlighted; click a hashtag to follow it, or click a highlighted one to stop following it everywhere.
ReadFlux can synchronize recommendation events between ReadFlux installations
through a user-provided WebDAV directory. Each installation owns a client
folder under v1/clients/ and stores authoritative monthly event files under
events/YYYY-MM.json. Clients read other folders as read-only mirrors and
combine those events locally; there is no shared manifest or profile file.
Configure the dedicated WebDAV directory, Basic Auth credentials, client name,
and pull interval in Settings → Sync. Existing local events are uploaded on
first connection. Later local changes upload after a short delay, while remote
pulls run at startup, on foreground resume, at the selected interval, or from
the Sync now button. WebDAV sync requires browser CORS support for MKCOL,
PROPFIND, GET, and PUT. Credentials and remote JSON are not encrypted by
ReadFlux.
Configure an AI provider in Settings → AI to enable two controls under the article byline:
- An Original | switch. Choosing the language translates the article body in place, paragraph by paragraph as the reply streams in, with untranslated paragraphs dimmed and a translated-paragraph count. Choose Original to return to the original text or to cancel a running translation. Links, emphasis, images, and code are preserved; only text is sent for translation.
- Summarize shows a short bulleted summary above the article.
Both use the target language from Settings → AI → Translation, which defaults to the interface language. Results are saved in IndexedDB per article, task, and language, so clicking again shows the saved result. Reopening an article shows its saved summary or translation again unless you hid it last time. A result is generated again when the article content changes. Ctrl+click (⌘+click on macOS), or Ctrl/⌘+Enter on the focused button, regenerates and replaces it.
Two provider types are supported:
- OpenAI-compatible: any
/chat/completionsendpoint, such as OpenAI, OpenRouter, DeepSeek, Ollama, or LM Studio. The API key is optional for local servers. Reasoning that some models inline as<think>or<reasoning>is hidden. - Anthropic: the Messages API, called with Anthropic's direct browser access header.
Enter the fields in order: provider, base URL, API key, then model. Load
models fills model suggestions from the provider's models endpoint when it
has one; otherwise type the model name. Reasoning effort defaults to the
provider's own default. Low, Medium, or High is sent as reasoning_effort to
OpenAI-compatible endpoints, which only reasoning models accept, and as
output_config.effort to Claude 5 models. Test connection and Save
report their result directly in the AI tab.
The browser calls the provider directly, so the provider must accept
cross-origin browser requests, including the CORS preflight for the
Authorization or x-api-key header. Local servers must allow the ReadFlux
origin (for Ollama, set OLLAMA_ORIGINS). Some gateways answer requests from
curl but reject browser preflights; the Amazon Bedrock OpenAI-compatible
endpoint is one example, and ReadFlux reports a network/CORS error for it.
When you click Summarize or Translate, the article title and text are sent to
the configured provider. Nothing is sent automatically. Reading events,
recommendation data, and Miniflux credentials are never sent. The provider
settings, including the API key, are stored unencrypted in localStorage.
Disconnecting removes them and all saved results from the browser. AI settings
and results are not included in the recommendation export.
- React
- TypeScript
- Vite
- i18next and react-i18next
- Miniflux REST API
- WebDAV for optional recommendation-event sync
- IndexedDB and Web Crypto API