@ranimontagna/agent-toolkit 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/README.md +42 -8
  2. package/package.json +1 -1
  3. package/skills/frontend/react/react-patterns/LICENSE +21 -0
  4. package/skills/frontend/react/react-patterns/NOTICE.md +11 -0
  5. package/skills/frontend/react/react-patterns/SKILL.md +341 -0
  6. package/skills/frontend/react/react-performance/LICENSE +21 -0
  7. package/skills/frontend/react/react-performance/NOTICE.md +11 -0
  8. package/skills/frontend/react/react-performance/SKILL.md +574 -0
  9. package/skills/frontend/react/react-testing/LICENSE +21 -0
  10. package/skills/frontend/react/react-testing/NOTICE.md +11 -0
  11. package/skills/frontend/react/react-testing/SKILL.md +423 -0
  12. package/skills/frontend/react-native/react-native-expert/LICENSE +21 -0
  13. package/skills/frontend/react-native/react-native-expert/NOTICE.md +11 -0
  14. package/skills/frontend/react-native/react-native-expert/SKILL.md +187 -0
  15. package/skills/frontend/react-native/react-native-expert/references/expo-router.md +187 -0
  16. package/skills/frontend/react-native/react-native-expert/references/list-optimization.md +204 -0
  17. package/skills/frontend/react-native/react-native-expert/references/platform-handling.md +188 -0
  18. package/skills/frontend/react-native/react-native-expert/references/project-structure.md +171 -0
  19. package/skills/frontend/react-native/react-native-expert/references/storage-hooks.md +173 -0
  20. package/skills/frontend/react-native/react-native-unistyles-v3/LICENSE +21 -0
  21. package/skills/frontend/react-native/react-native-unistyles-v3/NOTICE.md +11 -0
  22. package/skills/frontend/react-native/react-native-unistyles-v3/SKILL.md +159 -0
  23. package/skills/frontend/react-native/react-native-unistyles-v3/references/api-reference.md +495 -0
  24. package/skills/frontend/react-native/react-native-unistyles-v3/references/common-issues.md +389 -0
  25. package/skills/frontend/react-native/react-native-unistyles-v3/references/setup-guide.md +217 -0
  26. package/skills/frontend/react-native/react-native-unistyles-v3/references/styling-patterns.md +705 -0
  27. package/skills/frontend/react-native/react-native-unistyles-v3/references/third-party-integration.md +318 -0
