Search by

zFeeder 2.0 - the 2004 PHP RSS aggregator, rebuilt for 2026. Flat-file or SQLite, OPML subscriptions, template driven, embeddable in one line.

Package info

github.com/andreibesleaga/zfeeder

Type:project

pkg:composer/andreibesleaga/zfeeder

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v2.0.1 2026-09-18 10:43 UTC

This package is auto-updated.

Last update: 2026-09-18 15:36:35 UTC


README

zFeeder 2.0

The PHP feed aggregator from 2004, rebuilt for 2026.

CI License: GPL v2+ PHP 8.3+

zFeeder reads RSS, Atom and JSON feeds and puts them on your page. It keeps its subscriptions in OPML files, caches what it fetches, renders through templates you can edit, and drops into an existing page in one line of PHP. It needs no database server and no build step.

It was first released in 2003–2004 on SourceForge and, by its author's own count, ended up running on more than 20,000 websites. Development stopped at version 1.6 in 2004. This is version 2.0: the same product and the same architecture, on a current stack, with the security problems of 2004 fixed.

The original is archived, unmodified, as zfeeder-1.6.zip in andreibesleaga/old-projects — and the classic templates in this version are tested byte for byte against output captured from that code running on PHP 5.6. See docs/HISTORY.md.

What it does

  • Reads RSS 0.9, 0.91, 0.92, 1.0 and 2.0, Atom 1.0 and JSON Feed 1.1.
  • Keeps subscriptions in OPML, one file per category. Files written in 2004 still load.
  • Two storage backends, chosen at runtime: flat files, or a single SQLite file. bin/zfeeder migrate moves between them in either direction.
  • Caches every feed with a per-subscription refresh interval, using ETag and If-Modified-Since, and keeps serving the last good copy when a publisher is down.
  • Two complete template sets: classic reproduces the 2004 output exactly (14 templates), and modern is a responsive, accessible redesign (16). 30 in total.
  • An administration panel with the same five screens as 2004 — add feed, subscriptions, config, import, updates — in either a modern or a classic skin.
  • Feed autodiscovery from a site URL, and OPML import and export.
  • Embeds as a PHP include, an HTML fragment over HTTP, or a JSON API.
  • A command line tool for everything the panel does, so cron and scripted installs work.

Install

Docker, the quickest way

docker run -d --name zfeeder -p 8080:80 \
  -e ZF_ADMIN_PASSWORD_HASH="$(docker run --rm ghcr.io/andreibesleaga/zfeeder bin/zfeeder hash-password 'your password' | head -1)" \
  -v zfeeder-data:/var/www/data \
  ghcr.io/andreibesleaga/zfeeder:2.0.0

Open http://localhost:8080. The panel is at /admin.

A public instance runs at https://zfeeder.up.railway.app, with the panel in read-only demonstration mode.

From source

git clone https://github.com/andreibesleaga/zfeeder.git
cd zfeeder
composer install --no-dev
bin/zfeeder seed                     # load the shipped example subscriptions
bin/zfeeder hash-password            # prompts, prints the hash
php -S 127.0.0.1:8080 -t public      # development server

Shared hosting, the way 1.6 was installed

Download zfeeder-2.0.0.zip from the releases, unpack it, upload it, point the document root at public/, and put the data/ directory outside the web root. Dependencies are already in the archive; there is nothing to compile and no Composer needed on the server. Full instructions: docs/DEPLOYMENT.md.

Use it

One line, exactly as in 2004:

<?php echo zfeeder(['category' => 'news', 'template' => 'modern/cards']); ?>

The 1.6 include still works too:

<?php include 'zfeeder.php'; ?>

Not a PHP site:

GET /embed?category=news&template=modern/list     an HTML fragment
GET /api/feeds?category=news                       JSON
GET /api/opml/news                                 the subscription list as OPML

From the command line:

bin/zfeeder seed                           # load the shipped example subscriptions
bin/zfeeder add https://lwn.net/headlines/rss --category=opensource
bin/zfeeder refresh --category=news        # what cron runs
bin/zfeeder list-feeds
bin/zfeeder export --category=news > news.opml
bin/zfeeder check-config

bin/zfeeder list prints all twelve commands; each takes --help.

Refresh from cron every fifteen minutes:

*/15 * * * * /path/to/zfeeder/bin/zfeeder refresh --quiet

Configure it

Every option can be set three ways — an environment variable, data/config.json, or the admin panel — and the environment always wins. bin/zfeeder check-config prints the effective value of each option and where it came from.

ZF_STORAGE=sqlite           # flat (default) or sqlite
ZF_TEMPLATE_SET=modern      # classic or modern
ZF_ADMIN_SKIN=modern
ZF_MAX_DESCRIPTION_CHARS=600
ZF_DEMO_MODE=true           # read-only panel, for a public demo

All 44 options: docs/CONFIGURATION.md.

Security

The 2004 code stored passwords as unsalted MD5, wrote its configuration file as PHP built from $_POST, passed $_GET straight into a filesystem path, and would fetch any URL it was given. None of that survives. Version 2.0 uses Argon2id with a rate-limited login, a CSRF token on every state-changing request, an allow-list HTML sanitiser on all feed content, an address guard that blocks loopback and private ranges on every redirect hop, name validation plus realpath containment on every path derived from input, XML parsing with document type declarations refused, and JSON configuration stored outside the web root.

Each of the eighteen controls has a class in tests/Security/, S01… to S18…; the suite is 484 tests. See docs/THREAT-MODEL.md, which also records the four defects found in 2.0 itself and closed, and SECURITY.md.

Do not deploy the 2004 release. It is kept as history in andreibesleaga/old-projects, and it is not safe.

Documentation

Configuration every option, generated from the schema
Deployment Docker, Railway, Fly, Render, Kubernetes, a VPS, shared hosting
Templates the format, every token, writing your own
Architecture how it is put together and why
Upgrading from 1.6 bringing a 2004 installation forward
Runbook operating it: backup, restore, rotate, upgrade
Threat model what it defends against and how that is proven
Accessibility the WCAG 2.2 AA commitment and how it is checked
Test plan the suites, the golden method, and what is not tested
Verification report what each review actually produced, and what was not verified
History 2003 to 2026, with the original screenshots
Roadmap what 2.x will and will not do

Contributing

CONTRIBUTING.md. In short: the classic templates are frozen and proven by golden tests, tokens are never removed, new dependencies need a reason, and a security fix needs a test that fails without it.

Licence

GPL-2.0-or-later, the same licence the 2004 release carried. See LICENSE.

zFeeder is © 2003–2026 Andrei N. Besleaga. The original project is archived at sourceforge.net/projects/zvonnews.