Self-hosted plugin registry. Built with Bun, Elysia, SvelteKit and Drizzle ORM.
🌐 Read in your language: English · Deutsch · Español · Français · Italiano · 中文
📚 Docs: tabularium.wiki
A directory of plugins (or any release-shipping artefact) with a web UI, an OAuth-driven submission flow, an OpenAPI surface, and a built-in CMS. Authors connect their GitHub / GitLab / Gitea account, pick a repo, and Tabularium installs the release webhook for them — every new tag becomes a release in the registry.
- 🧩 Multi-provider submission — GitHub, GitLab, Gitea, Forgejo (any instance), with manifest preview on repo select
- 🔐 Signed releases — every ingested release is hashed (SHA-256) and signed with the registry's Ed25519 key; JWKS at
/.well-known/registry-key.json. GitHub build-provenance attestations are relayed when present. - 📨 Plugin requests — users can request plugins, upvote, and claim them at
/requests(toggleable) - 🔁 Plugin transfers — owners can transfer plugin ownership between accounts from
/settings - 🌐 Multi-locale READMEs — manifest
readmes:maps locales to README paths; registry serves the matched README via?locale= - 📱 Desktop app handoff — operators can register
tabularis://-style URL schemes; the plugin detail page surfaces an "Open in App" CTA - 🏷 Plugin kinds — admin-defined taxonomy (Themes, Snippets, SQL Templates, …) with opt-in per-kind public catalogue subpages
- 🪄 Install wizard — structured DB form (host/port/user/pw + test-connection), bootstrap admin password printed to logs, auto-redirect into
/adminalready signed-in after restart - 📝 Built-in CMS — markdown pages with widgets, translations per locale
- 🎨 Branding — name, colours, logo, favicon, analytics, robots policy
- 🌍 6 UI languages — English, Deutsch, Español, Français, Italiano, 中文 — admin-configurable
- 🗄 Multi-dialect — SQLite, Postgres, or MySQL (auto-detected from
DATABASE_URL) - 🚦 Feature toggles — disable submissions or requests without a redeploy
- 🪵 Audit log — every admin mutation tracked with actor + IP + target
The fastest way to run Tabularium is via the published Docker image:
curl -O https://codeberg.org/Tabularium/Tabularium/raw/branch/main/docker-compose.example.yml
mv docker-compose.example.yml docker-compose.yml
# Generate real secrets
openssl rand -hex 32 # use for JWT_SECRET
openssl rand -hex 32 # use for TOKEN_ENC_KEY
# Edit docker-compose.yml — replace both secrets above
docker compose up -dOpen http://localhost:3000. The install wizard prints a bootstrap password to the container logs:
docker compose logs registry | grep -A2 "FIRST-RUN SETUP"Walk through the wizard, point it at the embedded SQLite path (or swap to Postgres / MySQL via DATABASE_URL), and you're done.
The minimal example uses SQLite. To use Postgres or MySQL, change DATABASE_URL in the compose env block:
- Postgres:
postgres://user:pass@host:5432/db - MySQL:
mysql://user:pass@host:3306/db
If you want to hack on Tabularium itself rather than just deploy it:
git clone https://codeberg.org/Tabularium/Tabularium
cd Tabularium
bun install
just dev # starts minikube + tilt up (postgres + dragonfly + api + frontend)Tilt UI is at http://localhost:10350; the registry is port-forwarded to http://localhost:3000 and the frontend to http://localhost:5180. Source edits hot-reload into the cluster automatically.
The bootstrap password is printed on first boot:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
FIRST-RUN SETUP
Open the registry in your browser:
http://localhost:3000/init
Sign in with these temporary credentials:
Email: admin@example.com
Password: <auto-generated-password>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
| Layer | Tech |
|---|---|
| Runtime | Bun (≥ 1.3) |
| HTTP | Elysia + TypeBox |
| DB | Drizzle ORM — sqlite / postgres-js / mysql2 |
| Cache | Bun.redis (Dragonfly-compatible) or in-memory |
| Frontend | SvelteKit (SPA) + Eden Treaty end-to-end types |
| i18n | Paraglide JS |
| Docs | Docsify — no build step |
apps/
api/ Elysia API + install wizard
frontend/ SvelteKit SPA
packages/
client/ @tabularium/client — typed Eden Treaty client (TypeScript)
manifest/ @tabularium/manifest — pure validator + integrity primitives (published on npm)
cli/ @tabularium/cli — author-side `tabularium validate` (published on npm)
tabularium-rs/ tabularium-sdk — async Rust client (published on crates.io)
tsconfig/ Shared tsconfig
deploy/ k3s manifests (image build runs in `.forgejo/workflows/docker-build.yml`)
docs/ Docsify content (integrity guides, deploy, etc.)
.forgejo/ Codeberg Forgejo Actions workflows
Full docs live at tabularium.wiki.
- 🚀 Deploy guide — Docker, env vars, reverse proxy
- 🛠 Install wizard internals
- 🔌 API reference — OpenAPI spec at
/openapi/json
Apache 2.0 — see LICENSE.
Issues and PRs welcome on Codeberg. For larger changes, open a discussion first so we can align on direction.