TownHall
July 14, 2026 · View on GitHub
TownHall is a live audience Q&A app ("Slido-lite"): anyone can create a town hall (a room) and becomes its owner; participants post questions and upvote others' questions; the question list sorts by votes, and a trending panel highlights questions gaining votes right now. Owners moderate — resolve or delete questions, start/stop the session. Participants also continuously signal their mood on a 5-emoji scale, visualized as a big generated SVG face plus a distribution chart.
The app exists to compare real-time frameworks: the same app will be implemented several times (.NET + Fusion, plain .NET, .NET + SignalR, possibly TypeScript and Elixir stacks) to measure the code delta each framework produces. The Fusion-based version is implemented first; the other versions will be derived from it later. It's a Blazor app (WebAssembly + Server-Side Blazor) similar to the TodoApp from Fusion Samples.
See docs/TownHall-Phase1.md for the Phase 1 spec — the Fusion-based implementation, where every view updates in real time via Fusion's compute services and invalidation.
Framework versions
Each framework implementation lives on its own branch, named after the stack:
main— .NET + Fusion. Implemented first; the other versions are derived from it.signalr— .NET + SignalR, with no Fusion at all. Next up.
More branches (plain .NET, and possibly TypeScript and Elixir stacks) will be added to this list as they're built.
Version tags like <branch>-v1 (e.g. main-v1, signalr-v1) mark
feature-equivalent snapshots across the branches, so the same -v1 on any
branch is directly comparable. They're fixed tags — never moved.
The app is generated and kept updated with Claude Code. The full interaction log — every user prompt, with Claude's responses summarized to a bare minimum — lives in docs/ai-sessions/.
How to run
The app stores its data in PostgreSQL, so start one first — the repo's
docker-compose.yml provides it (on localhost:5432,
login postgres, password postgres):
docker compose up -d
dotnet run --project src/TownHall.Host
Then open http://localhost:5136. The app creates the townhall
database on first run by applying EF Core migrations from
src/TownHall.Db/Migrations. Tests (dotnet test) need the same Postgres;
they cover every API method twice — once against the server DI container,
once over Fusion RPC against a test host on a random port.
Try it
- Open http://localhost:5136 in two separate browser windows (W1, W2) — each gets its own generated name (sessions are per tab).
- In W1, create a town hall and enter it; you'll see the owner bar. Copy the participant link and open it in W2.
- W1 presses Start — W2 sees the room go Live within a second, no refresh.
- Post a question in W2, vote on it in W1: the lists, vote counts, and the Trending panel update everywhere in real time.
- Click mood emojis in both windows — the SVG face and the distribution chart follow the average instantly; close W2 and watch its mood drop out of the aggregate within ~30 s.
- In W1, resolve the question with a note (it moves to the Resolved tab) or delete it; toggle Private to hide the room from the home-page list.
- Paste the owner link (from the owner bar) into a third window to hand moderation rights to another session.
Related repositories
- ActualLab.Fusion — the real-time state synchronization framework this sample is built to showcase
- ActualLab.Fusion.Samples — other Fusion samples, including the TodoApp this app's structure follows