Library / SDK
prof18/feed-flow avatar
prof18/feed-flow

FeedFlow reads your feeds locally and syncs to whichever backend you like

FeedFlow is a minimalistic RSS Reader available on Android, iOS, macOS, Windows and Linux. Built with Kotlin Multiplatform, Jetpack Compose and SwiftUI.

1,282 stars69 forksKotlinApache-2.0

At a glance

What is it?
FeedFlow is a minimalistic RSS reader with dedicated apps for Android, iOS, macOS, Windows and Linux, sharing its business logic in Kotlin Multiplatform, drawing the Android and desktop interface with Compose Multiplatform and the iOS interface with SwiftUI, and storing articles in a SQLDelight backed local database. The sync story is the interesting part, since the library can stay local, push through cloud storage, or talk directly to reader services.
Who is it for?
FeedFlow is worth trying if you want one reader across your phone and your desktop that does not hold your subscriptions on somebody else's server, because the local library is the default and the sync backends are choices rather than requirements.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One shared core, three ways to draw the screen

The architecture is stated in the summary at the top of the README, and it is the part that makes a five-platform application feasible. It uses Kotlin Multiplatform for the shared logic, Compose Multiplatform for the Android and desktop interface, and SwiftUI for the iOS-specific interface. The key word in that third clause is specific. The iOS app is not Compose, so there is a real native surface on the one platform where users notice, while the parsing, the database access, the sync logic and the feed handling are shared. The repository layout follows that split, with core/, shared/ and sharedUI/ holding the common code, androidApp/, iosApp/ and desktopApp/ holding the platform applications, and feedSync/, database/ and i18n/ holding the parts that are neither UI nor platform. The project also has benchmarks/, e2e/, build-logic/ and tools/ directories, which tells you the team treats the shared code as a library that has to be measured and tested on its own terms.

Reading modes, and a library that does not need a server

The Why FeedFlow section is the product pitch and it is short. You read articles the way you want, in Reader Mode, in the in-app browser, or in your preferred browser, and Reader Mode also includes extras like opening comments directly and sharing articles without leaving the reading flow. You keep your library local, sync it through cloud storage, or connect directly to reader services. You organise a busy timeline with bookmarks, filters and blocked words. And you move data in and out easily with OPML feed import and export and CSV article import and export. The emphasis on reading modes is the interesting choice, because most readers pick one and make it a setting, whereas this one treats the destination of a link as a per-article decision, and the offline reading feature fits that, since saving article content during sync means the article is there when the link is not. The blocked words feature is the other one that changes daily use, since it hides articles containing given keywords or phrases rather than merely marking them.

The sync backends are the flexibility, and the local library is the default

The sync options are listed in detail in the highlights, and the range is wide. A local library is the base case, and then there are storage backends, Dropbox, Google Drive and iCloud, and then there are reader services that you connect to directly, FreshRSS, Miniflux, Feedbin and BazQux Reader. Those last four are self-hosted or subscription services that speak the same kind of API, and connecting to them means the app becomes a client of a server you already run. The design consequence is that the app has a sync interface with several implementations rather than a hard dependency on one, and the user decides where the data lives. The other pieces in that area are the timeline filters, which cover read status, bookmarks, source and category, and the cache cleanup tools, which matter because a reader that saves article content for offline use accumulates files.

The stack below the interface

The Tech Stack section is five lines and each one is a deliberate choice. Kotlin Multiplatform for the shared business logic, and Compose Multiplatform for the Android and Desktop UI, and SwiftUI for iOS-specific UI. Then SQLDelight-backed local storage, which is the part worth noticing, because SQLDelight means the database schema and the queries are checked at build time rather than discovered at runtime, which is the sort of tool that pays off once the app has a real schema and a real number of migrations. And then RSSParser for feed parsing, which is a separate project by the same author, so the parsing rules and the reading experience are versioned independently. The interface also offers theme modes for system, light, dark and OLED, and widgets for Android and iOS, which are the two features that decide whether a reader survives on a phone, because a widget is how you get back into the app without opening it.

Building it, with dummy credentials and a generated Xcode project

The build from source section is honest about what has to be faked. For Android you copy a dummy Google services file into the debug and release locations:

bash
cp config/dummy-google-services.json androidApp/src/debug/google-services.json
cp config/dummy-google-services.json androidApp/src/release/google-services.json

And for iOS you copy a dummy plist and configuration, install xcodegen, and generate the project:

