Communitygithub.com

mickzijdel/data-before-design

Use before building a view of stored data (card, panel, table, dashboard, report, profile page), and when a stakeholder says what to show, a field looks obviously useful, layouts for the same records compete, or several cards or charts cover the same categories. Not for pure looks (design-process) or how a posted chart reads (practical-charts).

What is data-before-design?

data-before-design is a Claude Code agent skill that use before building a view of stored data (card, panel, table, dashboard, report, profile page), and when a stakeholder says what to show, a field looks obviously useful, layouts for the same records compete, or several cards or charts cover the same categories. Not for pure looks (design-process) or how a posted chart reads (practical-charts).

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mickzijdel/dev-hooks/tree/HEAD/plugins/dev-hooks/skills/data-before-design

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Data before design

Three things decide whether a view of data is any good, and all three are settled before you write markup: what decision the view serves, what is actually in the field, and which of several layouts the person wants. Skipping any of them produces a view that looks finished and is wrong.

When to use

  • Any card, panel, table, dashboard or detail view over records you did not author
  • A stakeholder says "show me X" and X is a column name
  • You are about to summarise, truncate, badge, sort, colour or count a field
  • You are choosing between two ways to lay out the same information

Skip when the data is your own fixture, or the view is one value you already printed.

A chart or table that will be posted, shared or put in a report still starts here when it shows records you did not author. Once the data is settled, practical-charts covers how it reads: the headline title, honest axes, one highlighted series, the source inside the image.

Step 0: name the decision

Write one sentence before touching the data: "Someone looking at this is deciding ___." If you cannot finish it, you are building a data dump and the layout question has no answer.

  • Every field earns its place by changing that decision. Interesting but decision-neutral belongs in the detail view, not the card.
  • Prominence tracks decision weight, not query convenience. The field that was easiest to fetch is not the field that deserves the largest type.
  • A stakeholder naming a column has told you the data they want, not the decision. Ask what they would do differently depending on its value.

Step 1: profile the field, then design

Query before you design. For every field the view will show:

CheckWhy it changes the design
Non-null countA field NULL on every row needs no card — it needs a bug report
Distinct valuesFour values is a chip set; four thousand is a search box
Length: min / mean / p95 / maxThe mean hides the overflow — size the container to p95, and decide deliberately what the tail does
Coverage across recordsA card that fires for 1.6% of records is an empty state with a rare exception
Cardinality per parentOne note per person is a paragraph; twenty is a list with its own affordances
Date presenceYou cannot show staleness for a field that carries no date
VocabularyFree text with eight house phrasings needs normalising, not rendering
A comparator existsA bare number is unreadable — see below

State what you found before proposing the design, in numbers.

Every number on screen needs something to compare it against

52 notes tells the reader nothing: they cannot tell whether it is a lot. 52 notes (median 4) is a finding. Before displaying any count, total or score, find its comparator — a median, a target, the previous period, or the rest of the set — and display them together. If no comparator exists, that is evidence the number should not be on screen.

The degenerate case is a number that never varies: a count true of every record reads as a finding and is noise.

Step 2: mock the options, then build

For anything card-shaped, produce several static mocks from real records and let the person choose. Build only after that.

  • Say in one line what each option optimises for and what it costs
  • Mocks are throwaway HTML, not a component — do not wire them up

Mock six states, not one

Design every state the view can be in, each from a real record:

StateDraw it from
IdealThe typical record — the one at the median, not the one you picked
EmptyA record with nothing in the field, and a brand-new account with no records at all
PartialSome fields filled, some not — in real data this is the common case, not the exception
LoadingWhat occupies the space before the data arrives, at the size the data will be
ErrorThe fetch failed, or the value is malformed and cannot be rendered
DoneWhat confirms an action the view offers actually happened

Then the stress case

Volume extremes (busiest, typical, empty) are not the only extremes. A stress case is data that is present, well-formed, and painful: the name the field mangles, the record whose status makes a cheerful badge wrong, the person whose deleted account the summary still counts. Pick the one record that would most embarrass this view and render it.

Several cards on one page: one key for all of them

A reader learns a colour's meaning on the first card and applies it to every card after it. So before drawing any card on a page with several, write down one category table for the whole page: the canonical name, a fixed order and one colour for each category. Every card, legend and tooltip uses it.

  • One category, one colour; one colour, one category. A colour belongs to its category even on cards where that category is absent. Using it again for something else, even on a card that never shows the original, tells the reader the two are the same thing.
  • One name per category. "Global Health & Development" on one card and "Global Dev & Health" on the next makes the reader wonder whether they are two categories.
  • One taxonomy where the cards cut the same records. Before a card adds its own bucket, check whether it merges into a category the page already has. If a card really needs a finer split, give the sub-categories shades of the parent's colour, not new colours.
  • Categories that really are different get unused colours, plus a subtitle saying the breakdown is different. Never reuse a colour the page has already given to another category.
  • Same order in every legend, with "Other" always last and always the same neutral grey.

Done when listing every (label, colour) pair across the page gives a one-to-one mapping. Grep the markup or stylesheet for the colour values, not the rendered screenshot.

Rendering rules that fall out of the data

  • The empty state does work. "No notes yet" is a dead end. Say why it is empty and what fills it. An empty state a user meets on day one is onboarding, and is worth designing.
  • Numbers in a table: right-align, tabular figures (font-variant-numeric: tabular-nums), one precision for the whole column, units in the header rather than repeated in each cell. practical-charts rule 13 has the rest: no grid, a tinted key row, inline bars.
  • The default sort is a design decision. Records arriving in primary-key order is the absence of one.

Common mistakes

MistakeWhat happens
Designing from the schemaThe column exists; the data does not
Building with no decision namedEverything gets equal weight, because nothing has a reason to be bigger
Giving the easiest field the most prominenceThe layout describes the schema, not the job
Showing a number with nothing to compare it toThe reader cannot tell whether it is good, and stops looking
Counting something that is always trueA count that never varies reads as a finding and is noise
Trusting a plan written before the data was seenYou build the thing the plan named, not the thing the data supports
Mocking only the ideal stateThe design collapses on the record that has nothing, or half of something
Testing only volume extremesThe view survives the biggest record and humiliates someone on an ordinary one
Building one option because it was described firstThe person cannot choose what they were never shown
Picking colours and labels card by cardThe same blue means two things on one page, and the reader draws a link that isn't there

Where the non-obvious parts come from

  • Decision-first, and prominence by decision weight — Stephen Few, Information Dashboard Design
  • A number needs a comparator — Few again, on context as the thing that makes a number mean anything
  • The six states — Scott Hurff's UI Stack
  • Stress cases — Eric Meyer & Sara Wachter-Boettcher, Design for Real Life

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Related Skills