All articles
Design systemEngineering

One UI kit, six platforms

By Maxime Scharwath2 min read

A movie tile looks the same on an Apple TV, on a Samsung television and in your browser. It is one component, not three kept in step by hand.

Written once, against React Native

The @kromatv/ui kit is written against React Native. On Apple TV, Android TV, iPhone and Android it renders natively. On the web, on Tizen and webOS televisions, in the Tauri desktop app and in the web client it goes through react-native-web. One file, two rendering engines.

Colors, typography, elevations and focus live once too, in TypeScript, and generate the CSS variables the web targets read:

import { colors, type } from '@kromatv/ui/tokens';
 
colors.accent; // #F4B642, the one warm amber
colors.bg;     // #0A0A0C, the deep charcoal
type.hero;     // 66px / 700, Bricolage Grotesque

This site defines no color of its own. It imports the kit's Tailwind v4 theme, so it renders in the same charcoal and the same amber as the application.

Focus is the only real split

What differs between a television and a browser is the navigation, not the appearance. A remote has no cursor.

On native, the OS focus engine handles directional moves: UIFocusEngine on tvOS, nextFocus resolution on Android TV. On the web there is no focus engine at all, so movement is geometric. The next focusable in the pressed direction wins, with lateral drift penalized so that a neighbor in a straight line beats one off to the side.

That split lives in a handful of .web.ts files. Nothing else in the kit knows it exists.

What it costs, and what it buys

Writing against React Native costs a resolver step in every bundler and a second rendering path to keep honest. What it buys is that a change to the movie tile is one commit, and every screen KROMA draws has it the same day. Six shells, one component.