New: Two-factor sign-in, active sessions, security check — admin@0.3.88 · Changelog →

Your entire CMS
in one file.

Content, media, schema, users — all in a single POD. One SQLite file. Copy it anywhere. No database server. No cloud account. Built for Astro.

$npm install @a83/orbiter-admin
localhost:4322
Orbiter Space Station mode — dark glassmorphism dashboard with floating dock
0cloud deps
1 fileyour entire CMS
20built-in features
offlineno internet required
MITfree forever
< 2 minto first admin
As written about on
Admin runs on any Node.js host
RailwayCoolifyFly.ioRenderHetznerNode.jsGitHub Pages*Netlify*
* serverless platforms use Git sync mode — content is committed to the repo before each build
↓   Astro builds   →   FTP deploy   ↓
Publishes to any shared host via FTP
World4YouStratoIONOSHostingerAll-InklAny FTP server
configure host, credentials & remote path in Settings → one click to deploy, or trigger automatically after each build

How it works

Your entire CMS lives next to your source code — in one file.

your-site/
├── astro.config.mjs
├── content.pod   ← your entire CMS
└── src/pages/
Step 1 — Start the admin
npm install @a83/orbiter-admin
ORBITER_POD=$(pwd)/content.pod npm start
Step 2 — Add the integration to astro.config.mjs
import orbiter from '@a83/orbiter-integration';

export default defineConfig({
  output: 'server',
  integrations: [orbiter({ pod: './content.pod' })],
});
Step 3 — Read content in your pages
import { getCollection } from 'orbiter:collections';

const posts = await getCollection('posts');

Take the tour

Real screens from a real pod — Space Station mode, dark. Hover the glowing outlines, or use ← →.

Orbiter admin: Dashboard. Calendar of what goes live when, stats at a glance, notes and to-dos — everything an editor needs on one screen.
Calendar of what goes live when, stats at a glance, notes and to-dos — everything an editor needs on one screen.
More screens & editor details

More screens

A full CMS admin — standalone server on port 4322, glassmorphism UI, three themes.

Orbiter Space Station mode — dark glassmorphism dashboard with floating dock
Space Station mode — glass cards, stats sidebar, notes & to-do, floating dock

Write. Insert. Arrange.

A block-based editor built for real content — rich text, inline images, and layout controls without leaving the page.

Orbiter block editor — heading, paragraph, and inline image with alignment controls
Block editor — B / I / code / H1–H3 / quote / list / divider / image
Image picker sheet showing media library thumbnails and upload button
Insert from anywhere

Pick from your media library or upload directly — the native file picker gives you access to iCloud Drive, Dropbox, Google Drive, and any connected cloud folder, no integration needed.

Editor showing image floated right with text wrapping around it, alignment toolbar visible
Text flow control

Float images left or right so text wraps around them naturally — or center them, or stretch full-width. One click, instant preview in split view. Serialized as standard markdown.

What's included

A full CMS admin — standalone on port 4322. The Astro integration handles content at build time via orbiter:collections.

