A free, open-source, self-hosted backend platform for students, hobbyists, and indie developers building projects with fewer than ~100 users. No paid tiers. No hosted database bills. You own your data.
Platforms like Supabase and Firebase are excellent — until you cross a free-tier limit on a college project that will never have more than a handful of users. This project exists so that a student can spin up a real backend (database, auth, storage, API) in minutes, run it on their own laptop or a free-tier VM, and never think about a pricing page.
- SQLite as the storage engine — a single embedded database file, zero hosting cost, ACID-compliant, SQL-native. WAL mode handles concurrent access safely out of the box.
- CLI-first workflow — init a project, manage schema/migrations, and connect frameworks from the terminal.
- Dashboard (Web App / PWA) — a Supabase-style visual layer: table explorer, SQL editor, auth management, storage, logs, and settings.
- REST API — auto-generated from your schema, so any framework can talk to your backend with plain HTTP calls. No mandatory SDK.
- Official Python client —
pip install pyronitesfor a Supabase-style API against your backend. - PostgreSQL compatibility as a future goal — SQLite today, with a clear migration path once a project outgrows single-node scale.
Students, beginners, and indie developers building personal or college projects — not production apps expecting thousands of concurrent users. If your project outgrows ~100 users or needs multi-region availability, this project's docs will point you toward migrating to Postgres.
MVP complete (Phases 1–4). Python client published on PyPI.
| Phase | Scope | Status |
|---|---|---|
| 1 | Core backend (SQLite, auth, dynamic REST, API keys) | Done |
| 2 | Dashboard (tables, SQL editor, users, keys, logs) | Done |
| 3 | File storage + scheduled backups | Done |
| 4 | Docker + free-tier deploy (Render / Fly / Vercel) | Done |
| Client | Official pyronites package on PyPI |
Done |
See docs/PLAN.md for the full roadmap and docs/ARCHITECTURE.md for technical design.
Install from PyPI:
pip install pyronitesConfigure:
export PYRONITES_URL="https://your-backend.example.com" # or http://localhost:8000
export PYRONITES_KEY="pyro_live_..." # from the dashboard API Keys pageMinimal usage:
from pyronites import create_client
client = create_client()
# Tables
note = client.table("notes").insert({"title": "Hello", "body": "World"})
for row in client.table("notes").select().limit(10):
print(row)
client.table("notes").update({"title": "Updated"}).eq("id", note["id"])
client.table("notes").delete().eq("id", note["id"])
# Auth (optional)
client.auth.sign_in("user@example.com", "password")
print(client.auth.user())
# Storage
meta = client.storage.upload("photo.jpg")
data = client.storage.download(meta["id"])
# Optional local / cache tables
client = create_client(
local_tables=["settings"],
cache_tables=["catalog"],
local_db_path="./.pyronites_local.db",
)Package docs and API contract: pyronites/README.md and pyronites/docs/syntax.md.
PyPI: https://pypi.org/project/pyronites/
Prerequisites: Python 3.11+, Node 18+ (for the dashboard).
git clone https://github.com/Ashutosh3021/Pyronites.git
cd Pyronites
# Install
pip install -e ".[dev]"
# Start the API (creates pyrocore.db + runs migrations automatically)
python -m uvicorn backend.app:app --host 0.0.0.0 --port 8000Open http://localhost:8000/health — you should see {"status":"ok","database":true}.
cd frontend
npm install # or pnpm install
npm run devOpen http://localhost:3000 → sign up → create a table → start building.
Option A — Python client (recommended)
pip install pyronites
export PYRONITES_URL="http://localhost:8000"
export PYRONITES_KEY="pyro_live_..."from pyronites import create_client
client = create_client()
print(list(client.table("your_table").select().limit(10)))Option B — plain HTTP
curl -H "Authorization: Bearer pyro_live_..." \
http://localhost:8000/tables/your_tablecp .env.example .env
docker compose up --buildAPI: http://localhost:8000 — data lives in the pyrocore-data volume.
Full guide: docs/DEPLOY.md
Short version:
-
Backend → Render
Connect the repo as a Blueprint (render.yaml). SetFRONTEND_ORIGIN, cookie env vars, and optionallyS3_*for free-tier persistence. -
Frontend → Vercel
Import the repo, setNEXT_PUBLIC_API_URLto your Render URL, deploy. -
Open the Vercel URL, sign up, and use the dashboard.
For real (non-demo) data on free tier, enable S3/R2 sync (see docs/DEPLOY.md §10.1). On a paid Render plan, just attach a disk at /data.
| Component | Description |
|---|---|
| Python client | pip install pyronites — tables, auth, storage, local/cache policy |
| CLI / Python package | Create/manage projects, schema & migrations, connect apps |
| Dashboard | Table explorer, SQL editor, auth, API keys, storage, logs, settings |
| Core engine | SQLite (WAL) + REST API + session auth + file storage + backups |
- Don't rebuild solved problems. Password hashing (argon2), SQL (SQLite), containers (Docker).
- Zero cost by default. No paid service required for the MVP.
- Data ownership. Your data is a file you control.
- Honest tradeoffs. Single-node. Docs say when to migrate to Postgres.
- Simple now, extensible later.
Open source (license TBD — MIT or Apache 2.0 recommended).
Running into "429 Too Many Requests" errors? Here's what's happening and what you can do about it, in plain language.
Your PyroCore backend is probably hosted on a free-tier service (like Render's free plan). These free tiers put a strict limit on how many requests your backend can handle per minute. When your app — or even just a single page load — sends a burst of requests at once (like checking auth, loading tables, and syncing data all at the same time), the hosting service temporarily blocks further requests and returns a 429 error.
-
Upgrade your hosting plan. The simplest and most reliable fix. Free tiers are great for testing, but they aren't built for real traffic. A basic paid plan on Render, Fly.io, or any VPS will remove these limits entirely.
-
Avoid firing too many requests at once. If you're building a frontend app, don't load everything simultaneously. For example, wait for auth to finish before you start fetching table data. The official
pyronitesPython client now automatically handles rate-limit retries and deduplicates identical requests, so upgrading to the latest version helps a lot. -
Use local / cache tables. If you have data that doesn't need to be perfectly fresh every time, configure tables as
cache_tablesorlocal_tablesin the Python client. This keeps a copy on the user's device and only hits the remote backend occasionally, drastically cutting down on requests. -
Don't poll the same endpoint repeatedly. Calling
client.auth.user()over and over in a tight loop will hammer the/auth/meendpoint. The client now caches this for a short window, but it's still good practice to call it only when you actually need to check auth status. -
Combine or batch requests when you can. If your app needs several pieces of data, try to fetch them in fewer, bigger requests rather than many tiny ones.
The bottom line: 429 errors are a hosting quota issue, not a bug in PyroCore. The code changes we've made help your app play nicer with rate limits, but a paid hosting plan is the real fix for production use.
Core is stable enough for outside contributions. Open an issue or PR.
