# React Strict DOM (RSD) - LLM Guide
React Strict DOM is a cross-platform JavaScript library that provides React components based on web standards (W3C, React DOM). Write once using HTML, CSS, and DOM APIs that work on web and React Native (Android/iOS).
**Key characteristics:**
- Strict subset of React DOM and Web APIs
- Under 2 KB runtime on web, generates atomic CSS
- Renders platform-native UI elements
- Unified types across platforms (e.g., `HTMLElement`)
## Installation
```bash
npm install react-strict-dom
```
**Dependencies:** `react` + `react-dom` (web) or `react-native` (native)
**Setup (required):**
- Babel: `react-strict-dom/babel-preset`
- PostCSS: `react-strict-dom/postcss-plugin` (web)
- Import CSS file with `@react-strict-dom` directive
- Root element: `data-layoutconformance="strict"`
## Core Differences from React DOM
```jsx
// React DOM
import React from 'react';
function App() {
return
Hello
;
}
// React Strict DOM
import { html, css } from 'react-strict-dom';
const styles = css.create({
root: { padding: 16, backgroundColor: 'white' }
});
function App() {
return Hello;
}
```
**Key Changes:**
1. **Elements:** Use ``, ``, etc.
2. **Styling:** No `className` - use `style` prop with `css.create()` only
3. **Props:** Use `for` NOT `htmlFor`, `role="none"` NOT `role="presentation"`
4. **Refs:** Use ref callbacks, not `useRef` objects
5. **Events:** Only bubble phase on elements (use EventTarget API for capture)
## Styling System
### Basic Styles
```jsx
import { css, html } from 'react-strict-dom';
const styles = css.create({
container: {
padding: 16,
backgroundColor: 'white',
borderRadius: 8
}
});
Content
```
### Pseudo-states
Nest within properties. `default` is required.
```jsx
const styles = css.create({
button: {
backgroundColor: {
default: 'lightblue',
':hover': 'blue',
':focus': 'darkblue',
':active': 'navy'
}
}
});
```
**Supported:** `:hover`, `:focus`, `:active`, `::placeholder` (color only)
### Media Queries
```jsx
const styles = css.create({
container: {
width: {
default: 320,
'@media (min-width: 768px)': 600,
'@media (min-width: 1024px)': 800
},
color: {
default: 'black',
'@media (prefers-color-scheme: dark)': 'white'
}
}
});
```
**Supported:** Dimension queries, `prefers-color-scheme`, `prefers-reduced-motion`
### Merging & Conditional Styles
```jsx
```
### Dynamic Styles
```jsx
const styles = css.create({
dynamicSize: (height, width) => ({
height: height * 0.9,
width
})
});
```
**Limitations:** Arrow syntax, object literal body, simple identifier params
### Fallback Values
```jsx
const styles = css.create({
header: {
position: css.firstThatWorks('sticky', 'fixed')
}
});
```
### Shortform Properties
Only single values: `margin: 16` ✓ | `margin: "16px 8px"` ✗
## Theming
### Define Variables (*.css.{js,jsx,ts,tsx})
```jsx
// tokens.css.js
import { css } from 'react-strict-dom';
export const colors = css.defineVars({
primary: {
default: 'blue',
'@media (prefers-color-scheme: dark)': 'lightblue'
},
background: {
default: 'white',
'@media (prefers-color-scheme: dark)': 'black'
}
});
```
### Use Variables
```jsx
import { colors } from './tokens.css.js';
const styles = css.create({
container: {
color: colors.primary,
backgroundColor: colors.background
}
});
```
### Create & Apply Themes
```jsx
// theme.js
export const darkTheme = css.createTheme(colors, {
primary: 'purple',
background: '#222'
});
// App.js
{/* All children use themed variables */}
```
## HTML Elements & Props
**Available elements:** `div`, `span`, `p`, `h1`-`h6`, `button`, `input`, `textarea`, `img`, `a`, `ul`, `ol`, `li`, `section`, `article`, `header`, `footer`, `nav`, `main`, and more.
**Common props:** `style`, `children`, `aria-*`, `data-*`, `data-testid`, `dir`, `hidden`, `id`, `lang`, `role`, `ref`, `tabIndex` (0 or -1)
**Common events:** `onClick`, `onPointerDown/Up/Move`, `onKeyDown/Up`, `onFocus/Blur`, `onScroll`, `onCopy/Cut/Paste`
**Examples:**
```jsx
// Button
{}}>Click
// Input
setText(e.target.value)} placeholder="Text" maxLength={100} />
// Image
// Link
Link
```
## DOM APIs
Use ref callbacks for element access:
```jsx
{
if (node) {
// Measurement
node.getBoundingClientRect();
node.offsetHeight;
node.clientWidth;
// Traversal
node.parentElement;
node.children;
node.nextSibling;
// Interaction
node.focus();
node.blur();
node.scrollTop;
node.scrollLeft;
}
}}>Content
```
## Native Platform Integration (compat.native)
Use in `*.native.js` files to wrap React Native components:
```jsx
import type { TextProps } from 'react-native';
import { compat } from 'react-strict-dom';
import { Text } from 'react-native';
function CustomText(props) {
return (
{(nativeProps: TextProps) => (
{props.children}
)}
);
}
```
**Element mapping via `as`:**
- `as="span"` → Text
- `as="div"` → Container/Pressable
- `as="img"` → Image
- `as="input"` → Single-line TextInput
- `as="textarea"` → Multi-line TextInput
**Rules:**
- ✓ Type `nativeProps` with React Native type
- ✓ Spread entire `nativeProps` object
- ✗ Don't destructure `nativeProps`
## Cross-Platform Constraints
### Display
**Supported:** `flex`, `none`, `contents`, `block` (partial)
**Not supported:** `inline`, `inline-block`, `inline-flex`, `grid`
### Position
**Supported:** `relative`, `absolute`, `static`
**Not on native:** `fixed`, `sticky`
### Limitations
- No flow/grid layout or inline flexbox on native
- No margin collapse
- No `calc()`, `min()`, `max()`, `clamp()`
- No `url()` values
- No 3D transforms
- No animation properties (use React Native Animated)
- Background: only `backgroundColor` and `backgroundImage` (gradients)
### Units
**Supported:** Numbers (px), `%`, `rem`, `em`, `vh`, `vw`, `vmin`, `vmax`
## Migration Guide: React DOM → RSD
### 1. Change Imports
```jsx
// Before:
import React from 'react';
// After:
import { html, css } from 'react-strict-dom';
```
### 2. Convert Elements & Styles
```jsx
// Before
import styles from './styles.module.css';