Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Self-hosting

OpenSession runs as a single Cloudflare Worker with D1 (SQLite database), R2 (file storage), and the send_email binding for transactional emails. The entire stack fits within Cloudflare's free tier for most conference workloads.

Prerequisites

  • A Cloudflare account (free tier works)
  • Node.js 18+ and pnpm
  • Google OAuth credentials (for authentication)
  • A domain pointed at Cloudflare (for email sending)

Architecture

┌──────────────────────── Cloudflare Worker ────────────────────────┐ │ │ │ Spiceflow app (React Server Components) │ │ ├── Admin dashboard /org/:orgId/e/:eventId/* │ │ ├── Public CFP /submit/:eventSlug/:formSlug │ │ ├── Speaker portal /portal/:eventSlug/* │ │ ├── Embeds /embed/:eventSlug/* │ │ ├── API /api/auth/* (BetterAuth) │ │ └── Cron close forms, reminders, outbox drain │ │ │ └────────┬──────────────┬──────────────┬────────────────────────────┘ │ │ │ v v v D1 database R2 bucket send_email binding (SQLite) (files) (transactional mail)

Setup steps

    Clone the repository

    git clone https://github.com/remorses/opensession cd opensession pnpm install

    Create Cloudflare resources

    Create a D1 database and R2 bucket in your Cloudflare dashboard or via Wrangler:
    cd website npx wrangler d1 create opensession-db npx wrangler r2 bucket create opensession-files
    Update wrangler.jsonc with your database ID.

    Configure Google OAuth

    Create OAuth credentials in the Google Cloud Console:
    1. Create a new OAuth 2.0 Client ID
    2. Set the authorized redirect URI to https://your-domain.com/api/auth/callback/google
    3. Note the Client ID and Client Secret

    Set secrets

    Store your secrets using Wrangler or your preferred secrets manager:
    npx wrangler secret put BETTER_AUTH_SECRET npx wrangler secret put GOOGLE_CLIENT_ID npx wrangler secret put GOOGLE_CLIENT_SECRET
    Set BETTER_AUTH_URL to your production domain (e.g. https://opensession.dev).

    Run migrations

    pnpm db:migrate:remote

    Deploy

    pnpm deploy

Local development

For local development, the Vite dev server runs with Miniflare (local Cloudflare runtime) on port 8788:
cd website pnpm db:migrate:local pnpm dev
Secrets for local development should be injected through your secrets manager (the project uses sigillo). Never commit .env or .dev.vars files.

Environment

ResourceProductionPreview
Workeropensession-websiteopensession-website-preview
Domainopensession.devpreview.opensession.dev
D1opensession-dbopensession-preview-db
R2opensession-filesShared
The preview environment uses a separate D1 database so test data does not affect production.

Cost

Cloudflare Workers free tier includes:
ResourceFree tier limit
Worker requests100,000 / day
D1 reads5 million / day
D1 writes100,000 / day
D1 storage5 GB
R2 storage10 GB
R2 operations10 million reads, 1 million writes / month
Email sending100 / day (on Workers Paid, higher limits)
A conference with 500 submissions, 100 accepted speakers, and 50,000 public agenda views per month fits comfortably within these limits.