bash
cp config/dummy-google-service.plist iosApp/GoogleService-Info-dev.plist
cp config/dummy-google-service.plist iosApp/GoogleService-Info.plist
cp config/dummy-config.xcconfig iosApp/Assets/Config.xcconfig
brew install xcodegen
cd iosApp && ./.scripts/generate-project.sh

The reason for the dummy files is obvious, the cloud backends need credentials, and shipping placeholders means a contributor can build without them. The reason for xcodegen is the rule that follows, that the iOS Xcode project is generated from iosApp/project.yml and is not committed, and that you should regenerate the project whenever project.yml, the iOS source structure, the xcconfig files, the entitlements or the SwiftPM dependencies change. The generation script also creates the ignored Config-Debug.xcconfig from its tracked template when it is missing. If you want to test the real iOS sync providers locally, the instruction is to start from the template instead of the dummy and fill in your own keys.

Translations come with store copy

The translating section is a good example of a project that treats localisation as more than a strings file. You can help through Weblate, which is hosted for the project, or open a pull request with two things, a new strings.xml file under i18n/src/commonMain/resources/locale/values-<language-code>/ and matching store copy under assets/storecopy/<language-code>/. The second requirement is the interesting one, because the store listing text is a separate artefact from the interface text, and a translation that only covers the interface leaves the app half-translated in the store. The repository also carries an .ai/ directory, a .claude/ directory, a .codex/ directory, a .junie/ directory, an AGENTS.md, a CLAUDE.md and a .mcp.json, which is a strong signal that the project expects machine agents to work on it, and the contribution guidance is to open an issue first for a larger feature or a platform-specific change, since that is the fastest way to align on scope.

What it is, and what it deliberately is not

The downloads table is the clearest statement of the project's reach, with an Android app on Google Play and on F-Droid, an iPhone and iPad app on the App Store, a macOS app on the Mac App Store and as a Homebrew cask, a Windows app in the Microsoft Store, and a Linux app on Flathub, with GitHub Releases as the fallback for macOS, Windows and Linux. F-Droid and Flathub are the two entries that matter to a particular kind of user, because they are the channels that carry a build without a store account and without a store's telemetry. What the app is not is a discovery service. The feed suggestions are built in and curated across ten categories, so a fresh install does not start from zero, but that is a list rather than a recommender, and the app has no equivalent of a service that learns what you read. The other limit is the philosophy, since the product description is minimal, fast RSS reading without the clutter, which means features that add surface area are exactly what this project is not trying to add.

Editorial conclusion

FeedFlow is worth trying if you want one reader across your phone and your desktop that does not hold your subscriptions on somebody else's server, because the local library is the default and the sync backends are choices rather than requirements. It is the wrong tool if you want feed discovery, because the built-in suggestions are a curated list across ten categories rather than a recommender, and the wrong tool if you need a service of your own, since connecting to FreshRSS, Miniflux, Feedbin or BazQux means you run or subscribe to one of those. Before you build it yourself, copy the dummy configuration files as the instructions say, and note that the iOS Xcode project is generated rather than committed, so a change to project.yml or the SwiftPM dependencies means regenerating before the build.

Frequently asked questions

Which platforms does FeedFlow support and how is it built?

There are dedicated apps for Android, iOS, macOS, Windows and Linux, with Kotlin Multiplatform for the shared logic, Compose Multiplatform for the Android and desktop interface, and SwiftUI for the iOS-specific interface, with SQLDelight-backed local storage and RSSParser for feed parsing.

Where can FeedFlow sync its library to?

You can keep the library local, use storage backends such as Dropbox, Google Drive or iCloud, or connect directly to reader services such as FreshRSS, Miniflux, Feedbin and BazQux Reader. The app also saves article content during sync so articles are available offline.

How do I build FeedFlow from source on iOS?

Copy the dummy configuration files into iosApp, install xcodegen, and run the generation script with cd iosApp && ./.scripts/generate-project.sh. The Xcode project is generated from iosApp/project.yml and is not committed, so regenerate it whenever project.yml, the iOS sources, the xcconfig files, the entitlements or the SwiftPM dependencies change.

How do I translate FeedFlow?

Through the hosted Weblate project, or with a pull request containing a new strings.xml under i18n/src/commonMain/resources/locale/values-<language-code>/ and matching store copy under assets/storecopy/<language-code>/, so the store listing is translated alongside the interface.

Official sources

  1. License: Apache-2.0
  2. prof18/feed-flow on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/prof18-feed-flow.svg)](https://hysenlabs.com/projects/prof18-feed-flow)

Was this useful?