Stated up front. In January 2026 this magazine ran a piece about somebody who managed a neighbourhood football club's dues by chat and notepad, and built a tool for themselves on a weekend afternoon. This is not a specific group. We constructed the shape exactly as it actually works, and we do not name where. What follows was built to that shape.
The original's angle was good. The point was not the tool but the threshold — put up with it, cram it into a spreadsheet, or ask a developer friend. And that beside those three a fourth path had appeared: making what you need yourself.
But that piece showed none of what it said it would show. Zero screens of the tool it claimed was built, zero lines of definition, zero steps of the process. "A non-developer could build it on a weekend afternoon" was the only claim, and all that held it up was the statement.
In the field strand this is especially fatal. The reason this strand exists is permission — "you can do this too" — and permission without evidence is advertising.
Counting the lines
We cannot measure the time. As written below, the time it took me is no guide.
Instead we measure size. How many lines the maker actually touches.
what the maker edits: ui/pages/dues.json 38 lines, ui/app.json 7 lines
Forty-five lines. One screen (38) and a route table (7).
Showing what those 38 lines look like, whole, is the most important thing in this piece. Not an excerpt — the entire screen.
{
"type": "page",
"title": "Dues",
"initialState": { "rows": [], "paidCount": 0, "total": 0,
"collected": "", "owed": "", "notice": "" },
"content": {
"type": "center",
"child": {
"type": "linear", "direction": "vertical", "alignment": "center", "spacing": 14,
"children": [
{ "type": "text", "text": "APRIL DUES" },
{ "type": "text", "text": "{{paidCount}} of {{total}} paid" },
{ "type": "text", "text": "{{collected}} in · {{owed}} still out" },
{ "type": "box", "width": 460, "height": 230,
"child": {
"type": "list", "items": "{{rows}}",
"itemTemplate": {
"type": "linear", "direction": "horizontal",
"children": [
{ "type": "text", "text": "{{item.name}}" },
{ "type": "text", "text": "{{item.mark}}" }
]
}
} },
{ "type": "button", "label": "Jiwon paid",
"onTap": { "type": "tool", "tool": "dues.toggle",
"params": { "who": "Jiwon" } } },
{ "type": "text", "text": "{{notice}}" }
]
}
}
}
(Style attributes are stripped above. The real file is 38 lines with colours and font sizes attached.)
You can read it. That is the whole claim of this piece. Can somebody who never learned programming look at that and change "APRIL DUES" to "May dues" — probably yes. Can they guess what {{paidCount}} of {{total}} paid means — probably.
The verification protects the claim that it is small
This kind of claim collapses quietly. Features get added one at a time, it is 200 lines before anybody notices, and the article still says "small".
So it went into the verification.
LINES=$(cat dues.mbd/ui/pages/dues.json dues.mbd/ui/app.json | wc -l | tr -d ' ')
# This article's claim is that it is small, so if it stops being small the
# claim stops being true. It should fail rather than quietly drift.
[ "$LINES" -le 60 ] || { echo " the screen has grown to $LINES lines — the article claims small"; exit 1; }
Putting the property the article claims into the pass condition happens here first in this series. Other pieces checked structure — was it computed, is a reason attached — but this piece's claim is the size itself.
This content requires Developer or above
Sign in and upgrade your plan to continue reading.
View Plans