Dashboard design for MVPs
Design the dashboard around the one question a user opens it to answer. Lead with the number that matters and what it compares to, use bar or line charts rather than pies, show what needs action next, and make tables scan with right-aligned, tabular numbers in the user's currency. Cut anything that does not change a decision.
On this page
What a dashboard is for
Nielsen Norman Group describes dashboards as collections of data visualisations in a single-page view, built for information at a glance and quick action rather than deep exploration. That second half is the part generated dashboards miss. A dashboard is not a report. It is the screen someone opens to decide what to do next.
So the design starts with a question, not a layout. For each type of user, write down the one thing they open the app to find out:
- An invoicing tool: "Who owes me money, and is any of it late?"
- A marketplace vendor: "Where am I trading next, and are bookings coming in?"
- A booking app for a studio: "What is on today, and are there gaps I can fill?"
Each answer suggests a different dashboard. None of them suggests four stat cards, a revenue chart and a table of recent activity, which is what you get if you ask an AI builder for "a dashboard". That layout is the average of thousands of products. It fits none of them particularly well. I wrote about why in why every AI-built app looks the same.
The four parts of a useful MVP dashboard
Most good MVP dashboards have some version of these four parts, in this order of importance.
1. The headline number, with context
One figure that answers the main question, bigger than anything else on the screen. A number on its own means little, so pair it with what it compares to: last month, the target, the same day last week. "£4,820 outstanding, £1,200 of it overdue" is a headline. "Revenue: £12,480" is a label.
2. What needs action
A short list of things that need the user now: overdue invoices, unconfirmed bookings, listings missing a date. This is often the most used part of the screen, and generated dashboards rarely have it, because "what needs action" depends on the product's rules.
3. One chart that answers a question
A chart earns its place when it answers something the numbers cannot, usually "is this getting better or worse". One well-labelled chart beats three decorative ones. Give it a title that states the question or the finding, not just "Revenue".
4. The recent or upcoming list
A table of recent transactions, upcoming bookings or latest orders, with a link to the full list. Keep it short, five to ten rows, and make each row lead somewhere.
Charts that people can read
NN/g's article on dashboards and preattentive processing is the best short guide to chart choice. People judge length and 2D position accurately and quickly, so bar charts, line charts and scatterplots communicate quantities well. Angle and area are much harder to judge, so pie charts, donuts, gauges and radar charts make comparisons harder. NN/g recommends avoiding pie charts most of the time, and avoiding 3D effects, which distort shapes and alignment.
Colour is the other common mistake. NN/g notes that people do not perceive hues as ordered, so colour should not encode quantity, and colour vision deficiency affects a meaningful share of people. A bar chart where every bar is a different colour of the rainbow adds noise and no information. Use one colour for the data and a second only to highlight something specific, like the current month or a value over target. WCAG 2.2 success criterion 1.4.1 says colour should never be the only way information is conveyed, so label the highlight too.
shadcn/ui's chart component is built on Recharts and reads colours from a config object, which makes this easy to keep disciplined:
"use client"
import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
import {
ChartContainer,
ChartTooltip,
ChartTooltipContent,
type ChartConfig,
} from "@/components/ui/chart"
const chartConfig = {
paid: { label: "Paid", color: "var(--primary)" },
} satisfies ChartConfig
export function PaidByMonth({ data }: { data: { month: string; paid: number }[] }) {
return (
<ChartContainer config={chartConfig} className="min-h-[200px] w-full">
<BarChart accessibilityLayer data={data}>
<CartesianGrid vertical={false} />
<XAxis dataKey="month" tickLine={false} axisLine={false} tickMargin={8} />
<ChartTooltip content={<ChartTooltipContent />} />
<Bar dataKey="paid" fill="var(--color-paid)" radius={3} />
</BarChart>
</ChartContainer>
)
}Two details from the shadcn/ui docs matter here. ChartContainer needs a minimum height, such as min-h-[200px], to be responsive. And accessibilityLayer adds keyboard access and screen reader support to the chart, so turn it on.
Tables that scan
The table is often the most used part of a dashboard and the least designed. NN/g's research on data tables names four tasks people do with them: find records that match criteria, compare data, view or edit a single row, and act on records. Design for those four:
- Make the first column a readable identifier, like a customer or invoice name, not an ID.
- Order columns by importance and keep related ones next to each other.
- Freeze the header when the table scrolls.
- Right-align numbers and use tabular figures, so digits line up and amounts can be compared at a glance. Tailwind's
tabular-numsutility setsfont-variant-numeric: tabular-nums. - Format money and dates for your users. For a UK product, that means pounds and day-month dates, which generated code often gets wrong.
A tiny helper keeps formatting consistent across every table and card:
// lib/format.ts
const gbp = new Intl.NumberFormat("en-GB", { style: "currency", currency: "GBP" })
// timeZone "UTC" because a date-only ISO string is parsed as midnight UTC
const shortDate = new Intl.DateTimeFormat("en-GB", { day: "numeric", month: "short", timeZone: "UTC" })
export const formatMoney = (pence: number) => gbp.format(pence / 100)
export const formatShortDate = (iso: string) => shortDate.format(new Date(iso))
// formatMoney(1248050) gives "£12,480.50"; formatShortDate("2026-11-14") gives "14 Nov"<td className="text-right tabular-nums">{formatMoney(invoice.amountPence)}</td>Storing money as integer pence and formatting at the edge avoids floating point surprises in totals.
Dashboard elements compared
| Element | Do | Avoid |
|---|---|---|
| Headline metric | One number, large, with a comparison | Four equal cards with no context |
| Metric cards | Different sizes for different importance | Icons in tinted circles as decoration |
| Charts | Bars or lines, one data colour, a title that states the finding | Pies, donuts, 3D, a different colour per bar |
| Tables | Readable first column, right-aligned tabular numbers, sticky header | IDs as the first column, centred numbers |
| Money and dates | Formatted for the user's locale and currency | Dollar signs on a UK product, month-first dates |
| Actions | A short "needs attention" list near the top | Burying overdue items in a full table |
| Type and density | Smaller, tighter type for working tools | Marketing-page spacing on a data screen |
| Empty state | What will appear and how to add the first item | A blank chart with axes and no data |
Density, type and the first day
A working dashboard is used daily, so it can be denser than a marketing page. Smaller type, around 13 to 14px for tables, tighter row heights and hairline borders let people see more without scrolling. That is a theme decision, covered in how to make a shadcn app not look like shadcn.
The first day matters as much as the hundredth. A new user's dashboard has no data, so every chart, card and table needs an empty state that says what will appear and how to get there. A chart with axes and no bars looks broken. Empty states, errors and loading states AI forgets covers the code.
See it applied
The first article in my teardown series takes a typical AI-generated finance dashboard and redesigns it step by step using everything above: redesigning a vibe-coded finance dashboard.
If you would like the same thinking applied to your product, that is what I do: I design the dashboard around your users' main question and build it in your codebase. You can see dashboards I designed and built for vendors and hosts on FindPopups, or read the design guide for AI-built apps for the wider picture.
- Nielsen Norman Group: Dashboards, Making Charts and Graphs Easier to Understand, checked 9 November 2026
- Nielsen Norman Group: Data Tables, Four Major User Tasks, checked 9 November 2026
- shadcn/ui docs: Chart, checked 9 November 2026
- Tailwind CSS docs: font-variant-numeric, checked 9 November 2026
- MDN: Intl.NumberFormat() constructor, checked 9 November 2026
- W3C: WCAG 2.2, 1.4.1 Use of Color, checked 9 November 2026
Questions founders ask
How many metrics should an MVP dashboard show?
As few as answer the main question, often one headline number with context and two or three supporting ones. If every metric gets a card of equal size, users cannot tell which matters.
Which chart types work best on a dashboard?
Bar and line charts, because people judge length and position more accurately than angle or area. Nielsen Norman Group recommends avoiding pie and donut charts most of the time, and avoiding 3D effects.
Should an MVP have a dashboard at all?
Only if users need an overview to decide what to do next. For many MVPs the best home screen is the main list of work, such as orders, bookings or invoices, with a small summary on top.

Ant
Product designer who builds MVPs, based in Nottingham. 10+ years designing digital products, and the only person at BlackFig. More about me