Every CMS I've tried for Astro comes with the same overhead: a database to provision, a media CDN to configure, an auth service to wire up. For small sites and personal projects, that's a lot of ops for not a lot of content.
So I built Orbiter — a CMS where everything lives in one .pod file. Content, media, schema, users, sessions. All of it.
The idea
your-site/
├── astro.config.mjs
├── content.pod ← your entire CMS
└── src/pages/
The .pod extension is just SQLite. You can open it with any SQLite browser. Copy it, your whole site moves with it. Back it up with cp.
Setup
npm install @a83/orbiter-integration
// astro.config.mjs
import orbiter from '@a83/orbiter-integration';
export default defineConfig({
output: 'server',
integrations: [orbiter({ pod: './content.pod' })],
});
That's it. Orbiter injects a full admin UI at /orbiter using Astro's injectRoute — no files added to your src/pages.
Reading content
The virtual module mirrors Astro's own content collection API:
---
import { getCollection, getEntry } from 'orbiter:collections';
const posts = await getCollection('posts');
const post = await getEntry('posts', 'my-first-post');
---
For multilingual sites there are getLocaleCollection and getLocaleEntry helpers using a slug--locale convention.
What's in the admin
- Collection editor — rich text (Markdown + live preview), all common field types
- Schema editor — add or change fields without migrations
- Media library — stored as BLOBs directly in the pod
- Version history — every save creates a snapshot
-
JSON API —
GET /orbiter/api/[collection]with optional Bearer token - Import — WordPress WXR and Markdown files
- GitHub sync — for serverless environments where the filesystem is ephemeral
- PWA — the admin is installable on mobile
The tradeoffs I'm honest about
SQLite BLOB storage is convenient but not for large media libraries. If you have thousands of high-res images, this isn't the right tool. For a typical content site it's fine.
Serverless filesystems are ephemeral. Netlify and Vercel don't persist writes between deploys. The GitHub sync mode works around this — pack your pod and media into a git commit, rebuild on push — but it adds steps. I'm still not 100% happy with this DX.
WAL mode helps with concurrent reads but SQLite is still SQLite. For a site with hundreds of simultaneous admin users this is the wrong choice. For a team of 1–5 editing content, it's perfectly fine.
Why not Keystatic / Decap / Tina?
All great tools. The difference: they store content as files in your git repo, which means your database is your git history. That's a valid approach but it means every content change is a commit, and media files bloat your repo fast.
Orbiter's approach is the opposite: one binary blob, no git history for content, trivial to move.
Try it
git clone https://github.com/aeon022/orbiter.git
cd orbiter && npm install && npm run seed && npm run dev
Admin at http://localhost:8080/orbiter — login: admin / admin
Or scaffold a new project:
npm install -g @a83/orbiter-cli
orbiter init my-site
cd my-site && npm install && npm run dev
Top comments (0)