Buy me a coffee (opens new window) DE · Deutsch

Flat-file CMS · PHP 8.2+ · MIT

Counterglow Pages are folders.

A content system without a database. Every page is a folder, every text a plain file. Copy it, commit it, edit it on a plane, hand it to someone who has never heard of this software. It keeps working.

In progress · open source

The counterglow, German Gegenschein: a faint oval of sunlight scattered back by interplanetary dust, directly opposite the sun. Too dim to notice unless you already know where to look.

At a glance

Counterglow is a free, open-source flat-file CMS written in pure PHP 8.2 or newer by Dirk Gerber (Gerber.Media). Pages are folders and content is plain text, so there is no database, no build step and no vendor directory. It comes with a web panel, eleven themes, responsive images, SVG layout templates, a sitemap, an RSS feed and JSON search built in. Content files are byte-compatible with Kirby. Licence: MIT.

Language
PHP 8.2 or newer, GD recommended
Database
none
Dependencies
none, not even Composer packages
Licence
MIT
Status
in progress

The folder is the page

The folder name carries the URL, the sort order and the status. Changing the status in the panel just renames the folder. Pick a folder to see what a visitor gets.

content/

cover.jpg and cover.jpg.txt sit next to it: the image and its alt text.

/about
File · 1_about/about.txt
Title: About
----
Text:
A short story of how this site came to be.
Status · listed

About

Appears in menus and feeds, sorted first.

/notes/why-flat-files
File · 3_notes/1_why-flat-files/note.txt
Title: Why flat files outlive databases
----
Date: 2026-02-14
----
Tags: architecture, content
----
Text:
Markdown goes here, with **bold**, lists,
tables and code fences.
Status · listed

Why flat files outlive databases

The file name picks the template: note.txt renders through note.php.

/imprint
File · imprint/default.txt
Title: Imprint
----
Text:
Who is responsible for this site.
Status · unlisted

Imprint

Reachable by its URL, hidden from listings.

—
File · _drafts/idea/note.txt
Title: An idea for later
----
Text:
Not ready yet.
Status · draft

An idea for later

Only visible when you are signed in.

What is inside

The YAML parser, the Markdown parser, the image pipeline and the panel are all written for this project.

  • Content tags

    Rich components without writing HTML: (image: cover.jpg caption: …), galleries, video, files. Register your own from a plugin.

  • Templates

    A template is a PHP file with $page and $site ready. Fields are chainable and never null; collections filter, sort and paginate.

  • Responsive images

    image() writes srcset, dimensions and lazy loading. Renditions are generated once and cached as static files.

  • SVG layout templates

    Draw a layout in Inkscape, Figma or Illustrator, name layers like cg-text-title or cg-link-notes, and the CMS fills them from the content.

  • Every SVG sanitised

    Uploads are cleaned on the way in and templates on the way out, against an allowlist. No scripts, no event handlers, no resources from other sites.

  • Headless when you want

    /sitemap.xml, /feed.xml, /robots.txt, /search.json?q=… and every page as .json.

  • The panel

    Server-rendered, about nine kilobytes of JavaScript. ⌘K palette, ⌘S save, split Markdown preview, drag and drop. The essentials work without JavaScript.

  • Accounts and roles

    Admin, editor, author. Accounts are PHP files with bcrypt hashes, every POST carries a CSRF token, failed logins back off exponentially.

Eleven themes, one content folder

A theme only ships what it changes. Every lookup checks the theme first and falls back to /site. Switch in the panel under System → Theme.

  • HaloEditorial: serif display type, drop caps, printed paper.Accent #b4402c
  • UmbraDark and monospaced for docs and changelogs.Accent #5fd68a
  • PrismImage-first: split-screen hero, full-bleed photos.Accent #7b5cf0
  • Counter NewsTech news: lead story, card grid, reading progress.Accent #e5372b
  • HandbookDocumentation with a sidebar that maps the site.Accent #2563eb
  • MeridianOversized grotesk, generous whitespace.Accent #2f5bff
  • PorcelainAiry, hairline rules, a quiet sage accent.Accent #5f7a58
  • BoardroomStructured for reports and business writing.Accent #1a56db
  • GraphiteModern dark with one signal-lime accent.Accent #c6f24a
  • GripSkate-zine: condensed caps, thick ink rules.Accent #ff4d17
  • EyelinerAfter-hours: ink-black, hot magenta, italic serif.Accent #ff2d76

Running in one line

  1. You need PHP 8.2 or newer. GD is recommended for image resizing.

  2. Start the built-in server in the project folder:

    php -S localhost:8000 router.php
  3. Open localhost:8000/panel and create the first account. That is the whole installation.

On a real server

Upload the folder and make content/, media/, site/accounts/ and logs/ writable. Nothing to compile, migrate or seed. Apache rules ship in .htaccess, an nginx example is in the README.

Back up content/ and site/ and you have backed up the entire site.

What comes next

Counterglow is in progress. The next steps, in this order:

  1. RevisionsThe last ten versions of every page, kept on save.
  2. Redirects on renameA new slug writes a redirect, so old links keep working.
  3. Content exportA ZIP of content/ straight from the panel.
  4. Landing page generatorBuilt on the SVG slot mechanism.

Questions

Does Counterglow need a database?

No. Pages are folders and content is plain text files. Back up the folder and you have backed up the site.

Can I move existing Kirby content?

Yes. The content files are byte-compatible with Kirby, so a content folder can be moved across without a migration script.

What does Counterglow cost?

Nothing. It is open source under the MIT licence, and the code is on Codeberg.

Which hosting does it need?

Any web host with PHP 8.2 or newer. There is no Composer, no npm and no build step, so uploading the folder is enough.

Can I use it headless?

Yes. Every page is also available as JSON, and search runs at /search.json.

Read the code, keep the folder.

Questions, ideas or bug reports? Write to me. hello@gerber.media