@@ -0,0 +1,389 @@
1
+ # Common Issues
2
+
3
+ Curated from 150+ GitHub issues. Organized by category with symptoms, causes, and solutions.
4
+
5
+ ---
6
+
7
+ ## 1. Setup & Initialization
8
+
9
+ ### "Unistyles was loaded but not configured" after hot reload
10
+
11
+ **Symptoms:** Error appears after fast refresh / hot reload, not on cold start.
12
+ **Cause:** `StyleSheet.configure()` runs in a module scope that doesn't re-execute on HMR.
13
+ **Solution:** Ensure `StyleSheet.configure()` is imported in your entry point file. For Expo Router, follow the [Expo Router integration steps](setup-guide.md#expo-router-integration).
14
+ **Ref:** [#1098](https://github.com/jpudysz/react-native-unistyles/issues/1098)
15
+
16
+ ### "Unistyles not initialized correctly"
17
+
18
+ **Symptoms:** Crash on app start.
19
+ **Cause:** `StyleSheet.create()` is called before `StyleSheet.configure()`.
20
+ **Solution:** Move `StyleSheet.configure()` to your app's entry point, before any component imports that use `StyleSheet.create`.
21
+ **Ref:** [#1010](https://github.com/jpudysz/react-native-unistyles/issues/1010)
22
+
23
+ ### StyleSheet.configure timing with Expo Router
24
+
25
+ **Symptoms:** Styles don't work or "not configured" error with Expo Router.
26
+ **Cause:** Expo Router resolves routes before your config runs.
27
+ **Solution:**
28
+ 1. Set `"main": "index.ts"` in package.json
29
+ 2. Create `index.ts` with:
30
+ ```ts
31
+ import './unistyles' // configure first
32
+ import 'expo-router/entry'
33
+ ```
34
+ 3. For static rendering, also import config in `app/+html.tsx`
35
+
36
+ ### "Property value expected type of number but got null" for hasAdaptiveThemes
37
+
38
+ **Symptoms:** Runtime error mentioning `hasAdaptiveThemes` property.
39
+ **Cause:** `adaptiveThemes` set to `true` without both `light` and `dark` themes registered.
40
+ **Solution:** Ensure themes object has keys named exactly `light` and `dark`:
41
+ ```tsx
42
+ StyleSheet.configure({
43
+ themes: { light: lightTheme, dark: darkTheme },
44
+ settings: { adaptiveThemes: true }
45
+ })
46
+ ```
47
+ **Ref:** [#1040](https://github.com/jpudysz/react-native-unistyles/issues/1040)
48
+
49
+ ---
50
+
51
+ ## 2. Style Spreading (Most Common Issue)
52
+
53
+ ### "Style is not bound!" error
54
+
55
+ **Symptoms:** Runtime error "Style is not bound!" or styles not applying.
56
+ **Cause:** Spreading Unistyles styles with `{...styles.x}`. v3 styles are C++ proxy objects — spreading breaks the native binding.
57
+ **Solution:** ALWAYS use array syntax:
58
+ ```tsx
59
+ // WRONG
60
+ <View style={{ ...styles.container, ...styles.extra }} />
61
+ <View style={{ ...styles.container, marginTop: 10 }} />
62
+
63
+ // CORRECT
64
+ <View style={[styles.container, styles.extra]} />
65
+ <View style={[styles.container, { marginTop: 10 }]} />
66
+ ```
67
+
68
+ ### Spreading in useAnimatedStyle callbacks
69
+
70
+ **Symptoms:** Animated styles don't update or crash.
71
+ **Cause:** Spreading Unistyles styles inside `useAnimatedStyle`.
72
+ **Solution:** Use array syntax when combining:
73
+ ```tsx
74
+ // WRONG
75
+ const animStyle = useAnimatedStyle(() => ({ ...styles.box }))
76
+
77
+ // CORRECT
78
+ <Animated.View style={[styles.box, animStyle]} />
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 3. Babel Plugin Issues
84
+
85
+ ### Re-exporting StyleSheet from barrel files
86
+
87
+ **Symptoms:** Styles not reactive; theme changes have no effect.
88
+ **Cause:** The Babel plugin detects `StyleSheet.create` by checking the import source is `react-native-unistyles`. Re-exporting through a barrel file (e.g., `export { StyleSheet } from 'react-native-unistyles'` in `utils/index.ts`) breaks detection.
89
+ **Solution:** Always import directly:
90
+ ```tsx
91
+ // WRONG
92
+ import { StyleSheet } from '@/utils' // barrel re-export
93
+
94
+ // CORRECT
95
+ import { StyleSheet } from 'react-native-unistyles'
96
+ ```
97
+
98
+ ### Plugin interferes with other .create() calls
99
+
100
+ **Symptoms:** Other libraries' `.create()` calls break (e.g., Zustand, custom factories).
101
+ **Cause:** The Babel plugin processes any `StyleSheet.create()` it finds.
102
+ **Solution:** The plugin only processes `StyleSheet.create()` when `StyleSheet` is imported from `react-native-unistyles`. If you have a different `StyleSheet` variable, rename it to avoid collision.
103
+ **Ref:** [#993](https://github.com/jpudysz/react-native-unistyles/issues/993)
104
+
105
+ ### Wrong root directory
106
+
107
+ **Symptoms:** Styles not reactive; Babel plugin appears to do nothing.
108
+ **Cause:** The `root` option in Babel config resolves to the project root or an incorrect directory.
109
+ **Solution:** `root` must point to your **source code directory**, not the project root:
110
+ ```js
111
+ // WRONG — root resolves to project root
112
+ ['react-native-unistyles/plugin', { root: '.' }]
113
+ ['react-native-unistyles/plugin', { root: '' }]
114
+
115
+ // CORRECT
116
+ ['react-native-unistyles/plugin', { root: 'src' }]
117
+ ['react-native-unistyles/plugin', { root: 'app' }] // for Expo Router
118
+ ```
119
+
120
+ ### Files outside root not processed
121
+
122
+ **Symptoms:** Shared package styles not reactive.
123
+ **Cause:** Only files inside `root` are processed by default.
124
+ **Solution:** Add `autoProcessPaths` for additional directories:
125
+ ```js
126
+ ['react-native-unistyles/plugin', {
127
+ root: 'src',
128
+ autoProcessPaths: ['../packages/shared/src']
129
+ }]
130
+ ```
131
+
132
+ ---
133
+
134
+ ## 4. Theme Updates Not Propagating
135
+
136
+ ### Nested Text components + Reanimated conflict
137
+
138
+ **Symptoms:** Nested `<Text>` components don't update color when theme changes while using Reanimated.
139
+ **Cause:** Reanimated's animated components can interfere with Unistyles' ShadowTree updates on nested text.
140
+ **Solution:** Ensure nested Text components have explicit style bindings. If using Reanimated, avoid wrapping Text in Animated containers for theme-dependent colors.
141
+ **Ref:** [#1045](https://github.com/jpudysz/react-native-unistyles/issues/1045)
142
+
143
+ ### ScopedTheme not applied to dynamic children
144
+
145
+ **Symptoms:** Items rendered inside `<ScopedTheme>` after mount don't pick up the scoped theme.
146
+ **Cause:** ScopedTheme applies at mount time. Dynamically added children (e.g., FlatList items) may not inherit.
147
+ **Status:** WONTFIX — by design.
148
+ **Workaround:** Wrap each dynamically rendered item in its own `<ScopedTheme>`:
149
+ ```tsx
150
+ <ScopedTheme name="dark">
151
+ {items.map(item => (
152
+ <ScopedTheme key={item.id} name="dark">
153
+ <ItemCard item={item} />
154
+ </ScopedTheme>
155
+ ))}
156
+ </ScopedTheme>
157
+ ```
158
+ **Ref:** [#955](https://github.com/jpudysz/react-native-unistyles/issues/955)
159
+
160
+ ### Reanimated CSS transitions stale colors
161
+
162
+ **Symptoms:** After theme switch, CSS transition colors show the old theme's value.
163
+ **Cause:** Reanimated CSS transitions cache the initial color value.
164
+ **Solution:** Use `key={rt.themeName}` to force re-mount on theme change:
165
+ ```tsx
166
+ const { rt } = useUnistyles()
167
+ <Animated.View key={rt.themeName} style={styles.card} />
168
+ ```
169
+ **Ref:** [#1007](https://github.com/jpudysz/react-native-unistyles/issues/1007)
170
+
171
+ ### withUnistyles not always updating
172
+
173
+ **Symptoms:** Wrapped component doesn't re-render when theme changes.
174
+ **Cause:** The wrapped component may have internal memoization preventing updates.
175
+ **Solution:** Pass `key` prop tied to theme:
176
+ ```tsx
177
+ const UniButton = withUnistyles(Button, (theme) => ({
178
+ color: theme.colors.primary,
179
+ key: theme.colors.primary, // force update
180
+ }))
181
+ ```
182
+ **Ref:** [#980](https://github.com/jpudysz/react-native-unistyles/issues/980)
183
+
184
+ ### Theme reverts after app background on Android
185
+
186
+ **Symptoms:** Theme resets to initial theme when app returns from background.
187
+ **Cause:** Android activity recreation can re-trigger initialization.
188
+ **Solution:** Use `adaptiveThemes: true` if following OS theme, or persist theme choice and use `initialTheme: () => getStoredTheme()`.
189
+ **Ref:** [#963](https://github.com/jpudysz/react-native-unistyles/issues/963)
190
+
191
+ ---
192
+
193
+ ## 5. Android-Specific
194
+
195
+ ### FlatList crash on orientation change
196
+
197
+ **Symptoms:** App crashes when rotating device while FlatList is visible.
198
+ **Cause:** React Native core FlatList issue, not Unistyles-specific.
199
+ **Solution:** Use FlashList or Legend List instead of FlatList.
200
+ **Ref:** [#803](https://github.com/jpudysz/react-native-unistyles/issues/803)
201
+
202
+ ### Keyboard inset lag with react-native-keyboard-controller
203
+
204
+ **Symptoms:** `rt.insets.ime` lags behind actual keyboard position.
205
+ **Cause:** Conflict between Unistyles' IME tracking and react-native-keyboard-controller.
206
+ **Solution:** Use only one keyboard tracking solution. Prefer `rt.insets.ime` and remove `react-native-keyboard-controller`, or vice versa.
207
+ **Ref:** [#1065](https://github.com/jpudysz/react-native-unistyles/issues/1065)
208
+
209
+ ### CMake build failures
210
+
211
+ **Symptoms:** Build fails with CMake errors on Android.
212
+ **Cause:** Various CMake configuration issues, often related to NDK version or build tools.
213
+ **Solution:** Ensure you're using a compatible NDK version. Clean build:
214
+ ```bash
215
+ cd android && ./gradlew clean && cd ..
216
+ npx react-native run-android
217
+ ```
218
+ **Ref:** [#1058](https://github.com/jpudysz/react-native-unistyles/issues/1058), [#889](https://github.com/jpudysz/react-native-unistyles/issues/889), [#1013](https://github.com/jpudysz/react-native-unistyles/issues/1013)
219
+
220
+ ### Screen orientation not updating runtime values
221
+
222
+ **Symptoms:** `rt.screen.width` / `rt.screen.height` don't update on rotation.
223
+ **Cause:** Missing orientation listener setup or Android activity configuration.
224
+ **Solution:** Ensure your AndroidManifest.xml allows orientation changes:
225
+ ```xml
226
+ <activity android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|uiMode" />
227
+ ```
228
+ **Ref:** [#1033](https://github.com/jpudysz/react-native-unistyles/issues/1033)
229
+
230
+ ---
231
+
232
+ ## 6. Web-Specific
233
+
234
+ ### SSR hydration mismatches
235
+
236
+ **Symptoms:** React hydration warnings on page load with SSR.
237
+ **Cause:** Server-rendered styles don't match client-side computed styles.
238
+ **Solution:** Use the SSR utilities:
239
+ ```tsx
240
+ // Server: inject styles
241
+ const styles = useServerUnistyles() // or getServerUnistyles()
242
+
243
+ // Client: hydrate
244
+ hydrateServerUnistyles()
245
+ ```
246
+
247
+ ### Safari 16.3 and below not supported
248
+
249
+ **Symptoms:** Styles broken or app crashes on older Safari.
250
+ **Cause:** Unistyles v3 web implementation uses features not available in Safari < 16.4.
251
+ **Solution:** Require Safari 16.4+ or provide a fallback.
252
+ **Ref:** [#1073](https://github.com/jpudysz/react-native-unistyles/issues/1073)
253
+
254
+ ### Styles not working on Reanimated Animated.View on web
255
+
256
+ **Symptoms:** Animated.View doesn't receive Unistyles styles on web platform.
257
+ **Cause:** Reanimated's web implementation may not forward the style processing correctly.
258
+ **Solution:** Use `getWebProps` or apply styles differently on web.
259
+ **Ref:** [#1014](https://github.com/jpudysz/react-native-unistyles/issues/1014)
260
+
261
+ ### Gap polyfill incorrect margins on SmartTV
262
+
263
+ **Symptoms:** `gap` property produces wrong spacing on SmartTV web browsers.
264
+ **Cause:** Polyfill for `gap` uses margins which behave differently on some TV browsers.
265
+ **Solution:** Use explicit margin/padding instead of `gap` for TV targets.
266
+ **Ref:** [#1091](https://github.com/jpudysz/react-native-unistyles/issues/1091)
267
+
268
+ ---
269
+
270
+ ## 7. TypeScript Issues
271
+
272
+ ### boxShadow array in variants incorrect return type
273
+
274
+ **Symptoms:** TypeScript error when using `boxShadow` array inside variant styles.
275
+ **Cause:** Type inference doesn't correctly handle arrays inside variant branches.
276
+ **Workaround:** Cast with `as any` or extract the shadow to a const:
277
+ ```tsx
278
+ const shadow = [{ offsetX: 0, offsetY: 2, blurRadius: 4, color: 'rgba(0,0,0,0.1)' }]
279
+
280
+ variants: {
281
+ elevated: {
282
+ true: { boxShadow: shadow as any },
283
+ },
284
+ }
285
+ ```
286
+ **Ref:** [#1047](https://github.com/jpudysz/react-native-unistyles/issues/1047)
287
+
288
+ ### withUnistyles inference failures
289
+
290
+ **Symptoms:** TypeScript can't infer prop types when using `withUnistyles`.
291
+ **Cause:** Complex generic inference in the HOC type.
292
+ **Workaround:** Explicitly type the component:
293
+ ```tsx
294
+ const UniButton = withUnistyles<typeof Button, { color: string }>(
295
+ Button,
296
+ (theme) => ({ color: theme.colors.primary })
297
+ )
298
+ ```
299
+ **Ref:** [#1008](https://github.com/jpudysz/react-native-unistyles/issues/1008)
300
+
301
+ ### Variant categories with different shapes
302
+
303
+ **Symptoms:** TypeScript errors when variant categories have different style properties.
304
+ **Cause:** TypeScript tries to unify all variant branch types.
305
+ **Workaround:** Ensure all branches in a variant category have compatible types, or use type assertions.
306
+ **Ref:** [#1052](https://github.com/jpudysz/react-native-unistyles/issues/1052)
307
+
308
+ ---
309
+
310
+ ## 8. React Compiler
311
+
312
+ ### useVariants breaks with panicThreshold: 'all_errors'
313
+
314
+ **Symptoms:** Build error or runtime crash when using `styles.useVariants()` with React Compiler `panicThreshold: 'all_errors'`.
315
+ **Cause:** React Compiler can't analyze the `useVariants` call pattern.
316
+ **Status:** Known issue, planned fix in v4.
317
+ **Workaround:** Use `panicThreshold: 'none'` (default) or `'critical_errors'`.
318
+ **Ref:** [#1002](https://github.com/jpudysz/react-native-unistyles/issues/1002)
319
+
320
+ ### Plugin ordering
321
+
322
+ **Symptoms:** Styles not reactive, build errors.
323
+ **Cause:** React Compiler runs before Unistyles plugin.
324
+ **Solution:** Unistyles plugin MUST come BEFORE React Compiler in babel.config.js:
325
+ ```js
326
+ plugins: [
327
+ ['react-native-unistyles/plugin', { root: 'src' }], // FIRST
328
+ 'babel-plugin-react-compiler', // SECOND
329
+ ]
330
+ ```
331
+
332
+ ---
333
+
334
+ ## 9. Performance
335
+
336
+ ### useUnistyles causes re-renders
337
+
338
+ **Symptoms:** Excessive re-renders, especially on theme/orientation changes.
339
+ **Cause:** `useUnistyles()` subscribes to theme and runtime changes, triggering re-renders.
340
+ **Solution:** Prefer `StyleSheet.create(theme => ...)` which uses zero-re-render C++ updates. Reserve `useUnistyles()` for cases where you need theme/runtime in JS logic.
341
+
342
+ ### Variant memory in long lists
343
+
344
+ **Symptoms:** High memory usage or slow performance when using variants in long list items.
345
+ **Cause:** Each list item with `useVariants()` maintains its own variant state.
346
+ **Solution:** Use dynamic functions instead of variants for list items:
347
+ ```tsx
348
+ // Instead of variants:
349
+ const styles = StyleSheet.create(theme => ({
350
+ item: (isActive: boolean) => ({
351
+ backgroundColor: isActive ? theme.colors.active : theme.colors.surface,
352
+ }),
353
+ }))
354
+
355
+ // Usage in list item:
356
+ <View style={styles.item(isActive)} />
357
+ ```
358
+ **Ref:** [#1034](https://github.com/jpudysz/react-native-unistyles/issues/1034)
359
+
360
+ ### Tab navigation slow theme change
361
+
362
+ **Symptoms:** Theme change takes noticeable time with many tab screens.
363
+ **Cause:** Many mounted stylesheets updating simultaneously.
364
+ **Solution:** Use `adaptiveThemes` for smooth OS-level transitions, or batch theme updates.
365
+ **Ref:** [#1107](https://github.com/jpudysz/react-native-unistyles/issues/1107)
366
+
367
+ ---
368
+
369
+ ## 10. Third-Party Library Conflicts
370
+
371
+ ### Pressable from react-native-gesture-handler stale theme
372
+
373
+ **Symptoms:** `Pressable` from `react-native-gesture-handler` doesn't update on theme change.
374
+ **Cause:** RNGH's Pressable doesn't go through the standard React Native style processing that Unistyles hooks into.
375
+ **Solution:** Use React Native's built-in `Pressable` or wrap RNGH's Pressable with `withUnistyles`:
376
+ ```tsx
377
+ import { Pressable as GHPressable } from 'react-native-gesture-handler'
378
+ import { withUnistyles } from 'react-native-unistyles'
379
+
380
+ const Pressable = withUnistyles(GHPressable)
381
+ ```
382
+ **Ref:** [#1109](https://github.com/jpudysz/react-native-unistyles/issues/1109)
383
+
384
+ ### withUnistyles wraps elements on RN Web breaking SVG composition
385
+
386
+ **Symptoms:** SVG elements break when parent is wrapped with `withUnistyles` on web.
387
+ **Cause:** `withUnistyles` wraps the component in an additional View on web, breaking SVG's direct parent-child relationship.
388
+ **Solution:** Use `useUnistyles()` hook instead for SVG containers, or apply styles directly.
389
+ **Ref:** [#1087](https://github.com/jpudysz/react-native-unistyles/issues/1087)
@@ -0,0 +1,217 @@
1
+ # Setup Guide
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ npm install react-native-unistyles react-native-nitro-modules
7
+ # or
8
+ yarn add react-native-unistyles react-native-nitro-modules
9
+ ```
10
+
11
+ Then rebuild your native project:
12
+ ```bash
13
+ npx pod-install # iOS
14
+ npx react-native run-android # Android
15
+ ```
16
+
17
+ ## Babel Plugin Configuration
18
+
19
+ The Babel plugin is **mandatory**. It transforms `StyleSheet.create` calls at build time to enable zero-re-render reactivity.
20
+
21
+ ```js
22
+ // babel.config.js
23
+ module.exports = {
24
+ presets: ['module:@react-native/babel-preset'],
25
+ plugins: [
26
+ ['react-native-unistyles/plugin', {
27
+ root: 'src' // REQUIRED: directory containing your app source code
28
+ }]
29
+ ]
30
+ }
31
+ ```
32
+
33
+ ### Plugin options
34
+
35
+ | Option | Type | Description |
36
+ |--------|------|-------------|
37
+ | `root` | `string` | **Required.** Path to your source code root (relative to project root). Only files in this directory are processed. Must NOT resolve to the project root itself. |
38
+ | `autoProcessPaths` | `string[]` | Additional directories outside `root` to process (e.g., shared packages in a monorepo). |
39
+ | `autoProcessImports` | `string[]` | Additional package names whose imports trigger processing (e.g., `['@myorg/ui']`). |
40
+ | `autoRemapImports` | `Record<string, Record<string, string>>` | Map exotic component imports to Unistyles component factories. |
41
+ | `debug` | `boolean` | Enable debug logging to see which files are processed. Default: `false`. |
42
+
43
+ ### Example: Monorepo with shared packages
44
+
45
+ ```js
46
+ // babel.config.js
47
+ module.exports = {
48
+ plugins: [
49
+ ['react-native-unistyles/plugin', {
50
+ root: 'src',
51
+ autoProcessPaths: ['../shared-ui/src'],
52
+ autoProcessImports: ['@myorg/shared-ui']
53
+ }]
54
+ ]
55
+ }
56
+ ```
57
+
58
+ ### React Compiler ordering
59
+
60
+ If using React Compiler, the Unistyles plugin **MUST come BEFORE** React Compiler:
61
+
62
+ ```js
63
+ // babel.config.js
64
+ module.exports = {
65
+ plugins: [
66
+ ['react-native-unistyles/plugin', { root: 'src' }], // FIRST
67
+ 'babel-plugin-react-compiler', // SECOND
68
+ ]
69
+ }
70
+ ```
71
+
72
+ ## StyleSheet.configure
73
+
74
+ Call **once** before any component renders. Typically in your app entry point file.
75
+
76
+ ```tsx
77
+ import { StyleSheet } from 'react-native-unistyles'
78
+ import { lightTheme, darkTheme } from './themes'
79
+ import { breakpoints } from './breakpoints'
80
+
81
+ StyleSheet.configure({
82
+ themes: {
83
+ light: lightTheme,
84
+ dark: darkTheme,
85
+ },
86
+ breakpoints: {
87
+ xs: 0, // first breakpoint MUST start at 0
88
+ sm: 576,
89
+ md: 768,
90
+ lg: 992,
91
+ xl: 1200,
92
+ },
93
+ settings: {
94
+ initialTheme: 'light',
95
+ }
96
+ })
97
+ ```
98
+
99
+ ### Settings options
100
+
101
+ | Setting | Type | Description |
102
+ |---------|------|-------------|
103
+ | `initialTheme` | `string \| () => string` | Theme to use on app start. Can be a function for lazy evaluation (e.g., reading from storage). Mutually exclusive with `adaptiveThemes`. |
104
+ | `adaptiveThemes` | `boolean` | Auto-switch between `light` and `dark` themes based on OS color scheme. Requires themes named exactly `light` and `dark`. Mutually exclusive with `initialTheme`. |
105
+ | `CSSVars` | `boolean` | Use CSS custom properties for theme values on web. Enables instant theme switching without style recalculation. Default: `false`. |
106
+ | `nativeBreakpointsMode` | `'pixels' \| 'points'` | Whether breakpoint values are in physical pixels or logical points. Default: device-dependent. |
107
+
108
+ ### Minimal configuration (no themes, no breakpoints)
109
+
110
+ ```tsx
111
+ StyleSheet.configure({})
112
+ ```
113
+
114
+ Even without themes/breakpoints, `StyleSheet.configure()` must be called to initialize the C++ runtime.
115
+
116
+ ## TypeScript Declarations
117
+
118
+ Augment the Unistyles module to get type-safe themes and breakpoints:
119
+
120
+ ```tsx
121
+ // unistyles.ts (or wherever you call StyleSheet.configure)
122
+ import { StyleSheet } from 'react-native-unistyles'
123
+ import { lightTheme } from './themes'
124
+ import { breakpoints } from './breakpoints'
125
+
126
+ type AppThemes = {
127
+ light: typeof lightTheme
128
+ dark: typeof lightTheme // same shape as light
129
+ }
130
+
131
+ type AppBreakpoints = typeof breakpoints
132
+
133
+ declare module 'react-native-unistyles' {
134
+ export interface UnistylesThemes extends AppThemes {}
135
+ export interface UnistylesBreakpoints extends AppBreakpoints {}
136
+ }
137
+
138
+ StyleSheet.configure({
139
+ themes: { light: lightTheme, dark: darkTheme },
140
+ breakpoints,
141
+ })
142
+ ```
143
+
144
+ This enables:
145
+ - Auto-completion for `theme.colors.*`, `theme.spacing.*`, etc.
146
+ - Type-safe breakpoint names in styles and `mq`
147
+ - Type-safe theme names in `UnistylesRuntime.setTheme()`
148
+
149
+ ## Expo Router Integration
150
+
151
+ Expo Router resolves routes before Unistyles can initialize. Extra steps are needed:
152
+
153
+ ### 1. Change the main entry point
154
+
155
+ ```json
156
+ // package.json
157
+ { "main": "index.ts" }
158
+ ```
159
+
160
+ ### 2. Create index.ts
161
+
162
+ ```ts
163
+ // index.ts — import config BEFORE the router
164
+ import './unistyles' // your StyleSheet.configure() file
165
+ import 'expo-router/entry'
166
+ ```
167
+
168
+ ### 3. For static rendering (Expo SDK 52+)
169
+
170
+ Import your Unistyles config in `app/+html.tsx`:
171
+
172
+ ```tsx
173
+ // app/+html.tsx
174
+ import '../unistyles' // ensures Unistyles initializes for each static page
175
+
176
+ import { ScrollViewStyleReset } from 'expo-router/html'
177
+ import { type PropsWithChildren } from 'react'
178
+
179
+ export default function Root({ children }: PropsWithChildren) {
180
+ return (
181
+ <html lang="en">
182
+ <head>
183
+ <meta charSet="utf-8" />
184
+ <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
185
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
186
+ <ScrollViewStyleReset />
187
+ </head>
188
+ <body>{children}</body>
189
+ </html>
190
+ )
191
+ }
192
+ ```
193
+
194
+ ## Testing / Mocks Setup
195
+
196
+ The Babel plugin auto-disables in test environments (`NODE_ENV=test`). Import the mocks file in your Jest setup:
197
+
198
+ ```js
199
+ // jest.setup.js
200
+ require('react-native-unistyles/mocks')
201
+ require('./unistyles') // your StyleSheet.configure() call — provides theme data to mocks
202
+ ```
203
+
204
+ ```js
205
+ // jest.config.js
206
+ module.exports = {
207
+ setupFiles: ['./jest.setup.js'],
208
+ }
209
+ ```
210
+
211
+ The mock provides:
212
+ - `StyleSheet.create` that resolves theme functions using the first registered theme
213
+ - `StyleSheet.configure` that stores themes/breakpoints
214
+ - `useUnistyles()` returning `{ theme, rt }` with mock runtime values
215
+ - `withUnistyles` that applies mapper function
216
+ - `mq`, `Display`, `Hide`, `ScopedTheme` as no-ops
217
+ - `useAnimatedTheme` and `useAnimatedVariantColor` mocks (from `react-native-unistyles/reanimated`)