A lightweight, self-hosted and Git-based CMS native for Astro
Manage your content where your code lives. No database required.
A lightweight, self-hosted Content Management System that uses your GitHub repository as the content backend. No external database — your Markdown/MDX files and images live right in your repo. Built with Astro 6 and React 19, featuring server-side authentication and a Notion-inspired editing experience.
| Feature | Description |
|---|---|
| 📚 Multi-Collection | Manage multiple content types (Blog, Docs, Projects) in one workspace |
| 🏷️ Typed Templates | Define schema with String, Date, Boolean, Number, Array, Object |
| 🔍 Smart Filtering | Auto-generated filter UI based on your template types |
| 🧩 Plugin System | Slot-based WYSIWYG editor plugins (MDXEditor included) with CSS isolation |
| 🔐 Server-Side Auth | Env Auth with bcrypt — your Git token never leaves the server |
| 🔀 Multi-Tenant | One deployment, multiple repos — each user provides their own token at login |
| 🌐 i18n Ready | English and Vietnamese support |
| ⚡ Optimistic Locking | SHA-check prevents overwriting concurrent changes |
| 🚀 Self-Hosted | Deploy on any VPS, Docker, or serverless platform |
┌─────────────────────────────────────────────┐
│ Browser (React SPA) │
│ Dashboard, PostList, Images, Templates │
│ ProxyGitAdapter → /api/proxy/* │
└─────────────┬───────────────────────────────┘
│ Cookie session (HMAC-SHA256)
┌─────────────▼───────────────────────────────┐
│ Astro SSR Server (Node.js) │
│ middleware.ts → session guard │
│ /api/auth/login → bcrypt verify │
│ /api/proxy/git → GitHub API (server-side) │
│ /api/proxy/upload → file upload via API │
│ /api/proxy/blob → binary file serving │
└─────────────────────────────────────────────┘
- No client-side tokens: Git PAT stored server-side only (env or encrypted in session cookie)
- Bcrypt password hashing: 12-round bcrypt with constant-time comparison
- HMAC-SHA256 sessions: Signed cookies with HttpOnly + SameSite=Strict + Secure
- Token validation at login: Dynamic tokens are verified against GitHub API before session is created
- Rate limiting: 5 attempts per minute per IP
- Upload hardening: Path validation blocklist + file type/size limits on upload proxy
Pageel CMS features a slot-based plugin architecture for extending the editor experience.
| Package | Description | Status |
|---|---|---|
@pageel/plugin-types |
TypeScript interfaces for plugin development | ✅ Ready |
@pageel/plugin-mdx |
MDXEditor WYSIWYG editor with toolbar, image upload, debounce | ✅ Ready |
@pageel/cms |
Astro integration — auto-detect collections, inject /cms route |
✅ Ready |
Add to your .pageelrc.json:
{
"version": 2,
"plugins": {
"editor": "@pageel/plugin-mdx"
}
}| Tab | Description |
|---|---|
| ✏️ Edit | WYSIWYG editor (MDXEditor plugin) or fallback textarea |
</> Markdown |
Raw markdown editor — always available |
| 👁 Preview | Rendered HTML preview |
- Node.js >= 22.12.0
- A GitHub repository with markdown content
- A GitHub personal access token (fine-grained recommended)
git clone https://github.com/pageel/pageel-cms.git
cd pageel-cms
npm installcp .env.example .envEdit .env with your credentials:
CMS_USER=admin
CMS_PASS_HASH="$2a$12$..." # See docs/deployment.md for hash generation
CMS_SECRET=your-random-secret-min-16-chars
# Optional — if omitted, users provide these at login (Multi-Tenant mode)
GITHUB_TOKEN=ghp_your_token
CMS_REPO=username/repo💡 Two modes: Set
GITHUB_TOKEN+CMS_REPOfor a dedicated single-repo setup (Server Mode). Leave them empty to let each user provide their own token and repo at login (Connect Mode / Multi-Tenant).
npm run devOpen http://localhost:4321 — you'll be redirected to /login.
# After npm install (step 1)
npx pageel-cms hash your-password
# Or without project installed:
node -e "require('bcryptjs').hash('your-password', 12).then(h => console.log(h))"Copy the output hash to CMS_PASS_HASH in your .env file (wrap in double quotes).
npm run build
node dist/server/entry.mjsSee docs/deployment.md for VPS, Docker, and Vercel deployment guides.
| Document | Description |
|---|---|
| Setup & Auth Modes | Installation guide with detailed 3-mode configuration (Server, Connect, Open) |
| Deployment | VPS, Docker, Vercel deploy guides, env vars reference |
| Security Assessment | Auth, session, proxy security review |
| Plugin Development | TypeScript interfaces for building custom plugins |
| Product | Type | Purpose |
|---|---|---|
| Pageel CMS | OSS (MIT) | Git-native CMS for content & media |
| @pageel/plugin-mdx | OSS (MIT) | WYSIWYG editor plugin (MDXEditor) |
| @pageel/cms | OSS (MIT) | Astro integration bridge |
| Pageel Workhub | Commercial | Team workspace: workflow, review, permissions |
Pageel CMS focuses on content. For team collaboration features, see Pageel Workhub.
Contributions are welcome!
- Fork the repository
- Create feature branch (
git checkout -b feature/amazing-feature) - Commit changes (
git commit -m 'Add amazing feature') - Push to branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License. See the LICENSES.md file for details.
Made with ❄️ by Pageel
