Important
MantisBase is being reworked in Rust. This repository is the active rewrite. Behaviour and APIs may differ from earlier C++ releases, and feature parity is not guaranteed yet—some capabilities described in older marketing or in doc/ may be planned, partial, or unchanged only on legacy binaries. Treat this notice as authoritative until it is removed.
A lightweight Backend-as-a-Service (BaaS) in Rust — single binary, schemas, REST, and an admin UI
Local libSQL by default; Turso and PostgreSQL are included in the binary and chosen at runtime (--db).
MantisBase is a small backend you run yourself: define entity schemas, get JSON REST routes, enforce access rules, serve the admin dashboard under /mb, and optionally register webhooks. Admin accounts live in a dedicated table; application users (JWT login) use a single central mb_user table—not a special entity type in the catalog.
The rewrite targets the same product goals as the original C++ stack (speed, embeddability, clarity) with a smaller runtime surface while features land incrementally.
- Rust (see
rust-versioninCargo.toml)
PostgreSQL is supported via the bundled sqlx client; no separate Cargo feature is required. You only need a running Postgres instance when using --db postgresql.
Native dependencies (ring, libsql-sqlite3-parser, etc.) invoke the C compiler, which often writes temporary .s files under /tmp. If that filesystem is full or over quota, you will see errors like error writing to /tmp/cc….s: Disk quota exceeded.
Point the compiler at a directory on a volume with space:
mkdir -p /path/with/quota/headroom/tmp
export TMPDIR=/path/with/quota/headroom/tmp
cargo buildOptionally also set CARGO_TARGET_DIR to a path on the same volume if your default target dir is quota-limited.
git clone https://github.com/allankoechke/mantisbase.git
cd mantisbase
cargo build --releaseBuild the admin SPA (Vite → public/mb-dist/, served at /mb/):
cd admin && npm install && npm run build && cd ..Apply migrations, create an admin, set a JWT secret for app-user login, then serve:
./target/release/mantisbase migrations up
./target/release/mantisbase admins add admin@example.com 'your-admin-password'
export MB_JWT_SECRET='a-long-random-secret-for-user-jwt'
./target/release/mantisbase serveDefaults:
- API:
http://127.0.0.1:7070/api/v1/ - Admin UI:
http://127.0.0.1:7070/mb/— compiled assets from./public/mb-dist(override with--admin-ui-dirorMB_ADMIN_UI_DIR). Use HTTP Basic in the browser where the UI calls the API.
OpenAPI for the running shape of the API: GET /api/v1/openapi.json.
With admin Basic auth: GET /api/v1/admins lists { "admins": [ { "id", "email" }, … ] }; POST /api/v1/admins with {"email":"…","password":"…"} creates another admin; DELETE /api/v1/admins/{id-or-email} removes one (URL-encode the path segment). The CLI mantisbase admins … commands do the same against the database.
Admin routes expect Authorization: Basic … (email:password), not a bearer “admin token”.
curl -sS -u 'admin@example.com:your-admin-password' \
-X POST http://127.0.0.1:7070/api/v1/sys/schemas \
-H 'Content-Type: application/json' \
-d '{
"name": "posts",
"type": "base",
"fields": [
{"name": "title", "type": "string", "required": true},
{"name": "content", "type": "string"}
],
"rules": {
"list": {"mode": "public", "expr": ""},
"get": {"mode": "public", "expr": ""},
"add": {"mode": "auth", "expr": ""},
"update": {"mode": "auth", "expr": ""},
"delete": {"mode": "", "expr": ""}
}
}'Entity types (catalog): bare, base, view — there is no auth entity type; end-user sign-in is via POST /api/v1/auth/login against mb_user.
curl -sS -X POST http://127.0.0.1:7070/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"user-password"}'Response includes token (JWT) and user JSON. Use Authorization: Bearer <token> on routes whose rules require authenticated access.
Rough map for this Rust codebase (check src/http/mod.rs and OpenAPI for truth):
| Area | Status |
|---|---|
| Health, OpenAPI, CORS, request logging | Implemented |
| `GET | POST /api/v1/sys/schemas, GET |
| `GET | PATCH /api/v1/sys/configs(admin),GET /api/v1/sys/logs` (admin, stub) |
Entity row CRUD under /api/v1/entities/..., access rules |
Implemented |
| Admin users: CLI or `GET | POST /api/v1/admins, DELETE /api/v1/admins/{id}` (Basic) |
mb_user + POST /api/v1/auth/login + JWT |
Implemented |
| `GET | POST /api/v1/webhooks` (admin) |
Admin dashboard /mb/ |
Compiled Vite app (default ./public/mb-dist) |
| SSE realtime, file pipeline, refresh/logout auth routes, Duktape scripting, … | Not promised here; older doc/*.md may still describe the C++ server |
When in doubt, prefer openapi.json and this README over historical prose.
| Command | Purpose |
|---|---|
mantisbase serve |
HTTP server (--host, --port) |
mantisbase admins … |
Add, list, or remove admin users |
mantisbase migrations … |
Apply or reset SQL migrations |
Global flags include --data-dir, --admin-ui-dir (built SPA root), --dev, --db (libsql | turso | postgresql), and --db-url (or MB_DATABASE_URL). Turso typically needs MB_TURSO_AUTH_TOKEN.
| Variable | Role |
|---|---|
MB_JWT_SECRET |
Required to issue JWTs from /api/v1/auth/login |
MB_ADMIN_UI_DIR |
Directory with built admin index.html (default ./public/mb-dist) |
MB_DATABASE_URL |
DB URL when using Turso/Postgres (or pass --db-url) |
MB_TURSO_AUTH_TOKEN |
Turso auth token when --db turso |
MB_LOG_LEVEL |
trace … critical |
mantisbase/
├── src/ # Library + `mantisbase` binary (CLI, HTTP, storage)
├── admin/ # Vite + TypeScript admin UI (`npm run build` → `public/mb-dist/`)
├── migrations/ # libSQL / Turso SQL migrations
├── migrations/postgres/
├── public/mb-dist/ # Built admin bundle (served at `/mb/`; gitignored)
├── tests/
└── doc/ # Legacy / long-form guides (may predate the Rust port)
smtp— email (lettre)embed-js— experimental QuickJS embedding
Example: cargo build --release --features smtp
- API:
GET http://<host>:<port>/api/v1/openapi.json - Hosted book / site: may track releases; verify against this branch.
- Contributing: CONTRIBUTING.md
MantisBase remains under active development; breaking changes are possible while the Rust port catches up to the full prior surface.
Contributions are welcome. See CONTRIBUTING.md.
MIT License © 2026 Allan K. Koech
