5 min read

FreshRSS: Your Own Self-Hosted RSS Reader (GitHub, Scanned)

A self-hosted RSS reader for your own server, with multi-user accounts and an API for mobile apps.

FreshRSS logo
✅
Scan: safe. Nothing to warn about. The two pattern hits are the Docker image setting up its own feed refresh cron job and a long entity table in the bundled feed parser. Scanned Oct 26, 2026; the full report is below.

FreshRSS is a feed reader you run on your own server instead of signing up for one. You add RSS and Atom feeds, it fetches them on a schedule, and you read everything in a web interface that works on desktop and mobile browsers. It supports several user accounts, an anonymous read-only mode, custom tags, saved searches you can reshare as HTML, RSS or OPML, and extensions for anything the core does not do.

Two features set it apart from a basic reader. It can scrape sites that publish no feed at all, using XPath rules or JSON documents, and it accepts WebSub push notifications, so posts from compatible sources such as WordPress arrive instantly rather than at the next refresh. It also exposes a Google Reader compatible API, which lets you keep using phone and desktop apps like FeedFlow, NewsFlash or Reeder Classic with your own server behind them.

It is a mature project: started in 2012, about 16,400 stars and 458 contributors, at release 1.30.4 when scanned and still pushed to daily. It is PHP and runs on modest hardware (the README mentions a Raspberry Pi 1 handling 150 feeds), with SQLite built in or PostgreSQL, MariaDB or MySQL if you prefer. The catch is the one every self-hosted app has: you need somewhere to run it, and keeping it updated and safely exposed to the internet is your job.

  • Repository: github.com/FreshRSS/FreshRSS
  • Licence: AGPL-3.0 (GNU Affero General Public License v3.0)
  • Language: PHP. Stars: 16.4K. Forks: 1,326. Last push: Oct 26, 2026.
  • Scan: safe, Oct 26, 2026, commit 931fb41

Who it is for

People who left Google Reader or Feedly and want their subscriptions on hardware they control, households or small teams sharing one reader, and anyone with a home server, NAS or cheap VPS already running Docker.

Getting started

1. Run it with Docker, refreshing feeds at minutes 1 and 31 of each hour

docker run -d --restart unless-stopped --log-opt max-size=10m -p 8080:80 -e TZ=Europe/Paris -e CRON_MIN=1,31 -v freshrss_data:/var/www/FreshRSS/data -v freshrss_extensions:/var/www/FreshRSS/extensions --name freshrss freshrss/freshrss:edge

2. Or install it by hand on a PHP 8.1+ web server

git clone https://github.com/FreshRSS/FreshRSS.git

With Docker, open http://localhost:8080 and follow the setup screens. For a manual install, expose only the p/ folder to the web and give the web server write access to data/, which holds all your personal data. The edge branch and image are the rolling release with the newest fixes; use latest for fewer updates. One-click options also exist on YunoHost, Cloudron and PikaPods.

Safety scan

We cloned FreshRSS/FreshRSS at commit 931fb41 on Oct 26, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.

  • No secrets, no committed binaries and no install hooks across about 187,000 lines, most of it PHP. The four bare-IP URLs are in tests/app/Utils/httpUtilTest.php and use 198.51.100.7, a documentation-only TEST-NET address.
  • The persistence hit is Docker/entrypoint.sh installing a crontab inside the container when you set CRON_MIN. That is the feed refresh schedule the Docker instructions ask for, and it saves the container's environment to Docker/env.txt so the cron job sees the same settings. It touches nothing outside the container.
  • The 6,618-character line in lib/simplepie/simplepie/src/Parser.php is the bundled SimplePie feed parser declaring every HTML entity name in one string, so feeds that use them parse as valid XML. Long, not hidden.
  • The 5 known advisories (2 high, 1 moderate, 2 low) are in package-lock.json, which only holds lint and formatting tools (ESLint, Stylelint, markdownlint, SVGO). markdown-it, smol-toml and KaTeX come in through markdownlint and never ship in the app.
  • 6 workflows, none using pull_request_target, and all 11 third-party actions are pinned to commits, which is better than most projects on this list. Security policy, licence, contributing guide and Dependabot present; no CodeQL. OpenSSF Scorecard 6.9.

What the scanner counted

