React Native for Web

React Native for Web and What Renders Differently

React Native 36,878 for Web (https://github.com/necolas/react-native-web 22,138 ) (MIT, 0.21.2) reimplements React Native's components on top of React 7,897 DOM; it is what Expo 6,418 runs when you press w in expo start. Rendering one BookNest row to HTML in Node shows what it produces:

render.mjs: a BookNest row rendered by React Native for Web, in NodeJavaScript
import { createElement as h } from 'react';
import { renderToStaticMarkup } from 'react-dom/server';
import { AppRegistry, Pressable, StyleSheet, Text, View } from 'react-native-web';
const styles = StyleSheet.create({
  row: { flexDirection: 'row', padding: 12, gap: 8 },
  title: { fontSize: 16, fontWeight: '600' },
});
function BookRow() {
  return h(Pressable, { accessibilityRole: 'button', onPress: () => {} },
    h(View, { style: styles.row },
      h(Text, { style: styles.title, numberOfLines: 1 }, 'The Quiet Harbor'),
      h(Text, null, '$14.99')));
}
AppRegistry.registerComponent('BookNest', () => BookRow);
const { element } = AppRegistry.getApplication('BookNest');
const html = renderToStaticMarkup(element);
console.log(html.replace(/ class="[^"]*"/g, '').replaceAll('><', '>\n<'));
const title = html.match(/class="(css-text[^"]*)"/)[1].split(' ');
for (let i = 0; i < title.length; i += 4) console.log(title.slice(i, i + 4).join(' '));
Output
...
<button role="button" tabindex="0" type="button">
<div>
<div dir="auto">The Quiet Harbor</div>
<div dir="auto">$14.99</div>
...
css-text-146c3p1 r-maxWidth-dnmrzs r-overflow-1udh08x r-textOverflow-1udbk01
r-whiteSpace-3s2u2q r-wordWrap-1iln25a r-fontSize-ubezar r-fontWeight-1kfrs79

Each View becomes a div whose base class restores React Native's layout defaults (flex, column direction, no shrinking), Text becomes a div with dir="auto", and a Pressable with the button role becomes a real, focusable <button>. StyleSheet compiles every declaration into a shared atomic class, and numberOfLines={1} turns into nowrap with an ellipsis. Text stays selectable and hover exists, and two things differ more deeply: