Flowboard
A Kanban board where everyone moves together, live.
No sign-up. Open it in two tabs and watch them sync.
The problem
Most team boards feel like a shared file. Someone moves a card, you refresh, and you find out an hour later. The work happens together, but you can't see it happen.
I wanted a board that feels like a room: you see who is there, where they point and what they move, as it happens.
Three decisions that made it work
Three realtime tools, three jobs
Presence tracks who is online. Broadcast streams cursors and drags. Postgres changes push every saved move to every open tab. Each tool does the one thing it is best at.
presence · broadcast · postgres_changes Order without renumbering
Cards store a fractional position. Dropping a card between two others takes the midpoint, so a move writes one row instead of rewriting the whole column.
(before + after) / 2 Rules live with the data
Row Level Security is on every table. Access runs through one database function that allows the public demo board or boards you own.
is_demo or owner_id = auth.uid() export function positionForIndex(sorted: { position: number }[], index: number): number {
const clamped = Math.max(0, Math.min(index, sorted.length));
const before = clamped > 0 ? sorted[clamped - 1].position : undefined;
const after = clamped < sorted.length ? sorted[clamped].position : undefined;
if (before === undefined && after === undefined) return POSITION_GAP;
if (before === undefined) return after! - POSITION_GAP;
if (after === undefined) return before + POSITION_GAP;
return (before + after) / 2;
} A pure function with its own unit tests. The UI, the database and the realtime echo all agree on order because they all read the same number.
Designed so people stand out
The board stays quiet so people can be loud. A neutral canvas and soft cards, with four bright accents saved for the humans on it.
Cards and cursors move on springs, not timers, so a drag feels physical. Everyone gets a friendly name like Swift Otter, no account needed.