|
| 1 | +# react-native-css Development Guide |
| 2 | + |
| 3 | +## Project Overview |
| 4 | + |
| 5 | +A standalone CSS polyfill for React Native. Part of the Nativewind v5 ecosystem but can function independently of Tailwind CSS. Provides direct `.css` file support in React Native apps. |
| 6 | + |
| 7 | +### Relationship to Nativewind |
| 8 | + |
| 9 | +- **Nativewind** (`github.com/nativewind/nativewind`, main branch) provides the Tailwind CSS integration layer |
| 10 | +- **This repo** provides the underlying CSS-to-React-Native engine |
| 11 | +- Both are part of the v5 story, but this repo has no Tailwind dependency |
| 12 | + |
| 13 | +## Architecture |
| 14 | + |
| 15 | +``` |
| 16 | +.css file |
| 17 | + ↓ |
| 18 | +Metro Transformer (src/metro/metro-transformer.ts) |
| 19 | + ↓ delegates to Expo's CSS transformer |
| 20 | +lightningcss parses CSS AST |
| 21 | + ↓ |
| 22 | +compile() in src/compiler/compiler.ts |
| 23 | + ├→ parseMediaQuery() — media query conditions |
| 24 | + ├→ parseContainerCondition() — container queries |
| 25 | + ├→ parseDeclaration() — CSS properties → RN properties |
| 26 | + ├→ extractKeyFrames() — animation extraction |
| 27 | + └→ inlineVariables() — CSS variable optimization |
| 28 | + ↓ |
| 29 | +ReactNativeCssStyleSheet (JSON) |
| 30 | + ↓ |
| 31 | +getNativeInjectionCode() (src/metro/injection-code.ts) |
| 32 | + ↓ |
| 33 | +Native runtime consumes via StyleCollection |
| 34 | +``` |
| 35 | + |
| 36 | +### Babel Plugin |
| 37 | + |
| 38 | +The Babel plugin (`src/babel/react-native.ts`) rewrites React Native imports: |
| 39 | +``` |
| 40 | +import { View } from 'react-native' |
| 41 | + → import { View } from 'react-native-css/components' |
| 42 | +``` |
| 43 | +This enables `className` prop support on all React Native components. |
| 44 | + |
| 45 | +### Key Architectural Patterns |
| 46 | + |
| 47 | +- **Reactive style system** (`src/native/reactivity.ts`) — custom observables for media queries, container queries, color scheme changes |
| 48 | +- **StyleCollection singleton** (`src/native-internal/`) — isolated to prevent circular dependencies between native runtime and CSS file imports |
| 49 | +- **Platform-aware compilation** — different outputs for native (JSON) vs web (browser CSS) |
| 50 | +- **Inline variable optimization** — single-use CSS variables are inlined at compile time; multi-use preserved |
| 51 | + |
| 52 | +## Package Entry Points |
| 53 | + |
| 54 | +| Import | Purpose | |
| 55 | +|--------|---------| |
| 56 | +| `react-native-css` | Runtime API | |
| 57 | +| `react-native-css/compiler` | CSS-to-JSON compiler | |
| 58 | +| `react-native-css/babel` | Babel plugin for import transformation | |
| 59 | +| `react-native-css/metro` | `withReactNativeCSS()` Metro config | |
| 60 | +| `react-native-css/components` | Pre-wrapped RN components with className support | |
| 61 | +| `react-native-css/jest` | Jest test utilities | |
| 62 | +| `react-native-css/native` | Native runtime API | |
| 63 | +| `react-native-css/web` | Web runtime API | |
| 64 | + |
| 65 | +## Key Directories |
| 66 | + |
| 67 | +``` |
| 68 | +src/ |
| 69 | +├── babel/ # Babel plugin (rewrites RN imports) |
| 70 | +├── compiler/ # CSS compilation engine (lightningcss-based) |
| 71 | +│ ├── compiler.ts # Main entry |
| 72 | +│ ├── declarations.ts # CSS property handling |
| 73 | +│ ├── selectors.ts # Selector parsing |
| 74 | +│ ├── media-query.ts # Media query parsing |
| 75 | +│ ├── container-query.ts |
| 76 | +│ ├── keyframes.ts # Animation extraction |
| 77 | +│ └── inline-variables.ts |
| 78 | +├── metro/ # Metro bundler integration |
| 79 | +│ ├── metro-transformer.ts # Custom JS/CSS transformer |
| 80 | +│ ├── resolver.ts # Module resolution |
| 81 | +│ └── typescript.ts # TypeScript env generation |
| 82 | +├── native/ # Native runtime (iOS/Android) |
| 83 | +│ ├── api.tsx # styled(), useCssElement(), hooks |
| 84 | +│ ├── reactivity.ts # Observable/reactive system |
| 85 | +│ ├── styles/ # Runtime style resolution |
| 86 | +│ ├── conditions/ # Media/container query evaluation |
| 87 | +│ └── react/ # React integration hooks |
| 88 | +├── native-internal/ # Shared singletons (avoids circular deps) |
| 89 | +│ ├── root.ts # Global style collection root |
| 90 | +│ ├── style-collection.ts |
| 91 | +│ └── variables.tsx # CSS variable context |
| 92 | +├── web/ # Web runtime |
| 93 | +├── components/ # Pre-wrapped RN components (View, Text, etc.) |
| 94 | +└── utilities/ # Type utilities (dot notation) |
| 95 | +``` |
| 96 | + |
| 97 | +## Commands |
| 98 | + |
| 99 | +```bash |
| 100 | +yarn # Install dependencies (npm is NOT supported) |
| 101 | +yarn build # Build with react-native-builder-bob |
| 102 | +yarn test # Run tests (Jest with ESM) |
| 103 | +yarn typecheck # TypeScript validation |
| 104 | +yarn lint --fix # ESLint + Prettier |
| 105 | +yarn clean # Install deps, rebuild project and example app |
| 106 | +``` |
| 107 | + |
| 108 | +### Example App |
| 109 | + |
| 110 | +```bash |
| 111 | +yarn example ios # Build and run on iOS |
| 112 | +yarn example android # Build and run on Android |
| 113 | +yarn example start # Start Metro server |
| 114 | +yarn example start:build # Rebuild library + start Metro (clears cache) |
| 115 | +yarn example start:debug # Rebuild + start with debug logging |
| 116 | +``` |
| 117 | + |
| 118 | +## Testing |
| 119 | + |
| 120 | +- **Runner:** Jest with experimental ESM support (`NODE_OPTIONS="--experimental-vm-modules"`) |
| 121 | +- **Convention:** Tests in `src/__tests__/` organized by domain (`babel/`, `compiler/`, `native/`) |
| 122 | +- **Babel tests** use `babel-plugin-tester` |
| 123 | +- **Compiler tests** verify JSON output structure |
| 124 | +- **Run specific suites:** `yarn test babel`, `yarn test compiler` |
| 125 | +- Ignore `ExperimentalWarning: VM Modules` warnings — expected with ESM support |
| 126 | + |
| 127 | +## Code Conventions |
| 128 | + |
| 129 | +- TypeScript throughout |
| 130 | +- **Yarn v4 only** — npm is not supported (enforced via `packageManager` field) |
| 131 | +- Conventional commits required: `feat:`, `fix:`, `refactor:`, `docs:`, `test:`, `chore:` |
| 132 | +- Pre-commit hooks enforce linting and commit message format |
| 133 | +- Publishing via `release-it` |
| 134 | + |
| 135 | +## Common Pitfalls |
| 136 | + |
| 137 | +- **No npm** — this repo uses Yarn workspaces; `npm install` will not work |
| 138 | +- **No rebuild watch** — use `yarn example start:build` to rebuild + start in one command |
| 139 | +- **Metro transformer / Babel plugin changes require full rebuild** — no fast refresh for these |
| 140 | +- **native-internal exists to break circular deps** — don't import directly from `native/` in CSS file outputs; use `native-internal/` |
| 141 | +- **Nested node_modules in example/** — can cause Metro issues; ensure dependency versions match root |
0 commit comments