◈
One file. Everything.
Content, media, schema, users, sessions — all in a single POD (a SQLite database with a .pod extension). Copy it anywhere. Back it up with cp.
⬡
Astro-native
One line in astro.config.mjs gives you orbiter:collections — a Vite virtual module that snapshots your published content at build time. Zero runtime fetch.
⌗
Familiar content API
Read content with getCollection and getEntry — same shape as Astro's built-in content collections.
⬢
Content Layer loader
orbiterLoader() plugs directly into Astro's Content Layer API. Use astro:content with auto-generated Zod schemas, incremental builds, and hot reload when the pod changes.
▦
Schema editor
Add or change fields without migrations. Export and import schemas as JSON to copy them between collections or pods.
◫
Media library
Upload, browse, and manage files. Images are automatically resized and compressed on upload. Four storage backends: pod BLOB, local disk, GitHub CDN, or external URL.
⟳
Version history
Every save creates a snapshot, capped at 20 per entry. Restore any previous version with one click from the editor sidebar.
⊞
JSON API + RSS/Sitemap
GET /orbiter/api/[collection] — optional Bearer token. Plus auto-generated RSS 2.0 feeds and an XML sitemap. All injected, no config.
Show all 26 features
⇅
Git sync mode
orbiter unpack extracts media BLOBs to files, orbiter pack restores them. Commit your pod + media to Git — a GitHub Actions template is included for automatic rebuilds.
🗓
Scheduled publishing
Set a publish_at date on any entry. The server auto-publishes and fires the build webhook at the right time. Set unpublish_at to expire content.
💬
Editorial comments
Per-entry comment thread in the editor. Post, resolve, delete. Optional email notification on new comments via SMTP.
⌘
Command palette
⌘K fuzzy search across all content and navigation. Installable as a PWA on mobile and desktop.
👥
Multi-user & roles
Admin and editor roles. Entry locking warns when two editors open the same entry simultaneously. Manage users in the UI.
⌾
Multilingual (i18n)
Per-entry locale variants — same slug, separate locale columns. Configure locales in Settings, translate entries via locale tabs in the editor. getLocaleCollection() and getLocaleEntry() with automatic fallback.
◉
Space Station mode
A distinct layout with a floating magnification dock, command palette (⌘K), vim keyboard navigation, HUD panel, notification center, zen mode, and a full mobile tab-bar. Three themes × two colour schemes.
⊡
Trash & restore
Deleted entries move to a recoverable Trash tab. Restore to draft or permanently delete. Bulk restore and bulk purge. Activity log records every action with actor and timestamp.
◎
Draft preview
Generate a preview token in Settings → API. Attach it to your preview URL — getPreviewEntry() reads any draft directly from the pod, bypassing the published snapshot.
✉
Form inbox
Receive contact and booking form submissions from your Astro site via POST /api/form/:formId. View, filter, reply by email, and mark as confirmed, rejected, or done — all from the admin UI.
◉
Built-in SEO
Every entry has a built-in SEO panel — meta title, description, and OG image. No schema changes needed. Access via entry.seo.title, entry.seo.description, and entry.seo.ogImage.
↑
FTP / FTPS deploy
Upload your Astro dist/ directly to any shared hosting via FTP or FTPS. Configure host, port, credentials, and remote path in Settings. One click to deploy — or trigger automatically after a build webhook.
⌗
Code snippets
Built-in snippet library under Tools → Snippets. Copy-paste Astro code for contact forms, booking forms, SEO <head>, image rendering, getCollection, ticket buttons, RSS, and sitemap — dynamically adapted to your collection names.
▣
Desktop App — Mac & Windows
Download the installer, double-click to launch. Pick a template (Blog, Portfolio, Business, Events) — the app creates collections and demo content automatically. No terminal, no Node.js, no npm.
⊕
WordPress importer
Export your WordPress site as WXR and import it directly in the admin. HTML body text converts to Markdown automatically. Post dates, categories, and slugs are preserved. No CLI, no scripts.
⊘
Entry locking
When two editors open the same entry simultaneously, a lock warning appears before any changes are made. 90-second lock with automatic heartbeat refresh. Prevents silent last-write-wins overwrites.
>_
CLI
orbiter init scaffolds a new project with starter templates. orbiter status shows pod health. orbiter sync pushes/pulls via rsync. orbiter encrypt/decrypt wraps the pod in AES-256-GCM for git-safe storage.
◆
Publish HTML
One-click static site generator. Choose a built-in theme (Orbit or Canvas), click Generate, download a ZIP with a complete website. Dark mode, responsive, OG tags, sitemap — no Astro or build tools needed.
No cloud. No lock-in. No compromise.

Your data.
No strings attached.

