Lesson 05 / 24
Competitive and Current-State Analysis
Reading existing solutions decision by decision; spotting a convention through its adoption rate, measuring the cost of a deviation in step count, and the limits observed during the review.
Contents
The journey map showed where our own interface loses people, but it did not say whether these losses were unavoidable. Other systems doing the same job exist, and the decisions they made can be observed from the outside. This lesson turns that observation into a dataset.
The goal is not imitation. Reading existing solutions gives two separate pieces of information. First, which decisions are conventions: a problem solved the same way across every system is a pattern the user has already learned, and deviating from it produces a learning cost. Second, which decisions are open: the places where systems diverge from each other are the places where the designer will actually make a decision.
Breaking Systems Down into Decisions
The analysis does not start with the question “which is better” but with “which decisions were made.” Every system is reduced to a decision list, and the list is the same across all systems; only then are they comparable.
A decision must be observable and binary: is it present in the system or not. “Search works well” is not a decision but a judgment. “The search term is preserved when returning to the list after opening a record” is a decision; you look, and you write down the answer.
// current-state.mjs — spotting conventions and comparing step counts // A: our current catalog interface. B-E: four other systems doing the same job, reviewed. // (data constructed for this lesson) const SYSTEMS = ["A", "B", "C", "D", "E"]; const DECISIONS = [ { name: "search field top-center", present: ["A", "B", "C", "D", "E"] }, { name: "borrow action in record detail", present: ["A", "B", "C", "D", "E"] }, { name: "search preserved on return", present: ["B", "C", "D", "E"] }, { name: "result count shown", present: ["A", "B", "D", "E"] }, { name: "on-shelf badge in list", present: ["B", "C", "D"] }, { name: "refinements on the left", present: ["A", "B", "D"] }, { name: "reading list", present: ["A", "C", "E"] }, { name: "subject-tree navigation", present: ["C", "D"] }, { name: "shelf code in list", present: ["C"] }, { name: "record opens in a new tab", present: ["E"] }, ]; const N = SYSTEMS.length; const classify = (share) => (share >= 0.8 ? "convention" : share >= 0.4 ? "split" : "differentiator"); console.log("decision adopters share class ours"); const deviations = []; for (const d of DECISIONS) { const share = d.present.length / N; const ours = d.present.includes("A"); if (classify(share) === "convention" && !ours) deviations.push(d.name); console.log( `${d.name.padEnd(30)} ${d.present.join("").padEnd(11)} ${share.toFixed(2)} ${classify(share).padEnd(14)} ${ours ? "yes" : "NO"}` ); } console.log(`\ndeviation from a convention: ${deviations.length ? deviations.join(", ") : "none"}`); // How many screen steps the same task takes to complete on each system (observed by counting) const TASKS = [ { name: "find a known record and borrow it", steps: { A: 7, B: 5, C: 6, D: 5, E: 8 } }, { name: "browse by subject and compare three records", steps: { A: 13, B: 9, C: 11, D: 12, E: 10 } }, ]; const median = (values) => { const s = [...values].sort((x, y) => x - y); const m = s.length >> 1; return s.length % 2 ? s[m] : (s[m - 1] + s[m]) / 2; }; console.log("\n" + "task".padEnd(45) + " " + SYSTEMS.map((s) => s.padStart(2)).join(" ") + " min median our difference"); for (const t of TASKS) { const values = SYSTEMS.map((s) => t.steps[s]); const med = median(values); const diff = t.steps.A - med; console.log( `${t.name.padEnd(45)} ${values.map((v) => String(v).padStart(2)).join(" ")} ` + `${String(Math.min(...values)).padStart(3)} ${String(med).padStart(6)} ${(diff >= 0 ? "+" : "") + diff} steps` ); } // Step-by-step model of the comparison task: state preserved or not function stepCount(statePreserved, recordCount) { let a = 3; // type the term, run the search, apply the refinement for (let i = 0; i < recordCount; i++) { a += 2; // open the record, return to the list if (!statePreserved && i < recordCount - 1) a += 2; // retype the term, reapply the refinement } return a; } console.log("\ncomparison-task model (3 records)"); console.log(` state preserved : ${stepCount(true, 3)} steps`); console.log(` state not preserved : ${stepCount(false, 3)} steps`); console.log(` source of the gap : ${stepCount(false, 3) - stepCount(true, 3)} steps, from a single decision`); console.log(` observed A : ${TASKS[1].steps.A} steps, observed min (B): ${Math.min(...SYSTEMS.map((s) => TASKS[1].steps[s]))} steps`); // How the gap grows as record count increases console.log("\nrecords compared preserved not preserved gap"); for (const k of [2, 3, 5, 8]) { const p = stepCount(true, k), np = stepCount(false, k); console.log(`${String(k).padStart(16)} ${String(p).padStart(9)} ${String(np).padStart(13)} ${np - p}`); }
decision adopters share class ours
search field top-center ABCDE 1.00 convention yes
borrow action in record detail ABCDE 1.00 convention yes
search preserved on return BCDE 0.80 convention NO
result count shown ABDE 0.80 convention yes
on-shelf badge in list BCD 0.60 split NO
refinements on the left ABD 0.60 split yes
reading list ACE 0.60 split yes
subject-tree navigation CD 0.40 split NO
shelf code in list C 0.20 differentiator NO
record opens in a new tab E 0.20 differentiator NO
deviation from a convention: search preserved on return
task A B C D E min median our difference
find a known record and borrow it 7 5 6 5 8 5 6 +1 steps
browse by subject and compare three records 13 9 11 12 10 9 11 +2 steps
comparison-task model (3 records)
state preserved : 9 steps
state not preserved : 13 steps
source of the gap : 4 steps, from a single decision
observed A : 13 steps, observed min (B): 9 steps
records compared preserved not preserved gap
2 7 9 2
3 9 13 4
5 13 21 8
8 19 33 14
Three Decision Classes
Adoption rate splits decisions into three classes, and each class calls for a different design stance.
Convention (0.80 and above). The search field sitting top-center and the borrow action being in the record detail are the same in all five of the five systems. These decisions are not opened up for debate; the user has learned them elsewhere, and the interface inherits that learning. Deviating from a convention is not forbidden, but a measurable gain must be shown in exchange for the deviation.
Split decision (0.40 – 0.80). Showing on-shelf status in the list, the position of the refinements, whether a reading list exists: systems split into two camps. These decisions are genuine design decisions, and they are resolved with our own user data. In a split decision, the argument “everyone does it this way” cannot be used, because not everyone does.
Differentiator (below 0.40). The shelf code shown in the list exists only in C, and a record opening in a new tab exists only in E. These decisions are either an advantage or a choice that was tried and never caught on; the only way to tell the two apart is to ask, in that system’s own context, why it made this choice. These are the decisions that look most tempting to copy, and they are also the riskiest.
The Cost of a Deviation Is Measurable
The decision list has exactly one deviation from a convention: search being preserved on
return exists in four systems but not in ours. We are looking at the same phenomenon as
the search-lost-on-return code, which appeared in four of the twelve interviews in the
first lesson; now its cost is being tied to a number.
The step model builds the three-record comparison task under two conditions. When state is preserved, the task takes nine steps; when it is not, thirteen. The gap is four steps, and all of it comes from a single decision. The observed numbers confirm the model: our interface takes thirteen steps, and the system that completes it in the fewest steps takes nine.
The last table shows the real constraint. The gap is not constant; it grows together with the number of records compared. Two records, a two-step gap; three records, four steps; eight records, fourteen steps. The Subject Browser persona built in the second lesson does exactly this task, and their session lasts twenty-one and a half minutes. The user who pays the highest cost for the deviation is the user who uses the interface the most.
The rule that follows from this determines how the comparison is read: step count is calculated not for a single task but for the task’s range of sizes. A gap that looks trivial in a small example can grow linearly in real use.
The Difference Between the Median and the Best
The table has two comparison metrics, and they answer two separate questions. The gap against the median tells how far the interface has drifted from the customary; one step in the known-record task, two steps in the comparison task. The gap against the system that completes it in the fewest steps tells the reachable limit: four steps in the comparison task.
If the median is chosen as the target, the interface stays average. If the best is chosen, the target is clear, but that system may carry other constraints; system E, which completes the task in eight steps, opens records in a new tab — a decision that slows it down in this task but pays off in another. A system’s edge in one task does not mean all of its decisions are correct.
Limits of the Review
Reviewing existing systems means coming into contact with someone else’s interface, and often with someone else’s data.
The review is conducted as an ordinary user. The decision list is made of things observable in the publicly open interface. Creating a fake membership to reach closed sections, bulk-downloading another institution’s records, or bypassing access restrictions is not review, and it falls outside the analysis.
If someone else’s users are to be observed, the same rules apply. Observing another library’s users carries the same consent and anonymization obligation as observing our own participants; the institution’s permission is obtained separately.
Decisions are carried over, not content. A system’s record descriptions, classification data, or texts are that institution’s labor. What is taken from the analysis is information such as “the search term is preserved,” not the text itself.
The decision list is kept together with its source. Which system, on which date, and by attempting which task it was observed is written down. Interfaces change; a decision list with no date cannot be verified a year later.
Summary
- The analysis is done not with the question “which is better” but with a decision list that is common and binary across all systems.
- Adoption rate splits decisions into conventions, split decisions, and differentiators; deviating from a convention requires a measurable gain, and split decisions are resolved with our own data.
- In the sample data, the one deviation from a convention is “search not preserved on return”; the step model showed that this single decision adds four steps in a three-record comparison, and it matches the observed numbers.
- The cost of a deviation grows with task size: in a session comparing eight records, the gap rises to fourteen steps, and the cost is paid most by whoever uses the interface the most.
- The review is limited to the publicly open interface; fake membership, bulk data downloads, and carrying over content fall outside the analysis, and the decision list is kept together with its date.
Next Step
Data accumulated over five lessons: ten codes, three personas, seven tasks, one journey map, and one decision list. This accumulation is not yet a design job — it is a pile of material. The next lesson reduces the pile to a single sentence: the problem statement. It addresses the criterion by which findings are ranked, which parts a problem statement consists of, and why a solution seeping into it is the most common mistake.
To keep your progress and take notes, Log in
My notes
Log in to take notes.