File-based and dependency-free

CTXR has no database. Nodes are JSON files on disk. Indexes are JSON files too. Configuration, actors, audit logs — files. There is no PostgreSQL to provision, no schema to migrate, no ORM in the middle. The filesystem is the database.

It also has no framework and no build step in its core. The platform is plain PHP with no Composer dependencies, and the front-end ships as native ES modules with no bundler. This isn’t minimalism for its own sake. Each of these choices buys something concrete.

Why file-based

Derivability. Everything the system needs to run fast — indexes, compiled graphs — can be rebuilt from the raw nodes. The source of truth is the JSON in data/; the rest is derived. If an index is corrupt or a compiled document is stale, you don’t restore it from a backup, you regenerate it. Recovery is a command, not a procedure.

Disaster recovery is a file copy. A space is a directory. Backing one up is backing up a folder; cloning one is copying it; restoring one is putting the folder back and rebuilding the derived parts. There’s no separate backup strategy for “the database” because there is no database.

Local development is trivial. No container, no database server, no seed scripts. Check out the files and you have the real thing. What runs on your machine is what runs in production, because it’s the same files.

No query-planner mysteries. When content is files, you can see exactly what exists and what changed. “Who has access?” is a file you can read. “What changed?” is git diff. There’s no opaque, live database state you have to export and decrypt to understand.

Why dependency-free

Auditable. With no third-party packages in the core, every line the platform runs is code you can read. For a system that hosts many tenants, that’s not a nice-to-have — it’s the difference between trusting the platform and hoping about it.

Deployable. No composer install step that can drift, no npm build that can break differently on the server than on your laptop. Deploying is moving files. Fewer moving parts means fewer ways to fail at the worst moment.

Long-lived. Nothing depends on a package staying maintained, a build tool staying fashionable, or a transitive dependency not shipping a surprise. Code with no dependencies doesn’t rot when the ecosystem moves on.

The honest trade-offs

A file-based, single-instance design is not the right tool for everything, and it’s worth being clear about that. It isn’t built for write-heavy, high-concurrency workloads the way a clustered database is. Some conveniences a database hands you for free — ad-hoc queries across everything, transactions spanning many records — are things CTXR handles deliberately and within bounds instead.

That’s the point, though. The platform is optimized for content that is written occasionally and read constantly, served fast and reasoned about easily. For that shape of problem — which is the shape of almost every website — putting the data in files is not a compromise. It’s the advantage.