Every other CMS gives your content to a cloud. Orbiter gives it to you. A single POD — one SQLite file on your disk, in your repo, on your server. Copy it, encrypt it, email it. No account required. No monthly invoice. No vendor who can change pricing, shut down, or hold your data hostage.

📁
Backup in one command
cp content.pod backup.pod — that's your entire CMS. A 500-entry blog with images typically weighs under 50 MB.
✈️
Works completely offline
Run npm run dev on your laptop with no internet. Edit content on a plane. No API calls, no auth endpoints, no CDN.
🔍
Fully inspectable, always
Open your pod with any SQLite GUI. Run ad-hoc queries. No black box, no proprietary format, no data you can't read yourself.
⚖️
MIT License — genuinely free
Use it commercially, fork it, sell products built with it. No "open core" bait-and-switch. The full source ships with your project.
sqlite3 content.pod
# open your CMS like any other database
$ sqlite3 content.pod# list all tables
sqlite> .tables
_collections  _entries  _media  _users  _versions# inspect recent entries
sqlite> SELECT slug, status, updated_at
        FROM _entries ORDER BY updated_at DESC LIMIT 4;
my-first-post   published  2025-04-20
about-orbiter   published  2025-04-19
new-draft       draft      2025-04-18
hello-world     published  2025-04-15# how many media files?
sqlite> SELECT COUNT(*) || ' files, ' ||
        ROUND(SUM(LENGTH(data))/1048576.0, 1) || ' MB'
        FROM _media;
47 files, 18.3 MB# version history — every save is a snapshot
sqlite> SELECT COUNT(*) FROM _versions;
312

Honest tradeoffs

Orbiter is the right tool for small teams and content sites. Here's where it isn't.

⚠
Not for large media libraries
SQLite BLOB storage is convenient for content sites but not for thousands of high-res images. If your media library is in the gigabytes, this isn't the right tool.
⚠
Serverless requires extra steps
Netlify and Vercel don't persist filesystem writes between deploys. The GitHub sync mode works around this, but it adds steps. A VPS or Coolify gives you a better experience.
⚠
Built for small teams
Two people editing the same entry at the same moment will get last-write-wins. Fine for a team of 1–5. Not designed for large editorial teams working in parallel.

Space Station mode.

A distinct layout for the admin — dark glassmorphism, floating magnification dock, command palette, vim keyboard navigation, notification center, HUD panel, zen mode, and a full mobile tab-bar. Switch in one click from Settings.

Orbiter Space Station mode — dark glassmorphism dashboard with floating dock
Dashboard — glass cards, stats sidebar, notes & to-do, floating dock
Orbiter Space Station mode on mobile — bottom tab bar, responsive dashboard
Mobile-ready

The dock becomes a native-feeling bottom tab bar. Stats stack to a 2×2 grid. Cards resize to fit. Same content, any screen.

Floating dock⌘K command paletteVim navigationNotification centerHUD panel + draftsZen modeLive build status3 themes · 2 schemesMobile tab barNotes & to-do
Claude Code · ChatGPT · Antigravity

Scaffold a full project with AI.

One prompt. A complete Astro blog with Orbiter CMS — collections, example content, all pages, and a working admin — built by your AI assistant from scratch.

