Skip to content

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

sh
git clone https://github.com/siiway/lumen.git
cd lumen
bun install

2. Provision Cloudflare resources

sh
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-mail

Edit 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

sh
bun run dev

Open http://localhost:5173. You'll land on the InitPage. The flow is two-phase:

  1. Operator fills in OAuth + storage settings. Lumen stages the config and runs the schema, but does NOT mark itself configured.
  2. Operator signs in via Prism. Lumen verifies they are the owner of the configured team, then flips init:configured and 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:

  1. Email Routing → RoutesCustom address, Send to a Worker pointing at lumen.
  2. Repeat for each address you want to deliver to Lumen, or set a Catch-all to the same Worker.
  3. 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

sh
bun run deploy

First 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).