Guild Kiosk Architecture Decision
Problem
The kiosk app (BBS terminal UI for NFC check-in, weather, events, leaderboards) lives inside the Guild monolith as a Next.js route group at (kiosk)/. As we add more ambient features (Spotify now playing, community feeds, etc.), there’s a question of whether it should be extracted into a separate service.
Approach
Decision: keep the kiosk in the monolith.
The Raspberry Pi runs a headless browser pointing at a URL. It doesn’t know or care what serves the page. This eliminates deployment divergence as a reason to split — the kiosk deploys whenever the main app deploys, same URL, same infra.
Why not split
- The coupling is thin but real. The kiosk’s core job is check-in, which calls
processCheckInvia server actions with direct DB access. Extracting would mean switching to HTTP calls to/api/check-in— possible, but adds latency and failure modes for no benefit. - Route groups already isolate it.
(kiosk)/has its own layout, styles, and component tree. No client components leak into the frontend bundle. This is the architectural boundary Next.js gives us — it’s working. - New features are lightweight. Spotify is REST calls, weather and events are already integrated. None of these add heavy dependencies that would bloat the main app’s build.
- We’re still iterating fast. The BBS design just landed (~21 commits). Premature extraction would slow iteration by adding an API contract between two apps.
When to revisit
- The kiosk pulls in heavy client-side deps (canvas libs, websocket frameworks, animation engines) that noticeably increase main app bundle size or build time
- The kiosk needs a fundamentally different rendering strategy (e.g., real-time streaming that conflicts with the main app’s caching)
- The shared code surface shrinks to just API calls — meaning the kiosk is a pure display client with no benefit from being in the monolith
Migration path (when the time comes)
Extraction cost is low because the coupling is already minimal:
- Stand up a separate Next.js app for the kiosk
- Replace server actions with HTTP calls to existing
/api/check-in - Call external APIs (Spotify, weather, events) directly
- Copy over the few shared UI components (
GlitchText,Progress) - Point the Pi’s browser at the new URL
Open questions
- Does adding Spotify surface any bundle size concerns in practice?