CLI tool
fossar/selfoss avatar
fossar/selfoss

selfoss: a PHP feed aggregator you install by copying files

multipurpose rss reader, live stream, mashup, aggregation web application

2,470 stars339 forksHTMLGPL-3.0

At a glance

What is it?
selfoss is a self-hosted RSS and social feed reader written in PHP, distributed as a directory you copy into a document root. Its install model and its maintenance model are the same thing, and both matter more than its feature list.
Who is it for?
Adopt selfoss if you want a PHP feed reader you can deploy by copying files and updating with a cron job or systemd timer pointed at /update, and if you are willing to re-apply your config.ini changes after every release. Do not adopt it if you need a client-side app or cannot grant your database user trigger-creation rights, because the schema is created and migrated automatically and will not proceed without them.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

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

DEEP OPEN-SOURCE ANALYSIS

What selfoss is for, and who ends up running it

selfoss collects updates from web sites, social networks and other platforms into a single web interface. The README calls it a multipurpose RSS reader and feed aggregation web application, and the topics on the repository add mashup and news-feed to that description. The intended user is someone who wants their reading list on hardware they control rather than in a hosted service account.

The practical audience is narrower than the tagline. Because selfoss is written in PHP and the installation instructions begin with copying files into a document root, it fits people who already have a PHP host, whether that is shared hosting, a small VPS, or a container they manage themselves. If you do not have PHP hosting and do not want any, the copy-the-directory model is not an advantage, it is a prerequisite you have to satisfy first.

The repository is not archived and the last push recorded is 2026-09-06, so the project is still receiving commits. The README describes the current state plainly: it is maintained by Jan Tojnar in his free time, and maintenance is prioritized over new features. That sentence is the most useful thing on the page for anyone deciding whether to depend on selfoss.

Release cadence is the first thing to check before you commit

The release list is uneven. Version 2.19 is dated 2022-10-12, version 2.18 is dated 2018-03-05, and 2.17 is dated 2017-03-17. The README header for the development tree reads selfoss 2.20-SNAPSHOT, which means work has continued past 2.19 without a tagged release at the time of that snapshot.

This shape matters for how you plan upgrades. A project that tags rarely is not abandoned, since commits continue, but it does mean that fixes you want may only exist in a development build. The README anticipates exactly this and offers three download channels: stable releases for people who just want to use selfoss, development builds hosted on Cloudsmith for people who want unreleased features or bug fixes, and the Git-tracked source for contributors. Choosing a channel is a real decision here, not a formality.

The gap also means the upgrade instructions deserve more attention than they would in a project that ships monthly. The README tells you to consult the NEWS file to learn about backwards incompatible changes, and it warns that config.ini itself changes between versions and that you have to update it too. With multi-year gaps between releases, the number of changes accumulated in a single upgrade step can be larger than the version number suggests.

How the pieces fit: PHP application, data directory, cron-driven updates

The architecture visible in the README is a server-side PHP application with a writable data directory and an external trigger for fetching. Installation step one is copying all files, including the invisible .htaccess files, into a document root. Step two makes data/cache, data/favicons, data/logs, data/thumbnails and data/sqlite writeable. Step three puts database credentials in config.ini.

Feeds do not update themselves. Step five says to create a cron job or a systemd timer for updating feeds and point it at the /update URL on your selfoss instance via wget or curl, or alternatively to execute cliupdate.php from the command line. That is the whole scheduling model: an HTTP endpoint or a CLI script, invoked by whatever timer you already run. There is no built-in worker described in the README.

Database setup is also automatic. The README states you do not need to create the database tables because they will be created automatically, with the caveat that your database user must be allowed to create triggers. The same caveat appears in the update instructions, which says the database will be updated automatically under the same trigger-creation requirement. This is a design choice worth noticing: schema migration happens as a side effect of running the application, not as a separate migration command you invoke deliberately.

On the client side, the README lists Parcel as the build tool for the browser interface and names several bundled libraries, including SimplePie, Graby, htmLawed and Tracy. Feed parsing and full-text extraction are therefore delegated to third-party PHP libraries rather than implemented in the repository itself.

Getting it running: the actual commands and config keys

The stable path needs no build step. Copy the directory, set the five data subdirectories writeable, rename config-example.ini to config.ini, and edit it. The README says no configuration is needed to use selfoss, and that if you want SQLite you do not need to change anything in config.ini at all. For other databases you insert the access data in config.ini. The README's own instruction for the file is to delete any lines you do not wish to override, which implies config.ini is a set of overrides layered on defaults rather than a complete settings file.

