HomeWorksExperiments
Writing

© 2025 Guo Ying. Made with midnight builds.

Experiments>

Seat Board — Realtime Trip List

2026
Seat Board — Realtime Trip List
RealtimeUINext.js

Every trip card on the board shows a live "seats left" count. The experiment: can a booking UI feel alive with server-sent events instead of polling or WebSockets? Spoiler: yes, and it is far simpler to operate.

Live Demo Source on GitHub
Category
UI Experiment
Theme
Live data, no reload
Duration
~2 weeks
Role
Solo — code & design
Platform
Web (responsive)
Stack
Next.js · TypeScript · SSE · Tailwind CSS

Built to answer one question: does a booking list need WebSockets? For a screen that only ever shows "here is the current state", the answer is no — server-sent events are one HTTP connection, one event stream, and zero protocol bookkeeping.

// Server: one connection, many updates.
const encoder = new TextEncoder();
const stream = new ReadableStream({
  start(controller) {
    trips.forEach((trip) => {
      controller.enqueue(encoder.encode(`data: ${JSON.stringify(trip)}\n\n`));
    });
  },
});

What went right: the UI stays a plain render of state. No room for drift between "what the client thinks" and "what the server has".

What went wrong: reconnect handling is the hidden cost. A dropped connection needs an idempotent refetch, or the board silently freezes. That one bug took longer than the whole stream setup.