
On Friday evening, a tab bar in Orochia, our creator video platform, showed a small vertical scrollbar on its right end. One pixel too many, because of the focus ring. A detail. But the same pattern was in the settings navigation, in a row of short videos, in a date picker and in the table of contents of the reading pages.
The fix was made once, in the kit (krizaka-ui#295), with tests that failed before it. Then every application got it by bumping a version. That's the idea of a shared kit. Here is what it really gives us, with numbers, and what still gets in the way.
One kit, three platforms
Krizaka UI is the component library of all our sites and apps. It targets three platforms: the web (React), mobile (React Native with Expo) and the Mac (a Tauri window, which shows the web components as they are, with a few desktop forms).
On 17 October, the platforms page counts 156 components on the web, 79 on mobile and 112 on the Mac. The day before it was 151, 76 and 107. It moves fast, and that's on purpose.
The rule that matters most isn't a component, it's a decision: every component must say, for each platform, whether it exists there, whether it's still to build (with an issue), or whether it makes no sense there (and what to use instead). A new component without that decision fails the tests (krizaka-ui#283). On mobile, 22 gaps remain. I'd rather see them written down than discover them in an app.
The same contract, not the same code
Reusing a component doesn't mean copying its code from one platform to another. It means keeping the same interface: the same name, the same variants, the same colours from the same design tokens. On the web:
import { Button } from "@krizaka/ui/button";
<Button variant="primary" shape="cut">Continue</Button>;And on mobile:
import { Button } from "@krizaka/ui/native";
<Button variant="primary" label="Continue" />;You see the small difference: the text goes through label on mobile. It isn't perfect, and I'll say so. But someone who knows the web button already knows how to use the mobile one.
What it buys
A fix made once. The tab scrollbar is one example. Another: on krizaka.com's home, the cards of one row didn't line up their links when their sentences had different lengths. We fixed the card in the kit (krizaka-ui#187), with a test that measures the row in a real browser. Every card grid of every site got it.
Fewer hand-made things. This blog had its own home-made footer. It now uses the kit's (krizaka-blog#21), the same as the other Krizaka sites. For tables and forms, a lint rule refuses the ones written by hand outside the kit, and a counter keeps the number of exceptions: it can only go down.
Tests in one place. On 16 October, the kit's registries ran 1,682 tests for the components and 237 for the charts. An application doesn't have to retest how a button behaves; it tests what it does with it.
What it costs
The kit has a price too, and I'd rather say it.
You have to publish, then bump every application. @krizaka/ui has had 48 published versions since it was created on 8 October. On 17 October, 22 package.json files in our repositories depended on it, and 8 were at least one minor version behind. A fix in the kit isn't a fix in the app yet.
Reference screenshots. Every component has screenshots compared on every change, on Linux and on macOS, and they have to be regenerated when the rendering really changes. It's slow, and it needs a machine that isn't already busy.
Native parity. 22 gaps means 22 places where a mobile app has to wait, or do otherwise. And there are contract differences, like the button's label, that we'll pay for sooner or later.
What you can take from it
If you build several products, make a kit early, but treat it as a product: its own tests, a page that honestly says where each component exists, and a tool that tells you which applications are behind. Keep interfaces identical across platforms, even when the code can't be. And when you fix a detail in one app, first ask yourself whether it exists elsewhere.
The next post in this series is about what you don't see in the code: the accounts, the keys and the automation it takes to run all this on your own.