A hosted, multi-user release registry for lode, built on the bun-tpl template.
Status: implemented, not yet deployed. The registry API, read feed, web UI and publisher tooling are in place (milestones M0–M5 of docs/plan/20261009-2241-lode-registry-server.md); the first Cloudflare deployment and its on-edge checks are the owner steps listed in docs/develop/deployment.md. What ships today:
- API — Hono on Bun, SQLite via Drizzle, optional ECIES at-rest encryption.
- Web — React 19 + TanStack Router + Tailwind v4, file-based routes, dual EN/ZH i18n.
- Registry — per-user namespaces, packages with channels and draft → publish releases, streamed and multipart uploads to R2, optional ed25519 signatures, per-package token grants, quotas, admin controls, and the
/rfeed lode reads. Seedocs/modules/registry.mdanddocs/guides/. - Modules — account/auth (OAuth + TOTP), groups, Zanzibar relation tuples,
itembase +filestorage, cron, settings, audit logs, encryption admin, JSON backup. - Build — lode-compatible release asset (
index.js+ SPA + migrations) viascripts/package.ts; self-updates under the lode supervisor.
bun install
cp .env.example .env # uncomment the "Bundled dex IdP" block
bun run dev:all # starts dex + web + api in one process groupOpen the URL printed by bun run dev:all (e.g. http://lode-server.localhost:3355). Sign in with admin@example.com / admin — the bundled dex's static user. That login is an admin because it matches DEFAULT_ADMIN.
Already have an OAuth/OIDC provider? Point OAUTH_ISSUER at it in .env and use bun run dev instead — dev:all detects an external issuer and bows out so it doesn't fight your IdP.
After bun run dev:all has run, data/ contains the SQLite DB, uploaded blobs, and the OIDC discovery cache. To start over (e.g. after experimenting with DB_ENCRYPTION=true and forgetting the master password):
bun run clean # build artefacts only (dist/, .vite/, .tanstack/, coverage/)
bun run clean:all # also wipes data/ — DB, uploads, logs, oidc cacheclean:all is destructive; uncommitted local data is gone. Use it on a fresh clone or after intentionally tearing down a local experiment.
DB_ENCRYPTION defaults to false in dev — bun run dev:all lands you on login directly. If you enable encryption (recommended for production deploys), the first boot adds:
- Visit
/<base>/setup. - Paste the bootstrap token. It is auto-generated at every boot and surfaced via stderr /
<data dir>/bootstrap-token.txtwhile the system is in setup mode; both go away once init succeeds. - Choose a master password — this derives the master keypair that wraps the data-encryption key (DEK).
- Save the recovery key file (
<APP_NAME>-master-key.txt). - Sign in via OAuth. Any login matching
DEFAULT_ADMINis an admin.
- Identity — set
APP_NAME(slug) andAPP_DISPLAY_NAMEin.env. HTML title, TOTP issuer, backup filename, and sessionStorage namespace derive from these.BASE_PATHis unset by default (root mount); set it to serve under a URL prefix. Seedocs/develop/forking.md. - Modules — the shipped set is listed in
docs/modules/. To add one, followdocs/develop/module/playbook.md(10-step checklist) with starter files indocs/develop/module/recipe.md. - Logo — replace
apps/web/public/logo.svgand the inline SVG inapps/web/src/shared/components/logo.tsx.
bun run dev # Vite dev server (web + API via @hono/vite-dev-server)
bun run dev:all # dev + bundled dex IdP, one process group
bun run dev:dex # just the bundled dex IdP (use when running dev in another terminal)
bun run rebrand # rewrite manifests + .env defaults for a fork
bun run build # Build all packages
bun run lint # ESLint
bun run typecheck # tsc --noEmit
bun run test # Unit tests (bun:test + vitest)
bun run test:e2e # Live e2e: dex + API + encrypted DB + every module
bun run check # lint + typecheck + test + build + check:i18n + check:env-docs + check:api-docs
bun run gen:env-docs # regenerate docs/reference/env-reference.md from the zod schema + .env.example
bun run gen:api-docs # regenerate docs/reference/api-routes.md from the in-process Hono routes
bun run package # Build the lode release asset (dist/<app>-<os>-<arch>.tar.gz + manifest.json + checksums.txt)
bun run clean # Remove build artifactsapps/api/ Hono API; Drizzle schema lives per-module
apps/web/ React 19 SPA (TanStack Router file-based)
packages/shared/ ECIES utilities used by both api and web
packages/tsconfig/ Shared TS config
docs/ Architecture, module standards, deployment, rebranding
tests/e2e/ Live e2e harness (dex + API)
scripts/ dev-all / dev-dex / rebrand / package / clean / hash-password
/ check-i18n / i18n:unused / i18n:clean / gen-env-docs
docs/README.md— documentation indexdocs/architecture.md— runtime shapedocs/develop/module/standards.md— adding a moduledocs/develop/forking.md— rebranding checklist inherited from the templatedocs/guides/publisher.md— publishing a package from CIdocs/guides/operator.md— running an app that updates from the registrydocs/develop/deployment.md— production deployment + upgrade, Cloudflare Workersdocs/develop/operations.md— runbook (logrotate, backup, restore, known issues)docs/develop/forking.md— merging upstream template changesdocs/plan/20261009-2241-lode-registry-server.md— registry plandocs/modules/— per-module deep dives