---
title: 'Wireframe and Prototype'
source: 'https://academia.sh/en/courses/user-experience/wireframe-and-prototype'
course: 'User Experience and Behavior Design'
language: en
updated: '2026-08-19T05:19:58+00:00'
license: 'CC BY-SA 4.0'
---

# Wireframe and Prototype

Fidelity's three independent axes — visual, content, and interaction; separating a prototype's node coverage from its task coverage, and how the fidelity level affects preparation cost.

The flow has been checked, the navigation structure built. Both are consistent on paper,
but a consistent structure does not mean a usable interface. The only way to find out is
to show the structure to someone and give them a task.

The question is what to show. A crude outline made of boxes, a clickable copy, or a
visually complete screen filled with real text? This lesson takes on the fidelity-level
decision and computes how many tasks can be tested for how many screens a prototype
covers.

## Wireframe and Prototype Answer Different Questions

A **wireframe** shows a single screen's structure: what information exists, in what
hierarchy it sits, what actions are available. The question it answers is "are the right
things on this screen." A wireframe is static and single-screen; it cannot test a flow.

A **prototype** also includes the transitions between screens. The question it answers is
"can the user complete this task." A prototype is the flow diagram's runnable
counterpart: nodes correspond to screens, transitions to clicks.

The difference is not a difference in maturity but a difference in question. If a screen's
content is what's in question, a wireframe is enough, and building a prototype is wasted
effort. If whether the task is completed is what's in question, a wireframe says nothing.

## Fidelity Is Not a Single Axis

Fidelity level is usually thought of as a single slider between "low" and "high." In
reality there are three independent axes, and each can be set separately.

- **Visual fidelity.** How close the color, typography, spacing, and state design are to
  the real thing. The low end is gray boxes; the high end is every decision built in the
  Fundamentals of Interface Design course, applied.
- **Content fidelity.** Whether the text and data on the screen are real. The low end is
  placeholder text; the high end is the catalog's real records — including long titles,
  same-titled volumes, and empty metadata fields.
- **Interaction fidelity.** How many transitions work. The low end has a single clickable
  path; the high end has every branch.

The independence of these axes has a practical consequence: a prototype with **low visual
fidelity and high content fidelity** is the most efficient combination for catching
microcopy and information-architecture problems. When real record titles are placed
inside gray boxes, the truncation and same-titled-record problems measured in the first
topic become visible, while color decisions wait without diluting the discussion.

The reverse combination — high visual fidelity, low content fidelity — is the most
misleading. The participant assumes the screen they see is finished and comments on color
rather than structure; also, because every placeholder text is the same length, no
truncation problem ever surfaces.

## How Many Screens, How Many Tasks

While preparing a prototype, how many nodes to implement is a budget decision. This
decision's metric is not the share of screens covered but the share of tasks that can be
tested end to end.

```js
// prototype-coverage.mjs — a prototype's node coverage and task coverage are not the same

const ALL_NODES = [
  "start", "session active?", "login screen", "login error", "record status", "on shelf",
  "overdue book?", "pay fine", "borrow confirmation", "checked out", "reservation offer",
  "reservation confirmation", "borrow successful", "reservation successful", "give up",
];

// Each task's required sequence of nodes in the flow
const TASKS = {
  "borrow (session active)": ["start", "session active?", "record status", "on shelf", "overdue book?", "borrow confirmation", "borrow successful"],
  "borrow (login required)": ["start", "session active?", "login screen", "record status", "on shelf", "overdue book?", "borrow confirmation", "borrow successful"],
  "pay fine and borrow": ["start", "session active?", "record status", "on shelf", "overdue book?", "pay fine", "borrow confirmation", "borrow successful"],
  "reserve a checked-out record": ["start", "session active?", "record status", "checked out", "reservation offer", "reservation confirmation", "reservation successful"],
  "give up after wrong password": ["start", "session active?", "login screen", "login error", "give up"],
  "give up on reservation": ["start", "session active?", "record status", "checked out", "reservation offer", "give up"],
};

// Prototype versions: each version adds nodes to the previous one
const ADDED = [
  ["P1 main path", ["start", "session active?", "record status", "on shelf", "overdue book?", "borrow confirmation", "borrow successful"]],
  ["P2 login", ["login screen", "login error", "give up"]],
  ["P3 reservation", ["checked out", "reservation offer", "reservation confirmation", "reservation successful"]],
  ["P4 fine", ["pay fine"]],
];

const taskNames = Object.keys(TASKS);
const covered = (set, g) => TASKS[g].every((d) => set.has(d));

console.log("version           node  node coverage  testable tasks  task coverage");
const set = new Set();
const versions = [];
for (const [name, added] of ADDED) {
  added.forEach((d) => set.add(d));
  const testable = taskNames.filter((g) => covered(set, g));
  versions.push({ name, node: set.size, task: testable.length, set: new Set(set) });
  console.log(
    `${name.padEnd(15)} ${String(set.size).padStart(5)} ${((set.size / ALL_NODES.length) * 100).toFixed(1).padStart(13)}% ` +
      `${String(testable.length).padStart(16)} ${((testable.length / taskNames.length) * 100).toFixed(1).padStart(15)}%`
  );
}

// Of the nodes missing after a version, which one unlocks the most tasks
console.log("\nafter P1: missing node  tasks it blocks");
const p1 = versions[0].set;
const missing = ALL_NODES.filter((d) => !p1.has(d));
const blocking = missing
  .map((d) => [d, taskNames.filter((g) => !covered(p1, g) && TASKS[g].includes(d)).length])
  .sort((a, b) => b[1] - a[1]);
for (const [d, c] of blocking) console.log(`  ${d.padEnd(24)} ${c}`);

// Fidelity level's cost: assumed preparation time per node
const RATE = { "low (paper)": 0.5, "medium (clickable)": 2, "high (visual complete)": 6 };
console.log("\nfidelity level          P1     P2     P3     P4   (hours)");
for (const [name, hours] of Object.entries(RATE)) {
  console.log(
    `${name.padEnd(24)} ${versions.map((s) => (s.node * hours).toFixed(1).padStart(5)).join("  ")}`
  );
}
const largest = versions.at(-1).node;
console.log(`\ntesting every task requires ${largest} nodes`);
console.log(`${(largest * RATE["low (paper)"]).toFixed(1)} hours at low fidelity, ${(largest * RATE["high (visual complete)"]).toFixed(1)} hours at high fidelity  (${(RATE["high (visual complete)"] / RATE["low (paper)"]).toFixed(0)}x)`);
```

