Skip to main content
강홍재/ James
← Work
Live2026 · Founder · Product · Engineer· Started(First Commit date)

Frameboard

RICE · ICE · MoSCoW · Value × Effort in one workspace - open-source prioritization.

  • Next.js 15
  • FastAPI
  • PostgreSQL
  • Open Source
Screenshots
  • RICE board - priority cards in a grid, score distribution at a glance

  • Effort × Score scatter plot plus a Top-N bar chart to see how priorities cluster

  • Pick the framework per workspace (RICE · ICE · MoSCoW · Value × Effort)

  • Per-member scores, average, and min-max spread in one cell - average alone hides the disagreement

Setup

Problem

Every sprint, PMs burn time arguing "what's next?" across spreadsheets, sticky notes, and Slack threads. Existing tools split into two camps. The ones that lock you to a single framework (RICE-only, ICE-only) shut out teams whose baseline is somewhere else. The other camp is open and flexible but charges per seat or per workspace, so a 10-minute decision needs a budget request first. The result: prioritization meetings turn into "clean up the numbers" time, while the real conversation - why does this matter more? - gets squeezed into the last five minutes.

Context

Built from the QA seat, watching prioritization and release calls - the experience of using a prioritization tool was itself the requirement. RICE on paper doesn't show you why the score distribution comes out the way it does until you spin it through a real board. Improvements surfaced as I used it. Going open source removes the budget-approval step, so a 10-minute decision can stay a 10-minute decision for other teams that need it.

Users

PO/PM and product leads running prioritization workshops at team level.

Hypothesis

Pick the framework per workspace, let each member record their own score, aggregate automatically - and the prioritization meeting shifts from "cleaning numbers" to "debating disagreement."

Build

What I did
  • Polymorphic board across RICE / ICE / MoSCoW / Value × Effort - input columns, legend, and formula switch by framework
  • Team scoring - invite members, one score row per person, with average · contributors · min-max spread shown in a single cell
  • Ship-it toggle - completed items get struck through and sink to the bottom of the board; a retrospective toggle is separate
  • Effort × Score scatter plot + Top-N bar chart (RICE)
  • CSV / Notion / Linear export, GitHub OAuth, self-hostable via Docker Compose
Product decisions
  • Framework is a free choice per workspace - accepting the reality that teams are anchored to different baselines
  • Average exposed alongside min-max spread - showing only an average pretends consensus exists where dissent has been hidden
  • Open source plus free deploy on Cloudflare Pages - lowering the adoption cost is what creates the first entry
QA considerations
  • One board component switches the input columns, legend, and formula correctly for each of the four frameworks (RICE / ICE / MoSCoW / Value × Effort)
  • On a mode switch, no regression where another framework's formula gets applied or input columns disappear
  • Each framework's scoring formula is deterministic, so the same inputs always yield the same ranking and scatter position (pinned by 129 backend pytest tests)
  • In per-member aggregation, the average survives without the min-max spread silently dying - so noise pretending to be consensus doesn't erase the disagreement
  • Framework-switch flows are pinned as E2E scenarios so all four modes hold equal weight across refactors
  • Export (CSV / Notion / Linear) reflects each framework's column structure correctly and round-trips without data loss
  • On OSS self-hosting (Docker Compose), auth and data integrity hold identically to the managed environment

Outcome

Metrics

Open-source alpha - live at frameboard.pages.dev. Backend pytest at 129 tests, 5 E2E scenarios, CI green.

Result / Learning

Building my own PM workflow as a tool confirmed that "prioritization is the trigger that starts a conversation, not the score that ends it." The conversation only really begins when the cell shows the score range across members - "why is yours an 8 and mine a 3?" The average pretends consensus exists where it doesn't; the min-max spread is the actual door into the discussion. Next round's hypothesis is that the discussion trail itself - preserved alongside the score - is what changes the meeting.

Retrospective
  • Started this as a "score-the-items" tool; using it confirmed the value is being the trigger that starts a discussion. The next round redesigns from preserving the discussion trail first.
Tech stack
  • Next.js 15
  • TypeScript
  • Tailwind
  • shadcn/ui
  • FastAPI
  • SQLAlchemy
  • PostgreSQL
  • Playwright