AI_SETUP.md — paste into any AI assistant
You are scaffolding a new Astro blog site using Orbiter CMS (https://orbiter.sh).Orbiter is a self-hosted CMS where all content, media, schema, and users live in asingle SQLite database called a POD (.pod extension). No database server. No cloud dependency.Your task: set up a complete, working project from scratch — including a seed scriptthat creates collections and example content, and Astro pages that consume the data.Follow every step below in order. Run commands as you go. Do not skip steps.─────────────────────────────────────────────STEP 1 — Create the Astro project─────────────────────────────────────────────STEP 2 — Install Orbiter packages + add npm scriptsSTEP 3 — Configure astro.config.mjsSTEP 4 — Write seed.js (collections, posts, authors, pages, admin user)STEP 5 — Run the seed scriptSTEP 6 — Create BaseLayout, Header, PostCard, and all pagesSTEP 7 — Start both dev serversSTEP 8 — Verify everything worksSTEP 9 — Clean up[ + full file contents, project structure, and troubleshooting guide ]

How Orbiter compares

Other CMS options for Astro — and where Orbiter fits in.

Show the comparison table
Feature🪐 OrbiterDecap CMSKeystaticTina CMSPayload CMS
StorageSQLite fileGitGit / filesGit + cloudPostgres / MongoDB
External service✓ NoneGitHub OAuth requiredGitHub / localTina Cloud (free tier)✓ None
Setupnpm install + 3 linesYAML config fileConfig fileConfig + dashboardFull backend setup
Astro support✓ Native~ Plugin✓ Native~ PluginManual
Media storageIn pod (BLOBs)External CDNExternal CDNExternal CDNDB / S3
Version history✓ Built-inGit historyGit historyGit historyCustom / code
Schema editor UI✓ YesYAML onlyConfig onlyConfig onlyCode only
Offline admin✓ YesNo~ Local onlyNo✓ Yes
Backupcp content.podgit pushgit pushTina Cloud + gitDB dump
Serverless deploy✓ Git sync mode✓ Git-native✓ Git-native✓ Git-nativeDB required
LicenseMIT freeMIT freeMIT freeMIT + paid tiersMIT free
Multilingual (i18n)✓ Locale columnNo~ ManualNo✓ Built-in
Scheduled publishing✓ Built-inNoNoNo~ Plugin

Pricing

Orbiter is open source under the MIT License — free for personal and commercial use, forever. If it saves you time, consider supporting its development.

Open Source
Free forever
$0/ always
⚖ MIT License
  • Full source code on GitHub
  • Commercial use allowed
  • Modify and distribute freely
  • No attribution required
  • Self-hosted — your data, your server
  • All features included, no paywalls
  • Community support via GitHub Issues
Support
Buy us a coffee
☕one-time or recurring

Orbiter is free and stays free. If it saves you time or earns you money, consider supporting ongoing development — new features, bug fixes, and long-term maintenance.

  • Same MIT License (still free)
  • Help fund active development
  • Prioritized GitHub issue responses
  • Mention in README supporters list
  • Via Polar — any amount appreciated
Support Orbiter ☕
No account needed · secure payment via Polar

Frequently asked questions

Everything you need to know before getting started.

A POD is a standard SQLite database with a .pod extension. It contains all your content, media, users, and settings in one file. You can open it with any SQLite tool (TablePlus, DB Browser for SQLite, DBeaver) and inspect or query your content directly.
No. SQLite runs in-process alongside your Astro server. Nothing to provision, nothing to pay for, nothing to configure separately. The database is the file.
Yes, with a note: serverless platforms don't persist filesystem writes between function invocations. Your content is available at build time for static generation, but for editing you need a persistent Node.js server (VPS, Railway, Coolify). Netlify/Vercel are great for hosting the frontend — run the Orbiter admin on a persistent server.
cp content.pod backup.pod. That's it. Every entry, every media file, every schema definition, every user account — in one file. Schedule a cron job, sync to S3, commit it to git. Standard file tooling works.
Orbiter supports multiple users with admin and editor roles. Two people editing the same entry simultaneously uses last-write-wins semantics. Fine for teams of 1–5 people, not designed for large editorial teams editing in parallel.
GET /orbiter/api/[collection] returns all published entries as JSON. Supports optional Bearer token authentication. Works from any frontend, mobile app, or external service without extra setup.
Yes — @a83/orbiter-mcp is an MCP (Model Context Protocol) server exposing list_collections, get_entries, get_entry, and search_content tools. Run it via stdio for local tools like Claude Desktop, or --http for remote access, using the same API-key and collection-scoping rules as the Public Content API.
Yes. Export your WordPress site as WXR (the standard WordPress XML export) and import it via the Orbiter admin. Text content, post dates, and categories are converted. HTML body text is transformed to Markdown automatically.
The Astro integration works with any output mode — it only provides orbiter:collections at build time. The admin runs as a separate server (@a83/orbiter-admin) independently of your Astro output mode.
Yes. Open content.pod with any SQLite GUI — TablePlus, DB Browser for SQLite, DBeaver, or the sqlite3 CLI. Tables are _collections, _entries, _media, _users, _sessions, and _versions.
Orbiter is at v0.3.8x — published to npm, actively maintained, and used in real projects. The API may evolve before v1.0. It's suitable for personal sites, client projects, and small teams. Check the GitHub issues for anything relevant to your use case.
Through GitHub's private vulnerability reporting — opens a draft advisory only the maintainer can see, with a CVE request built in once a fix ships. See SECURITY.md for details. Please don't open a public issue for a vulnerability.
MIT License. Use it for any project including commercial ones. Modify it, fork it, distribute it. No attribution required (though appreciated). The source is on GitHub and stays open source.

What's new

The latest releases. Full changelog → Subscribe: Atom · JSON Feed

Oct
2026
admin@0.3.88 · core@0.3.21 · mcp@0.1.5 · integration@0.3.22 · client@0.1.4 · cli@0.3.15 — Latest
Two-factor sign-in, signed webhooks, key limits, version diff and media usage
  • 2FA (TOTP) — turn it on under Account with any authenticator app. Eight one-time recovery codes, codes can't be replayed, and an admin can reset a locked-out user. Docs →
  • Active sessions — see every signed-in device (browser, IP, time) and sign out one or all others.
  • API key limits — restrict a key to collections, give it an expiry date or a requests-per-minute limit. Applies to the REST API and MCP. A new dialog replaces the prompt chain.
  • Editor layout — custom fields now live in a collapsible “Details” card in the main column (grouped, two per row, long inputs full width; remembers open/closed per collection) instead of small boxes in the sidebar, so the body stays the main content. Collections without a body field drop the block-editing tools. Also fixed: validation errors on publish were never shown, the long dock popups in Station mode (many collections / tools) now scroll instead of running off the screen, and the Schema page can be scrolled in Station mode again.
  • Webhook recipes — tested receiver plus copy-paste handlers: Slack/Telegram on review, IndexNow, Cloudflare purge, Mastodon. Docs →
  • AI translation of missing locales — one click in the editor creates the missing language versions as drafts (never overwrites, never publishes). Docs →
  • Image variants + focal point — /orbiter/media/<id>?w=800&fmt=webp&ar=16:9 serves a resized, re-encoded or cropped version; crops keep the focal point you set in the media library. Bounded and cached. Docs →
  • Review workflow — optional. Editors submit entries for review; admins and the new reviewer role approve or request changes. Enforced on every publishing route. Docs →
  • Preview links — the editor's Preview button now uses a one-hour token bound to that entry instead of the master preview token (which also fixes previews for editors, who only got a masked token before).
  • Version diff — see field by field what a restore would change. Restoring now keeps the content it replaces, so a restore can be undone (previously the replaced content was lost, and the newest snapshot couldn't be restored at all).
  • Media usage — each file shows where it is used; filter Unused files and Broken refs; deleting a file that is in use warns first.
  • Signed webhooks — HMAC-SHA256 signatures, retries (5 s, 30 s, 5 min) and a delivery log, managed in Settings. Webhook URLs are now admin-only (editors could previously set them). Docs →
Oct
2026
admin@0.3.87 · core@0.3.20 · mcp@0.1.4 · cli@0.3.14
Security check, encrypted secrets, draft-only agent keys, Terminal theme
  • orbiter doctor + dashboard card — flags a pod tracked by git, plaintext credentials, an open Content API and more, with the fix next to each finding. Docs →
  • Encrypted secrets — set ORBITER_SECRET and stored FTP/SMTP/AI/GitHub/S3 credentials are encrypted at rest (AES-256-GCM). Opt-in; nothing changes without it.
  • Draft-only keys for agents — an API key can be allowed to create and edit drafts over MCP. It can never publish or touch live entries.
  • Terminal theme — a fourth palette: amber phosphor on near-black, with a warm paper light variant.
  • Admin polish — Settings style cards show their active state, the style default matches the app, leaving the XFCE dock reloads cleanly, visible keyboard focus, and reduced-motion support.
Oct
2026
admin@0.3.86 · core@0.3.19 · integration@0.3.21 · mcp@0.1.3
Security follow-up: uploaded files, URL imports, login limits, and what gets pushed to GitHub

A second pass over the admin and core packages after the previous release. Update @a83/orbiter-admin, @a83/orbiter-core and @a83/orbiter-integration together — the new media headers live in core.

  • GitHub push no longer ships secrets — the GitHub push feature committed the whole .pod, including live session tokens, password hashes and stored credentials (FTP, SMTP, AI and GitHub tokens). It now pushes a scrubbed copy. If you pushed before, rotate those credentials and check your repo history.
  • Uploaded files can't run script — media is served with nosniff and a sandboxing CSP, and anything that isn't an image, video, audio or PDF is forced to download. Applies to the admin and the public /orbiter/media route.
  • Server-side request forgery — importing or linking media by URL could be pointed at internal addresses (localhost, private networks, cloud metadata). Private and reserved targets are now blocked, redirects re-checked, downloads capped at 50 MB. Set ORBITER_ALLOW_PRIVATE_FETCH=1 if you need to import from your LAN in development.
  • Login rate limit — it trusted a client-supplied X-Forwarded-For header, so it could be bypassed. The header is now only honoured when the connection comes from a reverse proxy on a private address.
  • Restricted editors — AI suggestions, the collection list/detail, /api/info and the quality report no longer expose collections an editor isn't allowed to see. Form-builder configs are admin-only.
  • Content API drafts — with the API enabled but no token set, ?status=draft on /orbiter/api/[collection] returned unpublished entries to anyone. Drafts now require a configured, matching token.
  • API token hashed — the optional single api.token is now stored as a SHA-256 hash like API keys (existing plaintext values keep working and migrate on first use).
  • Desktop app — the embedded server only listens on loopback (it was reachable from your LAN), the window is sandboxed, only http(s) links are handed to the OS, and navigation away from the local admin is blocked.
  • Smaller fixes — CSV export works again and neutralises spreadsheet formulas, the login no longer reveals which usernames exist through timing, WordPress media import is covered by the same SSRF protection, and /health no longer exposes the pod path.
  • Sessions and public endpoints — changing a password signs out all other sessions. The public form and analytics endpoints are rate-limited and size-capped, and notification mails are capped. The Content API token is compared in constant time.

All releases →

Up and running in under 2 minutes.

One command scaffolds a new project with demo content — admin at localhost:4322, login with admin / admin.

New project
npx @a83/orbiter-cli init my-site
or try the full demo repo
git clone https://github.com/aeon022/orbiter.git
cd orbiter && npm install && npm run seed
ORBITER_POD=$(pwd)/apps/demo/demo.pod npm run dev --workspace=packages/admin
Like what you see?
Orbiter is free and open source. If it saves you time, consider supporting its development.
Support Orbiter ☕
Built with Orbiter
Built by
Abteilung83

Advanced Web Architecture & Digital Systems Engineering — Less Noise. Nice Data. No Bloat.

abteilung83.at →
Where we're going

One content source.
Two audiences.

The web is splitting — humans read stories, AI agents read structure. Orbiter is building for both with Dual Render: one POD, one build, two layers. Content for people and machines from a single source.