CheckResult
SecretsNone found.
Suspicious code2 pattern hits found and read; every one is listed under the raw findings.
Install-time codeNone: nothing runs at install beyond the package manager itself.
Committed binariesNone.
CI workflows6 workflows. None use pull_request_target. 0 of 11 third-party actions pinned to a tag rather than a commit.
Network hosts40 distinct hosts referenced from source; most often freshrss.github.io, www.php.net, github.com, www.gnu.org. 4 URLs to a bare IP address, listed under the raw findings.
Known vulnerabilities5 advisories across 296 pinned packages: 0 critical, 2 high, 1 moderate, 2 low. package-lock.json: 299 packages, 5 advisories.
Project hygieneHas security policy, automated dependency updates, licence file, contributing guide. Missing CodeQL.
OpenSSF Scorecard6.9 out of 10, as of Oct 26, 2026.

The raw findings

Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.

Pattern hits (2)
WhereRuleMatch
Docker/entrypoint.sh:70persistence-r "s#^[^ ]+ #$CRON_MIN #" | crontab -
lib/simplepie/simplepie/src/Parser.php:674very-long-line6618 chars
URLs to bare IP addresses (4)
WhereRuleMatch
tests/app/Utils/httpUtilTest.php:33ip-literal-url'public server' => ['https://198.51.100.7/feed1', 'https://198.51.100.7/feed2?a=1&b=2', true],
tests/app/Utils/httpUtilTest.php:33ip-literal-url'public server' => ['https://198.51.100.7/feed1', 'https://198.51.100.7/feed2?a=1&b=2', true],
tests/app/Utils/httpUtilTest.php:34ip-literal-url'public server, other port' => ['https://198.51.100.7/feed', 'https://198.51.100.7:8443/feed', false],
tests/app/Utils/httpUtilTest.php:34ip-literal-url'public server, other port' => ['https://198.51.100.7/feed', 'https://198.51.100.7:8443/feed', false],
Worst known vulnerabilities (5 of 5)
AdvisorySeverityPackageSummary
GHSA-gfr2-rv44-r23chighmarkdown-it@15.0.1markdown-it: Quadratic-time rendering of a single multi-line link reference definition with default options (regression …
GHSA-r7fv-28h4-cvq7highmarkdown-it@15.0.1markdown-it: Quadratic complexity in smartquotes with unmatched closing quotes
GHSA-r4xh-jqrq-34v2moderatesmol-toml@1.8.0smol-toml: Quadratic-time parse() from parseKey rescanning to end of document on each key line
GHSA-238p-pmpm-9mq7lowkatex@0.16.47KaTeX: Existing prototype pollution can bypass trust restrictions
GHSA-vfgh-jcmw-g37qlowmarkdown-it@15.0.1markdown-it: Quadratic-time denial of service in inline HTML parsing with html enabled

By the numbers

Stars16.4K
Forks1,326
Contributors458
Commits7,558
Open issues574
Open pull requests114
Releases72
Latest release1.30.4
LicenceAGPL-3.0
Main languagePHP
Project age14 years
Last pushOct 26, 2026
Tracked files1,309
Lines of code187.1K
Checkout size12 MB

Lines by language: PHP 130.7K, CSS 33.9K, Markdown 15.3K, JavaScript 4,621, YAML 951, HTML 696.

Questions

Is FreshRSS free?

Yes. FreshRSS is free and open source under the GNU AGPL 3.0, with no paid tier. You pay only for whatever server you run it on, and several hosting providers offer it ready-made if you would rather not run it yourself.

Can I use FreshRSS from my phone?

Yes, two ways. The web interface works in mobile browsers, and FreshRSS has an API compatible with Google Reader that many feed apps can sync with, such as FeedFlow on Android and iOS or Reeder Classic and Readkit on Apple devices. Enable the API in the settings and set an API password first.

What do I need to run FreshRSS?

Docker on any small Linux machine is the easiest route. Without Docker you need Apache, nginx or lighttpd with PHP 8.1 or newer and a few common PHP extensions. SQLite is built in, so a separate database server is optional. It runs comfortably on very low-end hardware such as a Raspberry Pi.

Can FreshRSS follow sites that have no RSS feed?

Yes, for many of them. FreshRSS can build a feed from a web page using XPath rules you define, or from a JSON document, and extensions and tools like RSS-Bridge cover more cases.


This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.