Quick start
Lumen runs as a single Cloudflare Worker that serves both the API and the React SPA, plus an email() handler bound to Cloudflare Email Routing.
One Lumen, one team
A Lumen install serves exactly one Prism team. Owners and co-owners of that team can manage app config and assign mailbox addresses to members. Members cannot self-assign addresses.
Prerequisites
- A Cloudflare account with Workers Paid plan.
- A custom domain hosted on Cloudflare with Email Routing enabled.
- A running Prism instance (or
prism.siiway.org) with an OAuth application created for Lumen. - Bun ≥ 1.3 and wrangler.
1. Install
git clone https://github.com/siiway/lumen.git
cd lumen
bun install2. Provision Cloudflare resources
bunx wrangler d1 create lumen-db
bunx wrangler kv namespace create lumen-kv
# Optional. Skip if you don't want raw .eml + attachment storage.
bunx wrangler r2 bucket create lumen-mailEdit wrangler.jsonc and paste the IDs into d1_databases[0].database_id and kv_namespaces[0].id. If you don't want R2, remove the r2_buckets block — the InitPage's "Enable R2" toggle is off by default.
3. Run locally
bun run devOpen http://localhost:5173. You'll land on the InitPage. The flow is two-phase:
- Operator fills in OAuth + storage settings. Lumen stages the config and runs the schema, but does NOT mark itself configured.
- Operator signs in via Prism. Lumen verifies they are the owner of the configured team, then flips
init:configuredand goes live.
If the wrong account signs in during phase 2, Lumen refuses to complete init. The same Prism callback also enforces team membership for everyday sign-ins after init is complete.
4. Configure Email Routing
In the Cloudflare dashboard:
- Email Routing → Routes →
Custom address,Send to a Workerpointing atlumen. - Repeat for each address you want to deliver to Lumen, or set a Catch-all to the same Worker.
- After someone has signed into Lumen at least once, an owner/co-owner can go to Settings → App admin → Addresses and assign that address to a member. Members can't self-assign — they only see their assigned addresses under Settings → Addresses.
5. Deploy
bun run deployFirst deploy
Once deployed, immediately complete the InitPage. Until you do, anyone who hits the public URL can stage a config (the OAuth flow then prevents them from completing — but it's still better to lock this down quickly).