Real-time interactive presentations and polls — a Mentimeter clone built on RedwoodSDK + Cloudflare Workers.
Live demo: https://livespark.shortcircuit.workers.dev
- 🚀 Create presentations with multiple slide types
- 📊 Multiple Choice — animated live bar chart
- ⭐ Rating — 1–5 stars with average score
- ☁️ Word Cloud — frequency-weighted word display
- 💬 Open Text — live scrolling response feed
- 🔴 Real-time sync — all clients update instantly via
useSyncedState - 📱 Mobile-friendly — audience joins by 6-character code
- 🔢 Live audience count on the host panel
| Layer | Technology |
|---|---|
| Framework | RedwoodSDK (React Server Components) |
| Runtime | Cloudflare Workers |
| Real-time | Cloudflare Durable Objects + useSyncedState |
| Styling | Vanilla CSS (dark glassmorphism design system) |
| Language | TypeScript + React 19 |
Real-time state is powered by rwsdk's built-in useSyncedState hook — a drop-in replacement for useState that synchronises across all connected clients in the same session room via Cloudflare Durable Objects:
const [state, setState] = useSyncedState<SessionState>(initial, "sessionState", sessionId);When the host navigates slides or an audience member votes, every connected browser updates instantly — no WebSocket boilerplate required.
- Node.js 18+
- pnpm 10+
- A Cloudflare account (free plan works)
git clone https://github.com/your-username/livespark
cd livespark
pnpm install
pnpm devOpen http://localhost:5173 in your browser.
pnpm releaseOn first deploy,
rw-scripts ensure-deploy-envwill guide you through Cloudflare account setup.
src/
├── worker.tsx # Worker entry: routes + syncedStateRoutes
├── client.tsx # Client entry point
├── durableObjects/
│ └── SessionDO.ts # TypeScript types for session state
├── app/
│ ├── document.tsx # HTML shell
│ ├── db/
│ │ └── store.ts # In-memory session store
│ └── pages/
│ ├── home.tsx # Landing page + slide builder
│ ├── host.tsx # Host control panel (live charts)
│ ├── audience.tsx # Audience voting UI
│ └── results.tsx # Final results view
public/
└── global.css # Design system (edit this for styles)
- Host opens the app → clicks Create Presentation
- Adds slides (Multiple Choice, Rating, Word Cloud, Open Text) → Start Session
- A unique 6-character join code and link are displayed
- Audience enters the code or opens the join link on their phone
- Votes are cast → bar charts update live on the host screen
- Host navigates Prev / Next → audience view advances in real time
- End Session → shareable results page at
/results/:sessionId
- Sessions are stored in-memory in the Worker — they reset on Worker restart. Swap
src/app/db/store.tsfor Cloudflare D1 for persistence. - Audience count decrements on graceful navigation away; abrupt tab closes may lag until the DO connection times out.
MIT