Engineering · Part 16 · a design system that cannot drift
A living component gallery
Reference documentation for a design system that cannot drift: reusable UI as server-side template partials that real pages compose, and a staff-only gallery that showcases the very same partials in their states — so "the component" and "the demo of the component" are guaranteed to be one thing.
A design system's failure mode is not ugliness; it is drift. The styleguide shows a
button one way, the actual app renders it another, and over months the two diverge until the gallery
is a museum of how things used to look. The cure is structural: make the showcase
{% include %} the identical file the app uses, so there is physically no separate copy
to fall out of sync. This document is that idea, which costs almost nothing and pays forever.
Components are template partials, composed everywhere
Reusable UI lives as small Django partials — one file per component — parameterised at the include site:
templates/components/
button.html card.html input.html table.html badge.html
modal.html subnav.html account_widget.html file_upload.html …
<!-- a real page composes them; the markup for "badge" lives in ONE place -->
{% include 'components/badge.html' with state=post.status label=post.get_status_display %}
{% include 'components/button.html' with label='Publish' variant='primary' %}
The rule that makes this a system rather than a folder of snippets: your own pages compose
these partials rather than hand-writing their markup. The status badge on the post list, the
status badge in the gallery, and the status badge in an email are the same
components/badge.html — so a change to it changes everywhere at once, and there is no
"the version on the dashboard" to forget. Not everything needs to be a component (plain shell chrome
can stay ordinary markup, and third-party widgets that render their own controls are left alone) —
but anything that appears in more than one place becomes a partial, for exactly the reason Part 11
made the account widget one.
The gallery includes the real thing
Now the payoff. A staff-only page renders a living gallery by including those same partials, in each of their states — never a hand-copied approximation:
<!-- the gallery: the SAME include the app uses, shown in every state -->
<h3>Badge</h3>
{% for s in badge_states %}
{% include 'components/badge.html' with state=s label=s %}
{% endfor %}
<h3>Button</h3>
{% include 'components/button.html' with label='Primary' variant='primary' %}
{% include 'components/button.html' with label='Secondary' variant='secondary' %}
{% include 'components/button.html' with label='Danger' variant='danger' %}
Because the gallery {% include %}s the production partial, it is impossible for the
showcase to lie: if a button's markup changes, the gallery shows the new button on the next request,
with no update to the gallery itself. The gallery is not a description of the design system — it
is the design system, executed. It becomes the look-and-feel source of truth precisely
because it shares source with the app, and it doubles as the fastest way to see a component in states
that are awkward to reach in the real app (an error state, an empty state, every status at once).
In this codebase: see it live at /staff/ui.
A routes hub, while you are there
The same staff page is the natural home for a second, unglamorous but valuable thing: a hub linking every page in the app, including the ones that never appear in the navigation — legal pages, the authentication and password-reset flows, account management, the admin, the health endpoint. In a server-rendered app these are easy to lose track of; a single index of "every URL this app serves" is a five-minute build that saves an engineer hunting for the password-reset template's actual address, and gives QA one place from which to reach everything.
Why a staff page and not a separate tool
Component galleries usually mean a separate front-end tool with its own build, its own server, and its own copy of your styles — which is one more thing to run and, fatally, one more place the styles can diverge from production. Rendering the gallery as an ordinary staff page inside the real app removes all of that: it uses the real CSS (the same stylesheet the app ships), the real partials, the real shell, served by the real server, gated by the same staff-only rule as your other internal tools (Part 12's default-deny). There is nothing extra to build or deploy, and — the whole point — nothing that can drift, because there is no second copy of anything. The gallery is live because it is not separate.
The shape to copy
- Reusable UI as parameterised template partials, one file per component; real pages compose them rather than hand-writing markup.
- A staff-only gallery page that
{% include %}s the same partials in each state — never a hand-copied demo — so the showcase shares source with production and cannot drift. - Add a routes hub to the same page: a link to every URL, including the ones outside the nav.
- Render it inside the real app (real CSS, real shell, staff-gated), not as a separate tool with its own build and its own divergent copy of the styles.
And with a design system that shows itself honestly, the series is complete — sixteen documents, one recurring idea at every scale: define each thing once, in one place, and let everything else reuse it.