A modern, lightweight CMS built with FastHTML and SQLite
Project description
FastCMS
A modern, lightweight content management system built with FastHTML and SQLite. Inspired by Wagtail, reimagined for simplicity and speed.
Built by Predictive Labs Ltd
Features
- Page Tree — Hierarchical page management with drag-and-drop reordering
- Rich Text Editing — WYSIWYG editor with image and link embedding
- StreamField-style Blocks — Composable content blocks (text, image, embed, table, code)
- Media Library — Image and document management with collections and tagging
- User Management — Role-based access control (Admin, Editor, Moderator)
- Full-Text Search — SQLite FTS5 powered search across all content
- Revision History — Full version control with diff and restore
- Draft/Publish Workflow — Draft, review, schedule, and publish content
- Snippets — Reusable content fragments manageable from the admin
- Dynamic Forms — Build forms in the admin, collect submissions, export CSV
- JSON API — Headless CMS capability with RESTful endpoints
- Multi-Site Support — Serve multiple sites from a single instance
- Live Preview — See changes before publishing
- SQLite Embedded Storage — Zero-config database, no external dependencies
- HTMX-Powered Admin — Fast, SPA-like admin experience with server-side rendering
Quick Start
Prerequisites
- Python 3.10+
- pip
Installation
# Clone the repository
git clone https://github.com/predictivelabs/FastCMS.git
cd FastCMS
# Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
# Install dependencies
pip install -r requirements.txt
First Run
# Initialize the database and create an admin user
python setup.py
# Start the server
python main.py
The app will be running at http://localhost:5001.
- Public site: http://localhost:5001/
- Admin panel: http://localhost:5001/admin/
- API: http://localhost:5001/api/v1/pages/
Default admin credentials (set during setup.py):
- Email:
admin@example.com - Password:
admin(change immediately in production)
Configuration
Environment variables (set in .env):
# Server
HOST=0.0.0.0
PORT=5001
# Database
DATABASE_PATH=data/fastcms.db
# Security
SECRET_KEY=change-me-to-a-random-string
SESSION_COOKIE=fastcms_session
# Media
MEDIA_PATH=media/
MAX_UPLOAD_SIZE_MB=10
# Site
SITE_NAME=FastCMS
DEFAULT_LOCALE=en
Project Structure
FastCMS/
├── main.py # Application entry point
├── setup.py # Database init and admin user creation
├── requirements.txt # Python dependencies
├── .env # Environment configuration
├── data/
│ └── fastcms.db # SQLite database (created on first run)
├── media/ # Uploaded images and documents
├── static/ # CSS, JS, and static assets
│ ├── css/
│ ├── js/
│ └── img/
├── app/
│ ├── __init__.py
│ ├── db.py # Database models and schema
│ ├── auth.py # Authentication and authorization
│ ├── pages.py # Page tree and content management
│ ├── blocks.py # StreamField block system
│ ├── media.py # Image and document management
│ ├── search.py # Full-text search (FTS5)
│ ├── snippets.py # Reusable content snippets
│ ├── forms.py # Dynamic form builder
│ ├── api.py # JSON API endpoints
│ ├── settings.py # Site settings management
│ ├── workflows.py # Draft/publish/review workflow
│ └── components.py # Shared FastHTML UI components
├── admin/
│ ├── __init__.py
│ ├── routes.py # Admin route definitions
│ ├── dashboard.py # Admin dashboard
│ ├── page_editor.py # Page create/edit views
│ ├── page_explorer.py # Page tree browser
│ ├── media_library.py # Image/document manager
│ ├── user_manager.py # User administration
│ ├── snippet_editor.py # Snippet management
│ └── components.py # Admin UI components (sidebar, panels, choosers)
└── templates/ # Email templates and other text templates
Dependencies
| Package | Purpose |
|---|---|
python-fasthtml |
Web framework (Starlette + HTMX + FastTags) |
fastlite |
SQLite ORM with MiniDataAPI |
python-multipart |
File upload handling |
pillow |
Image processing and thumbnails |
python-dotenv |
Environment variable loading |
bcrypt |
Password hashing |
itsdangerous |
Signed tokens for previews and password resets |
Development
# Run with live reload (development mode)
python main.py --reload
# Run tests
python -m pytest tests/
# Reset database
rm data/fastcms.db && python setup.py
Deployment
FastCMS runs as a single Python process with an embedded SQLite database. No external services required.
# Production
pip install -r requirements.txt
python setup.py
python main.py
For production, set SECRET_KEY to a strong random value and configure a reverse proxy (nginx/caddy) in front of uvicorn.
Demo
Try the live demo at fastcms.predictivelabs.ai
License
MIT License — see LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fasthtml_cms-0.1.0.tar.gz.
File metadata
- Download URL: fasthtml_cms-0.1.0.tar.gz
- Upload date:
- Size: 8.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
32ce6feef827ed6ab1c53d484107b1b8949ea9c2530b725fdaccc02083b5136c
|
|
| MD5 |
cfe35dc2ebe7192a0d3e3abe5ec1224a
|
|
| BLAKE2b-256 |
a49e33381e188338f8511130c9d7886c50998809f2c6a1717af9838791d4916f
|
File details
Details for the file fasthtml_cms-0.1.0-py3-none-any.whl.
File metadata
- Download URL: fasthtml_cms-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
be7e2a15b665b1490fd5fc3d8ad72771210165fbdc78ade02c948da3e69162dc
|
|
| MD5 |
c3e27746b8e64d8451cd88aebeffe9a3
|
|
| BLAKE2b-256 |
2d5853159b101822c963fe7cf13d31bd5e3b7bdc75284b539647f632f399b1e8
|