If you obtained selfoss from Git, the README requires composer install to retrieve external sources, and npm install inside the client/ directory for JavaScript dependencies. It offers npm run install-dependencies as a shortcut for installing both sets. Building the browser interface uses npm run build, which the README says installs the result into the public directory. During development, npm run dev watches for asset changes, rebuilds bundles and reloads selfoss automatically. The README notes that when switching between npm run dev and npm run build you may need to delete client/.cache. A distributable package can be produced with npm run dist, which the README says creates a zipball with dependencies bundled.

Contributors have two more commands: npm run check runs the coding style checks that CI enforces, and npm run fix attempts to correct formatting. Importing an existing feed list is done through the web interface at the /opml path on your instance, where you upload an OPML file exported from your previous reader.

Upgrades rewrite the application but not your data, and that asymmetry is the trap

The update procedure is explicit about what to delete and what to keep. Back up the database and the data directory. Delete all old files and directories except data/ and config.ini, with the README capitalizing do NOT delete the data directory. Copy the new files in, again including the invisible .htaccess files. Then consult NEWS.md, clean the browser cache, and reinsert your database connection and individual configuration into config.ini.

The step that will bite people is the last one. The README states that config.ini changes between versions and that new options are added, so you have to update the file too. If you have been editing config.ini in place across upgrades, you now have to reconcile your customizations with a file whose upstream shape has moved. Nothing in the README describes a mechanism for merging those changes automatically. In practice this means keeping your local overrides in a diffable form, or accepting that each upgrade is a manual re-application exercise.

The database side is the opposite: it migrates itself, provided the database user can create triggers. If your hosting provider grants a restricted database user without that privilege, the automatic schema creation and migration will not work, and the README gives no fallback procedure for creating the tables by hand. That is a hard dependency on your database permissions, and it applies to first install as much as to upgrades.

Where selfoss is the wrong tool

The clearest mismatch is the update trigger. If you cannot run cron or a systemd timer, or cannot reach the /update endpoint from wherever that timer runs, feeds will not refresh. selfoss expects to be polled on a schedule by something outside itself. A reader who wants updates to appear the moment a site publishes, without configuring a scheduler, is not the user this design targets.

The second mismatch is the permission requirement on the database user. Self-hosting on cheap shared hosting sometimes means a database account without trigger privileges. The README offers no workaround, so this becomes a blocker rather than an inconvenience.

The third is the front-end build. Anyone who wants to modify the interface, or who takes the Git route to get a fix that has not been released, has to run composer install, npm install in client/, and npm run build. That is a normal workflow for a PHP developer and an unwelcome one for an administrator who chose selfoss precisely because installation is copying files.

Finally, the maintenance statement deserves to be read literally. The README says maintenance is prioritized over new features, and the release dates show what that looks like in practice. If your decision depends on a feature that is not already present, the project's own stated priorities suggest you should not expect it on a schedule.

The alternative worth comparing, and the licensing detail to check

The obvious comparison is with a desktop feed reader that stores subscriptions locally and fetches on its own schedule. The difference is not the feature list, it is where the fetching happens. A desktop reader runs as a process on your machine, holds its own schedule, and needs no writable web directory, no database user with trigger privileges, and no cron entry. selfoss inverts that: fetching is a server-side job triggered from outside, state lives in a database you provision, and the interface is a web page you reach over the network. The trade is that selfoss is reachable from any device with a browser, including the Android client the README recommends, Reader For Selfoss. A desktop reader is reachable from the machine it runs on unless you add synchronization yourself.

On licensing, selfoss is GPL-3.0, created by Tobias Zeising. The README adds two qualifications that are easy to miss. Some parts of the source code can be licensed under version 3 only, and the project is currently trying to resolve that, with a link to issue 1218. Separately, the package with bundled dependencies might be distributed under version 3 only. That distinction matters if you plan to redistribute selfoss or a modified build, because the or-later option may not apply uniformly across the codebase. This is a factual description of what the README states, not legal advice; if redistribution is part of your plan, read the referenced issue and the licence texts yourself.

Upgrade cost is the recurring expense. Each release means backing up the database and data directory, deleting and replacing application files, re-applying config.ini, and reading NEWS.md for incompatible changes. There is no described automation for the configuration half of that work.

Editorial conclusion

Adopt selfoss if you want a PHP feed reader you can deploy by copying files and updating with a cron job or systemd timer pointed at /update, and if you are willing to re-apply your config.ini changes after every release. Do not adopt it if you need a client-side app or cannot grant your database user trigger-creation rights, because the schema is created and migrated automatically and will not proceed without them. Before committing, verify three things: that your PHP server can write to data/cache, data/favicons, data/logs, data/thumbnails and data/sqlite; that you can run composer install and npm install in client/ if you take the Git route; and that you have read NEWS.md for the version you are moving to, since the README explicitly points there for backwards-incompatible changes.

Official sources

  1. fossar/selfoss on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Community notes

Community notes