Skip to content

PATTERN Cited by 1 source

HTML subset to native UI mapping

Problem

You want one UI codebase that renders on web + iOS + Android. Two directions are available:

  • Native primitives → HTML adapter (react-native-web): write RN components (<View />, <ScrollView />), let a library translate to HTML at runtime. Carries runtime adapter cost on web.
  • HTML subset → native primitives adapter (react-strict-dom): write HTML subset (html.div, html.button), let a library map to RN on mobile and pass-through on web. No runtime cost on web because a build step strips the adapter.

Pattern (the second direction)

Write UI in an HTML + CSS subset (html.div, html.button, html.span), paired with StyleX for styling. Let react-strict-dom handle the mapping:

  • Web: passes through to native DOM elements. Build step strips the abstraction. Zero runtime cost.
  • Native (iOS/Android): maps to RN primitives (<Text>, <View>) at build/runtime.
import { css, html } from 'react-strict-dom';

const styles = css.create({
  button: {
    backgroundColor: { default: 'white', ':hover': 'lightgray' },
    padding: 10
  }
});

function MyButton() {
  return (
    <html.button style={styles.button}>
      A cross-platform button
    </html.button>
  );
}

Why the HTML-subset direction wins here

Two arguments, both from Zalando's 2025-10 post:

  1. Substrate longevity. HTML + CSS have had multiple decades of specification and implementation work compounding behind them. RN's component model is younger and more volatile. Zalando: "HTML and CSS are incredibly expressive, have evolved over many years, and are likely to remain relevant for years to come. In contrast, any other form of UI representation could potentially become obsolete at any point."
  2. Zero runtime cost on web. The build step eliminates the abstraction layers on web; output is plain HTML + CSS with no adapter overhead. react-native-web carries that adapter at runtime.

Structural constraints

The subset constraint from concepts/cross-platform-ui-subset-tradeoff applies: react-strict-dom's HTML surface covers only the intersection of what all platforms can render. For everything outside:

Both are necessary for a realistic cross-platform component library.

When to reach for this pattern

  • You're building cross-platform UI (web + iOS + Android) from one codebase.
  • You want web output to be plain HTML/CSS — no JS adapter.
  • You're OK with accepting HTML subset as the expressive ceiling, plus a disciplined escape-hatch story for the non-intersection.

When not to

  • Your target is mobile-only (no web). The HTML framing adds complexity for no benefit; use RN directly.
  • Your app is very native-forward (heavy use of platform-specific navigation primitives, camera integration, hardware sensors). The HTML subset covers less of your surface; the subset-to-escape-hatch ratio is bad.

Seen in

Last updated · 507 distilled / 1,218 read