Host hopping shouldn’t require a consultant
Most CMS “migrations” are archaeology: database dumps, upload folders, half-broken URLs, and a prayer that plugins survive the flight.
Forma’s bet is simpler: the site is a package.
What’s in the zip
From Settings → Backup (or GET /api/v1/export/site with backup:read):
| Piece | Why it’s there |
|---|---|
manifest.json |
format=formax-site, format_version, schema_version, app_version |
data.json |
Portable content snapshot (pages, posts, settings, redirects…) |
database/forma.db |
The live SQLite file |
uploads/ |
Every binary the site actually uses |
That’s the whole product surface that matters for this site. Not the PHP app tree — the content + media + settings.
Two exports, two jobs
- Site package (
/export/site) — binaries included. Use this to move hosts or clone staging. - Versioned JSON (
/export) — no binaries. Handy for diffs, audits, and agent-readable snapshots.
Import is the reverse: Admin → Backup → Import, or POST /api/v1/import/site with multipart field package.
Schema version is the forward gear
schema_version exists so future Forma releases can migrate older packages instead of rejecting them cold. Packages newer than the running app get rejected on purpose — you upgrade the app first, then import.
That’s how you avoid the WordPress trap of “restore succeeded, site broken.”
A migration that feels like shipping a box
- Export package from production (or ask an agent to).
- Drop a clean Forma instance on the new host.
- Import the zip (replace DB; merge or replace uploads as needed).
- Point DNS. Flush cache. Check
/sitemap.xmland a couple of pages.
No plugin compatibility matrix. No “which MySQL version.” One file database, one uploads tree, one manifest.
Agents and backups
Give a trusted agent backup:read and it can pull a package before a risky rewrite. Give settings:write and it can import into staging. That’s not magic — it’s treating backup/restore as API surface instead of a ritual you only remember after the outage.
What packages are not
A site package is not an app update. It won’t replace admin/, lib/, or api/. Content moves in the zip; Forma the product moves with git releases / deploy. Keep those stories separate and both stay honest.
Portability isn’t a slogan if you can’t put the whole site in one artifact. Now you can.