```
version           node  node coverage  testable tasks  task coverage
P1 main path        7          46.7%                1            16.7%
P2 login           10          66.7%                3            50.0%
P3 reservation     14          93.3%                5            83.3%
P4 fine            15         100.0%                6           100.0%

after P1: missing node  tasks it blocks
  login screen             2
  checked out              2
  reservation offer        2
  give up                  2
  login error              1
  pay fine                 1
  reservation confirmation 1
  reservation successful   1

fidelity level          P1     P2     P3     P4   (hours)
low (paper)                3.5    5.0    7.0    7.5
medium (clickable)        14.0   20.0   28.0   30.0
high (visual complete)    42.0   60.0   84.0   90.0

testing every task requires 15 nodes
7.5 hours at low fidelity, 90.0 hours at high fidelity  (12x)
```

## Counting Screens Is Not Counting Tasks

The first table's two columns do not track each other. The main-path prototype covers
46.7% of the nodes but can test only 16.7% of the tasks end to end. By the third version,
node coverage climbs to 93.3%, while task coverage stays at 83.3%.

The reason is a compound condition: a task is testable only if **all** the nodes it passes
through are implemented. A single missing node renders the entire task unusable. A
prototype that is half-ready can test not half the tasks but far fewer.

This has a direct practical consequence: a prototype is built **from the task list, not
the screen list.** The tasks to be tested are chosen first, then the set of nodes those
tasks pass through is derived, and the prototype covers that set. Proceeding screen by
screen produces a prototype where most of the prepared screens cannot be tested.

The second table says which node to build first. After the main-path prototype, the nodes
that unlock the most tasks are the login screen, the checked-out state, the reservation
offer, and giving up; each blocks two tasks. This is the same logic as the flow diagram's
path count, and it ties the priority discussion to a number.

## Cost Ratio, Not Cost Itself

The hour values in the third table are assumed unit costs; the real numbers depend on the
team, the tooling, and the screen's complexity. What matters is not the absolute durations
but the ratio between them: a low-fidelity prototype costs twelve times less per node than
a high-fidelity one. A prototype covering every task is 7.5 hours at low fidelity, 90 hours
at high fidelity.

Here is where this ratio determines the decision: **with the same budget, you can test one
task in detail or twelve tasks roughly.** Which question is being asked determines this
choice. The structural question — can the user complete the task — is answered with a
wide, cheap prototype. The visual-decision question — do these two states stand apart
clearly enough — is answered with a narrow, expensive prototype.

A cheap prototype has a second advantage, more important than cost: because it is
**disposable**, it is easy to criticize. A prototype that took ninety hours makes it hard
for the team working on it to accept change proposals; both the designer and the
participant lean toward defending the investment.

## Questions a Prototype Cannot Answer

A prototype is a copy, and it systematically misleads on certain questions.

**Data scale.** The prototype has ten records, the catalog has thousands. A results list
working well with ten records proves nothing; truncation, sorting, and narrowing problems
surface with scale. The cheapest way to raise content fidelity is to keep not the record
count but the records' **variety** realistic: the longest title, two same-titled volumes,
a record with missing metadata.

**Error frequency.** In the prototype, the connection never drops, an operation never
fails, the session never expires. The dead-end error node found in the flow diagram never
appears in the prototype, because there is no path that falls into it. Error states are
tested only if they are deliberately placed in the prototype.

**Time.** In the prototype, every transition is instant. The design of waiting states —
the Loading and Empty States lesson in the Fundamentals of Interface Design course — is
not naturally tested in a prototype; unless delay is added by hand, the user never waits.

**Learning.** A prototype session is a one-time encounter. A structure that looks hard on
first use might be the fastest by the third use; a structure that looks easy on first use
might be tiring in the long run. A prototype measures the first encounter, and this must
be stated explicitly.

## Summary

- A wireframe questions a single screen's content, a prototype questions whether a task
  can be completed; the difference between them is not maturity but the question asked.
- Fidelity is three independent axes — visual, content, and interaction; the low-visual,
  high-content combination is most efficient at catching information-architecture and
  copy problems.
- Node coverage and task coverage do not grow at the same rate; in the sample data, 46.7%
  node coverage could test only 16.7% of the tasks, because a single missing node blocks
  a task entirely.
- A prototype is built from the task list, not the screen list; missing nodes are ranked
  by computing how many tasks each one unlocks.
- What the fidelity level means is a ratio, not an absolute cost; with the same budget,
  either one task is tested in detail or many tasks are tested roughly.
- A prototype systematically understates data scale, error frequency, wait time, and
  learning; these limits are written alongside the findings.

## Next Step

The prototype is ready, but a cheap check can be run before calling in participants. A
large share of known usability problems are found by reviewing the interface with an
established list of evaluation criteria in hand. The next lesson takes on these criteria
one principle at a time, computes how much multiple evaluators' findings overlap, and
shows with a number why a single expert is not enough.
