---
"@type": Article
"@id": "https://helloloam.dev/principles/files-not-a-database"
"@source": "https://helloloam.dev/data/article/files-not-a-database.json"
"@stamp": "2026-10-22T21:53:55+00:00"
about:
  "@type": DefinedTerm
  "@id": "https://helloloam.dev/data/definedterm/files-not-a-database.json"
  name: Files, not a database
  identifier: files-not-a-database
  inDefinedTermSet:
    "@type": DefinedTermSet
    "@id": "https://helloloam.dev/data/definedtermset/basics.json"
    name: Basics
    identifier: basics
author: {"@id":"https://helloloam.dev/#organization"}
datePublished: "2026-10-03"
description: A site is a folder with four roots — data, theme, assets and guide. No database, and nothing behind the scenes that behaves like one.
headline: Files, not a database
identifier: files-not-a-database
inLanguage: en
publisher: {"@id":"https://helloloam.dev/#organization"}
url: "https://helloloam.dev/principles/files-not-a-database"
---

# Files, not a database

## A site is a folder

Content is one JSON file per thing in `data/`. Templates are PHP files in `theme/`. Images and other served files sit in `assets/`. The site's own rules for the agents that work on it are markdown in `guide/`. Four roots, one kind of file each — that is the whole site.

## Why not a database

A database is a second world with its own language, [its own backups](/principles/backups-as-a-snapshot) and its own failure modes — and it needs an interface in front of it. Files are the world your operating system, git, your editor, the web server and your agent already share. Loam put the content there. Everything it does — rendering, checking, history, access — reads from the files and never replaces them.

## What files give you

- **Recovery is copying.** Restore, move or clone a site by copying a folder. No dump to import, no migration to run.
- **History is free.** Every change is a diff, every earlier state a commit. Undo, audit trail and backup are one mechanism.
- **Nothing is hidden.** List a folder and you see the entire state of the site. Every live entity is public at its own address, `/data/<type>/<name>.json` — the file, served as it lies.
- **Ownership is literal.** Your content is yours because it sits in a folder you can pick up.

## Lists instead of queries

Without a database, order is something you choose. A menu, the featured services, the team in the order you want them: each is a list you keep by hand, and the page that shows it reads that list. For machines there is one index of everything live, `/data.json`, with a word search on it (`?q=`) — hits first, then the file. An overview of a type, newest first, comes from the same index.

## When something goes wrong

Because the files are the truth, a wrong state is fixed by fixing the file, and wrong behaviour by fixing the engine. There is no table only the application can read and [no cache that has to be warm](/principles/speed-by-caching): delete what the engine derived and the next request builds it again. That one distinction keeps a loam site understandable on its worst day.

## What it costs

Queries. A database is good at “every article from 2025 by this author, newest first”; a folder is not. Loam answers with curation and one index: lists you keep in order by hand, and a full index with word search for machines. For a company, an organisation or a body of knowledge that is the right trade. A marketplace needs a different tool.
