Versioning
OpenFeed is self-hosted software. Once you install it, your database lives on your server — we never have access to it. The versioning system is designed with that in mind: everything is automatic, explicit, and safe to run without thinking about it.
The Version Number
There is one version number: the version field in package.json. It follows semantic versioning (e.g. 0.1.0).
This same number is:
- Reported by
GET /api/version - The version shown in any release tags on GitHub
There is no separate API version, no header-based versioning, and no /v1/ URL prefix. Because OpenFeed is self-hosted, a given server always runs exactly one version of the software, so URL-based API versioning adds complexity without benefit.
Checking What Version Is Running
GET /api/versionThis endpoint is always public (no access key required). It returns:
{
"version": "0.1.0",
"dbVersion": 4
}version— the application version frompackage.jsondbVersion— the highest database migration that has been applied (see below)
Database Migrations
The database schema evolves through numbered migrations defined in src/server/db/migrations.ts. Each migration has:
- A sequential integer version (
1,2,3, ...) - A short description
- An
up()function that applies the schema change
Migrations are tracked in a schema_migrations table inside your SQLite database:
CREATE TABLE schema_migrations (
version INTEGER PRIMARY KEY,
description TEXT NOT NULL,
applied_at INTEGER NOT NULL -- Unix milliseconds
)Migrations run automatically on startup. When you upgrade OpenFeed and restart the server, any new migrations are applied before the server begins handling requests. No manual database steps are required.
Each migration runs inside a transaction — if something goes wrong mid-migration, no partial change is committed and the migration will be retried on the next startup.
Existing Databases
If you have a database created before the migration system was introduced (i.e. schema_migrations is empty but your tables already exist), OpenFeed detects this on first boot and stamps the existing migrations as already applied without re-running them. Your data is not touched.
Upgrade Process
# From inside your openfeed directory:
bash scripts/setup.shThat's it. The script pulls the latest code, installs dependencies, and rebuilds. When you restart the server, any new migrations run automatically.
After restarting, confirm the upgrade with:
curl http://localhost:3000/api/versionAdding a Migration (For Contributors)
When a schema change is needed:
- Open
src/server/db/migrations.ts - Append a new entry to the
MIGRATIONSarray with the next sequentialversionnumber:
{
version: 5,
description: "Add read_at column to items",
up: (db) => {
db.exec("ALTER TABLE items ADD COLUMN read_at INTEGER");
},
},- Bump the
versionfield inpackage.json(at minimum a patch bump) - Include both changes in the same commit/PR
Rules:
- Never renumber or modify a migration that has already been released — existing installs will have already applied it
- Always append; never insert in the middle
- Keep each migration focused on a single, atomic schema change
- Prefer
ALTER TABLEandCREATE TABLEoverDROP TABLE— preserve user data whenever possible - If a migration could be slow on large datasets, note it in the description