@vetala/vetala 0.1.0-beta

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.

Potentially problematic release.


This version of @vetala/vetala might be problematic. Click here for more details.

Files changed (271) hide show
  1. package/CONTRIBUTING.md +77 -0
  2. package/LICENSE +184 -0
  3. package/README.md +136 -0
  4. package/THIRD_PARTY_LICENSES.md +17 -0
  5. package/dist/src/agent.d.ts +30 -0
  6. package/dist/src/agent.js +216 -0
  7. package/dist/src/agent.js.map +1 -0
  8. package/dist/src/approvals.d.ts +18 -0
  9. package/dist/src/approvals.js +81 -0
  10. package/dist/src/approvals.js.map +1 -0
  11. package/dist/src/cli.d.ts +2 -0
  12. package/dist/src/cli.js +87 -0
  13. package/dist/src/cli.js.map +1 -0
  14. package/dist/src/config.d.ts +12 -0
  15. package/dist/src/config.js +183 -0
  16. package/dist/src/config.js.map +1 -0
  17. package/dist/src/context-memory.d.ts +7 -0
  18. package/dist/src/context-memory.js +96 -0
  19. package/dist/src/context-memory.js.map +1 -0
  20. package/dist/src/ink/command-suggestions.d.ts +7 -0
  21. package/dist/src/ink/command-suggestions.js +179 -0
  22. package/dist/src/ink/command-suggestions.js.map +1 -0
  23. package/dist/src/ink/ink-terminal-ui.d.ts +36 -0
  24. package/dist/src/ink/ink-terminal-ui.js +79 -0
  25. package/dist/src/ink/ink-terminal-ui.js.map +1 -0
  26. package/dist/src/ink/repl-app.d.ts +9 -0
  27. package/dist/src/ink/repl-app.js +789 -0
  28. package/dist/src/ink/repl-app.js.map +1 -0
  29. package/dist/src/ink/transcript-cards.d.ts +6 -0
  30. package/dist/src/ink/transcript-cards.js +24 -0
  31. package/dist/src/ink/transcript-cards.js.map +1 -0
  32. package/dist/src/path-policy.d.ts +11 -0
  33. package/dist/src/path-policy.js +67 -0
  34. package/dist/src/path-policy.js.map +1 -0
  35. package/dist/src/process-utils.d.ts +13 -0
  36. package/dist/src/process-utils.js +52 -0
  37. package/dist/src/process-utils.js.map +1 -0
  38. package/dist/src/repl.d.ts +9 -0
  39. package/dist/src/repl.js +13 -0
  40. package/dist/src/repl.js.map +1 -0
  41. package/dist/src/sarvam/client.d.ts +15 -0
  42. package/dist/src/sarvam/client.js +208 -0
  43. package/dist/src/sarvam/client.js.map +1 -0
  44. package/dist/src/sarvam/models.d.ts +2 -0
  45. package/dist/src/sarvam/models.js +7 -0
  46. package/dist/src/sarvam/models.js.map +1 -0
  47. package/dist/src/search-provider.d.ts +6 -0
  48. package/dist/src/search-provider.js +8 -0
  49. package/dist/src/search-provider.js.map +1 -0
  50. package/dist/src/session-store.d.ts +19 -0
  51. package/dist/src/session-store.js +318 -0
  52. package/dist/src/session-store.js.map +1 -0
  53. package/dist/src/skills/runtime.d.ts +26 -0
  54. package/dist/src/skills/runtime.js +317 -0
  55. package/dist/src/skills/runtime.js.map +1 -0
  56. package/dist/src/skills/types.d.ts +25 -0
  57. package/dist/src/skills/types.js +2 -0
  58. package/dist/src/skills/types.js.map +1 -0
  59. package/dist/src/terminal-ui.d.ts +29 -0
  60. package/dist/src/terminal-ui.js +236 -0
  61. package/dist/src/terminal-ui.js.map +1 -0
  62. package/dist/src/tools/filesystem.d.ts +2 -0
  63. package/dist/src/tools/filesystem.js +622 -0
  64. package/dist/src/tools/filesystem.js.map +1 -0
  65. package/dist/src/tools/git.d.ts +2 -0
  66. package/dist/src/tools/git.js +326 -0
  67. package/dist/src/tools/git.js.map +1 -0
  68. package/dist/src/tools/index.d.ts +6 -0
  69. package/dist/src/tools/index.js +21 -0
  70. package/dist/src/tools/index.js.map +1 -0
  71. package/dist/src/tools/registry.d.ts +15 -0
  72. package/dist/src/tools/registry.js +59 -0
  73. package/dist/src/tools/registry.js.map +1 -0
  74. package/dist/src/tools/shell.d.ts +2 -0
  75. package/dist/src/tools/shell.js +97 -0
  76. package/dist/src/tools/shell.js.map +1 -0
  77. package/dist/src/tools/skill.d.ts +3 -0
  78. package/dist/src/tools/skill.js +130 -0
  79. package/dist/src/tools/skill.js.map +1 -0
  80. package/dist/src/tools/web.d.ts +3 -0
  81. package/dist/src/tools/web.js +144 -0
  82. package/dist/src/tools/web.js.map +1 -0
  83. package/dist/src/types.d.ts +236 -0
  84. package/dist/src/types.js +2 -0
  85. package/dist/src/types.js.map +1 -0
  86. package/dist/src/workspace-trust.d.ts +3 -0
  87. package/dist/src/workspace-trust.js +31 -0
  88. package/dist/src/workspace-trust.js.map +1 -0
  89. package/dist/src/xdg.d.ts +9 -0
  90. package/dist/src/xdg.js +77 -0
  91. package/dist/src/xdg.js.map +1 -0
  92. package/package.json +57 -0
  93. package/skill/agents-md-generator/SKILL.md +75 -0
  94. package/skill/agents-md-generator/references/agents_md_template.md +160 -0
  95. package/skill/agents-md-generator/references/loc_measurement.md +67 -0
  96. package/skill/agents-md-generator/references/monorepo_detection.md +78 -0
  97. package/skill/agents-md-generator/references/monorepo_strategy.md +60 -0
  98. package/skill/agents-md-generator/references/read_only_commands.md +151 -0
  99. package/skill/agents-md-generator/references/update_strategy.md +160 -0
  100. package/skill/agents-md-generator/references/working_agreements.md +53 -0
  101. package/skill/biz-opportunity-scout/SKILL.md +53 -0
  102. package/skill/biz-opportunity-scout/references/competitive_analysis.md +84 -0
  103. package/skill/biz-opportunity-scout/references/market_sizing.md +68 -0
  104. package/skill/biz-opportunity-scout/references/pmf_indicators.md +94 -0
  105. package/skill/biz-opportunity-scout/references/report_template.md +243 -0
  106. package/skill/biz-opportunity-scout/references/unit_economics.md +97 -0
  107. package/skill/code-review/SKILL.md +86 -0
  108. package/skill/code-review/references/change_analysis.md +116 -0
  109. package/skill/code-review/references/git_operations.md +115 -0
  110. package/skill/code-review/references/impact_detection.md +149 -0
  111. package/skill/code-review/references/output_format.md +137 -0
  112. package/skill/code-review/references/severity_criteria.md +100 -0
  113. package/skill/code-security-audit/SKILL.md +123 -0
  114. package/skill/code-security-audit/references/audit_process.md +277 -0
  115. package/skill/code-security-audit/references/remediation_patterns.md +599 -0
  116. package/skill/code-security-audit/references/report_format.md +391 -0
  117. package/skill/code-security-audit/references/security_domains.md +830 -0
  118. package/skill/code-security-audit/references/vulnerability_patterns.md +813 -0
  119. package/skill/composition-patterns/SKILL.md +83 -0
  120. package/skill/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
  121. package/skill/composition-patterns/rules/architecture-compound-components.md +112 -0
  122. package/skill/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
  123. package/skill/composition-patterns/rules/patterns-explicit-variants.md +100 -0
  124. package/skill/composition-patterns/rules/react19-no-forwardref.md +42 -0
  125. package/skill/composition-patterns/rules/state-context-interface.md +191 -0
  126. package/skill/composition-patterns/rules/state-decouple-implementation.md +113 -0
  127. package/skill/composition-patterns/rules/state-lift-state.md +125 -0
  128. package/skill/deploy-to-vercel/SKILL.md +293 -0
  129. package/skill/deploy-to-vercel/resources/deploy-sandbox.sh +301 -0
  130. package/skill/deploy-to-vercel/resources/deploy.sh +301 -0
  131. package/skill/doc/SKILL_GUIDELINES.md +138 -0
  132. package/skill/git-workflow/SKILL.md +94 -0
  133. package/skill/git-workflow/references/advanced-git.md +632 -0
  134. package/skill/git-workflow/references/branching-strategies.md +344 -0
  135. package/skill/git-workflow/references/ci-cd-integration.md +683 -0
  136. package/skill/git-workflow/references/code-quality-tools.md +351 -0
  137. package/skill/git-workflow/references/commit-conventions.md +439 -0
  138. package/skill/git-workflow/references/github-releases.md +288 -0
  139. package/skill/git-workflow/references/pull-request-workflow.md +773 -0
  140. package/skill/git-workflow/scripts/verify-git-workflow.sh +263 -0
  141. package/skill/jetbrains-vmoptions/SKILL.md +51 -0
  142. package/skill/jetbrains-vmoptions/references/common-options.md +357 -0
  143. package/skill/jetbrains-vmoptions/references/gc-options.md +350 -0
  144. package/skill/jetbrains-vmoptions/references/memory-options.md +339 -0
  145. package/skill/jetbrains-vmoptions/references/prerequisite-check.md +65 -0
  146. package/skill/kysely-converter/SKILL.md +62 -0
  147. package/skill/kysely-converter/references/delete.md +323 -0
  148. package/skill/kysely-converter/references/insert.md +386 -0
  149. package/skill/kysely-converter/references/operators.md +331 -0
  150. package/skill/kysely-converter/references/select.md +1000 -0
  151. package/skill/kysely-converter/references/update.md +349 -0
  152. package/skill/kysely-converter/references/window_function.md +537 -0
  153. package/skill/react-best-practices/SKILL.md +131 -0
  154. package/skill/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
  155. package/skill/react-best-practices/rules/advanced-init-once.md +42 -0
  156. package/skill/react-best-practices/rules/advanced-use-latest.md +39 -0
  157. package/skill/react-best-practices/rules/async-api-routes.md +38 -0
  158. package/skill/react-best-practices/rules/async-defer-await.md +80 -0
  159. package/skill/react-best-practices/rules/async-dependencies.md +51 -0
  160. package/skill/react-best-practices/rules/async-parallel.md +28 -0
  161. package/skill/react-best-practices/rules/async-suspense-boundaries.md +99 -0
  162. package/skill/react-best-practices/rules/bundle-barrel-imports.md +59 -0
  163. package/skill/react-best-practices/rules/bundle-conditional.md +31 -0
  164. package/skill/react-best-practices/rules/bundle-defer-third-party.md +49 -0
  165. package/skill/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
  166. package/skill/react-best-practices/rules/bundle-preload.md +50 -0
  167. package/skill/react-best-practices/rules/client-event-listeners.md +74 -0
  168. package/skill/react-best-practices/rules/client-localstorage-schema.md +71 -0
  169. package/skill/react-best-practices/rules/client-passive-event-listeners.md +48 -0
  170. package/skill/react-best-practices/rules/client-swr-dedup.md +56 -0
  171. package/skill/react-best-practices/rules/js-batch-dom-css.md +107 -0
  172. package/skill/react-best-practices/rules/js-cache-function-results.md +80 -0
  173. package/skill/react-best-practices/rules/js-cache-property-access.md +28 -0
  174. package/skill/react-best-practices/rules/js-cache-storage.md +70 -0
  175. package/skill/react-best-practices/rules/js-combine-iterations.md +32 -0
  176. package/skill/react-best-practices/rules/js-early-exit.md +50 -0
  177. package/skill/react-best-practices/rules/js-hoist-regexp.md +45 -0
  178. package/skill/react-best-practices/rules/js-index-maps.md +37 -0
  179. package/skill/react-best-practices/rules/js-length-check-first.md +49 -0
  180. package/skill/react-best-practices/rules/js-min-max-loop.md +82 -0
  181. package/skill/react-best-practices/rules/js-set-map-lookups.md +24 -0
  182. package/skill/react-best-practices/rules/js-tosorted-immutable.md +57 -0
  183. package/skill/react-best-practices/rules/rendering-activity.md +26 -0
  184. package/skill/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
  185. package/skill/react-best-practices/rules/rendering-conditional-render.md +40 -0
  186. package/skill/react-best-practices/rules/rendering-content-visibility.md +38 -0
  187. package/skill/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
  188. package/skill/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
  189. package/skill/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
  190. package/skill/react-best-practices/rules/rendering-svg-precision.md +28 -0
  191. package/skill/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
  192. package/skill/react-best-practices/rules/rerender-defer-reads.md +39 -0
  193. package/skill/react-best-practices/rules/rerender-dependencies.md +45 -0
  194. package/skill/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
  195. package/skill/react-best-practices/rules/rerender-derived-state.md +29 -0
  196. package/skill/react-best-practices/rules/rerender-functional-setstate.md +74 -0
  197. package/skill/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
  198. package/skill/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
  199. package/skill/react-best-practices/rules/rerender-memo.md +44 -0
  200. package/skill/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
  201. package/skill/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
  202. package/skill/react-best-practices/rules/rerender-transitions.md +40 -0
  203. package/skill/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
  204. package/skill/react-best-practices/rules/server-after-nonblocking.md +73 -0
  205. package/skill/react-best-practices/rules/server-auth-actions.md +96 -0
  206. package/skill/react-best-practices/rules/server-cache-lru.md +41 -0
  207. package/skill/react-best-practices/rules/server-cache-react.md +76 -0
  208. package/skill/react-best-practices/rules/server-dedup-props.md +65 -0
  209. package/skill/react-best-practices/rules/server-hoist-static-io.md +142 -0
  210. package/skill/react-best-practices/rules/server-parallel-fetching.md +83 -0
  211. package/skill/react-best-practices/rules/server-serialization.md +38 -0
  212. package/skill/react-native-skills/SKILL.md +115 -0
  213. package/skill/react-native-skills/rules/animation-derived-value.md +53 -0
  214. package/skill/react-native-skills/rules/animation-gesture-detector-press.md +95 -0
  215. package/skill/react-native-skills/rules/animation-gpu-properties.md +65 -0
  216. package/skill/react-native-skills/rules/design-system-compound-components.md +66 -0
  217. package/skill/react-native-skills/rules/fonts-config-plugin.md +71 -0
  218. package/skill/react-native-skills/rules/imports-design-system-folder.md +68 -0
  219. package/skill/react-native-skills/rules/js-hoist-intl.md +61 -0
  220. package/skill/react-native-skills/rules/list-performance-callbacks.md +44 -0
  221. package/skill/react-native-skills/rules/list-performance-function-references.md +132 -0
  222. package/skill/react-native-skills/rules/list-performance-images.md +53 -0
  223. package/skill/react-native-skills/rules/list-performance-inline-objects.md +97 -0
  224. package/skill/react-native-skills/rules/list-performance-item-expensive.md +94 -0
  225. package/skill/react-native-skills/rules/list-performance-item-memo.md +82 -0
  226. package/skill/react-native-skills/rules/list-performance-item-types.md +104 -0
  227. package/skill/react-native-skills/rules/list-performance-virtualize.md +67 -0
  228. package/skill/react-native-skills/rules/monorepo-native-deps-in-app.md +46 -0
  229. package/skill/react-native-skills/rules/monorepo-single-dependency-versions.md +63 -0
  230. package/skill/react-native-skills/rules/navigation-native-navigators.md +188 -0
  231. package/skill/react-native-skills/rules/react-compiler-destructure-functions.md +50 -0
  232. package/skill/react-native-skills/rules/react-compiler-reanimated-shared-values.md +48 -0
  233. package/skill/react-native-skills/rules/react-state-dispatcher.md +91 -0
  234. package/skill/react-native-skills/rules/react-state-fallback.md +56 -0
  235. package/skill/react-native-skills/rules/react-state-minimize.md +65 -0
  236. package/skill/react-native-skills/rules/rendering-no-falsy-and.md +74 -0
  237. package/skill/react-native-skills/rules/rendering-text-in-text-component.md +36 -0
  238. package/skill/react-native-skills/rules/scroll-position-no-state.md +82 -0
  239. package/skill/react-native-skills/rules/state-ground-truth.md +80 -0
  240. package/skill/react-native-skills/rules/ui-expo-image.md +66 -0
  241. package/skill/react-native-skills/rules/ui-image-gallery.md +104 -0
  242. package/skill/react-native-skills/rules/ui-measure-views.md +78 -0
  243. package/skill/react-native-skills/rules/ui-menus.md +174 -0
  244. package/skill/react-native-skills/rules/ui-native-modals.md +77 -0
  245. package/skill/react-native-skills/rules/ui-pressable.md +61 -0
  246. package/skill/react-native-skills/rules/ui-safe-area-scroll.md +65 -0
  247. package/skill/react-native-skills/rules/ui-scrollview-content-inset.md +45 -0
  248. package/skill/react-native-skills/rules/ui-styling.md +87 -0
  249. package/skill/react-vite-guide/SKILL.md +101 -0
  250. package/skill/react-vite-guide/references/composition-patterns.md +709 -0
  251. package/skill/react-vite-guide/references/performance-optimization.md +1222 -0
  252. package/skill/react-vite-guide/references/vite-specific.md +385 -0
  253. package/skill/react-vite-guide/references/web-interface.md +146 -0
  254. package/skill/skill-maker/SKILL.md +52 -0
  255. package/skill/skill-maker/references/content_spec.md +67 -0
  256. package/skill/skill-maker/references/frontmatter_spec.md +96 -0
  257. package/skill/skill-maker/references/input_validation.md +90 -0
  258. package/skill/skill-maker/references/skill_structure.md +74 -0
  259. package/skill/system-prompt-creator/SKILL.md +50 -0
  260. package/skill/system-prompt-creator/references/data_format_selection.md +135 -0
  261. package/skill/system-prompt-creator/references/multi_prompt_architecture.md +386 -0
  262. package/skill/system-prompt-creator/references/prompt_structure.md +140 -0
  263. package/skill/system-prompt-creator/references/quality_criteria.md +83 -0
  264. package/skill/typst-creator/SKILL.md +51 -0
  265. package/skill/typst-creator/references/layout.md +401 -0
  266. package/skill/typst-creator/references/math.md +297 -0
  267. package/skill/typst-creator/references/scripting.md +237 -0
  268. package/skill/typst-creator/references/styling.md +217 -0
  269. package/skill/typst-creator/references/syntax.md +234 -0
  270. package/skill/web-design-guidelines/SKILL.md +35 -0
  271. package/terminal.png +0 -0
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: Prefer useDerivedValue Over useAnimatedReaction
3
+ impact: MEDIUM
4
+ impactDescription: cleaner code, automatic dependency tracking
5
+ tags: animation, reanimated, derived-value
6
+ ---
7
+
8
+ ## Prefer useDerivedValue Over useAnimatedReaction
9
+
10
+ When deriving a shared value from another, use `useDerivedValue` instead of
11
+ `useAnimatedReaction`. Derived values are declarative, automatically track
12
+ dependencies, and return a value you can use directly. Animated reactions are
13
+ for side effects, not derivations.
14
+
15
+ **Incorrect (useAnimatedReaction for derivation):**
16
+
17
+ ```tsx
18
+ import { useSharedValue, useAnimatedReaction } from 'react-native-reanimated'
19
+
20
+ function MyComponent() {
21
+ const progress = useSharedValue(0)
22
+ const opacity = useSharedValue(1)
23
+
24
+ useAnimatedReaction(
25
+ () => progress.value,
26
+ (current) => {
27
+ opacity.value = 1 - current
28
+ }
29
+ )
30
+
31
+ // ...
32
+ }
33
+ ```
34
+
35
+ **Correct (useDerivedValue):**
36
+
37
+ ```tsx
38
+ import { useSharedValue, useDerivedValue } from 'react-native-reanimated'
39
+
40
+ function MyComponent() {
41
+ const progress = useSharedValue(0)
42
+
43
+ const opacity = useDerivedValue(() => 1 - progress.get())
44
+
45
+ // ...
46
+ }
47
+ ```
48
+
49
+ Use `useAnimatedReaction` only for side effects that don't produce a value
50
+ (e.g., triggering haptics, logging, calling `runOnJS`).
51
+
52
+ Reference:
53
+ [Reanimated useDerivedValue](https://docs.swmansion.com/react-native-reanimated/docs/core/useDerivedValue)
@@ -0,0 +1,95 @@
1
+ ---
2
+ title: Use GestureDetector for Animated Press States
3
+ impact: MEDIUM
4
+ impactDescription: UI thread animations, smoother press feedback
5
+ tags: animation, gestures, press, reanimated
6
+ ---
7
+
8
+ ## Use GestureDetector for Animated Press States
9
+
10
+ For animated press states (scale, opacity on press), use `GestureDetector` with
11
+ `Gesture.Tap()` and shared values instead of Pressable's
12
+ `onPressIn`/`onPressOut`. Gesture callbacks run on the UI thread as worklets—no
13
+ JS thread round-trip for press animations.
14
+
15
+ **Incorrect (Pressable with JS thread callbacks):**
16
+
17
+ ```tsx
18
+ import { Pressable } from 'react-native'
19
+ import Animated, {
20
+ useSharedValue,
21
+ useAnimatedStyle,
22
+ withTiming,
23
+ } from 'react-native-reanimated'
24
+
25
+ function AnimatedButton({ onPress }: { onPress: () => void }) {
26
+ const scale = useSharedValue(1)
27
+
28
+ const animatedStyle = useAnimatedStyle(() => ({
29
+ transform: [{ scale: scale.value }],
30
+ }))
31
+
32
+ return (
33
+ <Pressable
34
+ onPress={onPress}
35
+ onPressIn={() => (scale.value = withTiming(0.95))}
36
+ onPressOut={() => (scale.value = withTiming(1))}
37
+ >
38
+ <Animated.View style={animatedStyle}>
39
+ <Text>Press me</Text>
40
+ </Animated.View>
41
+ </Pressable>
42
+ )
43
+ }
44
+ ```
45
+
46
+ **Correct (GestureDetector with UI thread worklets):**
47
+
48
+ ```tsx
49
+ import { Gesture, GestureDetector } from 'react-native-gesture-handler'
50
+ import Animated, {
51
+ useSharedValue,
52
+ useAnimatedStyle,
53
+ withTiming,
54
+ interpolate,
55
+ runOnJS,
56
+ } from 'react-native-reanimated'
57
+
58
+ function AnimatedButton({ onPress }: { onPress: () => void }) {
59
+ // Store the press STATE (0 = not pressed, 1 = pressed)
60
+ const pressed = useSharedValue(0)
61
+
62
+ const tap = Gesture.Tap()
63
+ .onBegin(() => {
64
+ pressed.set(withTiming(1))
65
+ })
66
+ .onFinalize(() => {
67
+ pressed.set(withTiming(0))
68
+ })
69
+ .onEnd(() => {
70
+ runOnJS(onPress)()
71
+ })
72
+
73
+ // Derive visual values from the state
74
+ const animatedStyle = useAnimatedStyle(() => ({
75
+ transform: [
76
+ { scale: interpolate(withTiming(pressed.get()), [0, 1], [1, 0.95]) },
77
+ ],
78
+ }))
79
+
80
+ return (
81
+ <GestureDetector gesture={tap}>
82
+ <Animated.View style={animatedStyle}>
83
+ <Text>Press me</Text>
84
+ </Animated.View>
85
+ </GestureDetector>
86
+ )
87
+ }
88
+ ```
89
+
90
+ Store the press **state** (0 or 1), then derive the scale via `interpolate`.
91
+ This keeps the shared value as ground truth. Use `runOnJS` to call JS functions
92
+ from worklets. Use `.set()` and `.get()` for React Compiler compatibility.
93
+
94
+ Reference:
95
+ [Gesture Handler Tap Gesture](https://docs.swmansion.com/react-native-gesture-handler/docs/gestures/tap-gesture)
@@ -0,0 +1,65 @@
1
+ ---
2
+ title: Animate Transform and Opacity Instead of Layout Properties
3
+ impact: HIGH
4
+ impactDescription: GPU-accelerated animations, no layout recalculation
5
+ tags: animation, performance, reanimated, transform, opacity
6
+ ---
7
+
8
+ ## Animate Transform and Opacity Instead of Layout Properties
9
+
10
+ Avoid animating `width`, `height`, `top`, `left`, `margin`, or `padding`. These trigger layout recalculation on every frame. Instead, use `transform` (scale, translate) and `opacity` which run on the GPU without triggering layout.
11
+
12
+ **Incorrect (animates height, triggers layout every frame):**
13
+
14
+ ```tsx
15
+ import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
16
+
17
+ function CollapsiblePanel({ expanded }: { expanded: boolean }) {
18
+ const animatedStyle = useAnimatedStyle(() => ({
19
+ height: withTiming(expanded ? 200 : 0), // triggers layout on every frame
20
+ overflow: 'hidden',
21
+ }))
22
+
23
+ return <Animated.View style={animatedStyle}>{children}</Animated.View>
24
+ }
25
+ ```
26
+
27
+ **Correct (animates scaleY, GPU-accelerated):**
28
+
29
+ ```tsx
30
+ import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
31
+
32
+ function CollapsiblePanel({ expanded }: { expanded: boolean }) {
33
+ const animatedStyle = useAnimatedStyle(() => ({
34
+ transform: [
35
+ { scaleY: withTiming(expanded ? 1 : 0) },
36
+ ],
37
+ opacity: withTiming(expanded ? 1 : 0),
38
+ }))
39
+
40
+ return (
41
+ <Animated.View style={[{ height: 200, transformOrigin: 'top' }, animatedStyle]}>
42
+ {children}
43
+ </Animated.View>
44
+ )
45
+ }
46
+ ```
47
+
48
+ **Correct (animates translateY for slide animations):**
49
+
50
+ ```tsx
51
+ import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
52
+
53
+ function SlideIn({ visible }: { visible: boolean }) {
54
+ const animatedStyle = useAnimatedStyle(() => ({
55
+ transform: [
56
+ { translateY: withTiming(visible ? 0 : 100) },
57
+ ],
58
+ opacity: withTiming(visible ? 1 : 0),
59
+ }))
60
+
61
+ return <Animated.View style={animatedStyle}>{children}</Animated.View>
62
+ }
63
+ ```
64
+
65
+ GPU-accelerated properties: `transform` (translate, scale, rotate), `opacity`. Everything else triggers layout.
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: Use Compound Components Over Polymorphic Children
3
+ impact: MEDIUM
4
+ impactDescription: flexible composition, clearer API
5
+ tags: design-system, components, composition
6
+ ---
7
+
8
+ ## Use Compound Components Over Polymorphic Children
9
+
10
+ Don't create components that can accept a string if they aren't a text node. If
11
+ a component can receive a string child, it must be a dedicated `*Text`
12
+ component. For components like buttons, which can have both a View (or
13
+ Pressable) together with text, use compound components, such a `Button`,
14
+ `ButtonText`, and `ButtonIcon`.
15
+
16
+ **Incorrect (polymorphic children):**
17
+
18
+ ```tsx
19
+ import { Pressable, Text } from 'react-native'
20
+
21
+ type ButtonProps = {
22
+ children: string | React.ReactNode
23
+ icon?: React.ReactNode
24
+ }
25
+
26
+ function Button({ children, icon }: ButtonProps) {
27
+ return (
28
+ <Pressable>
29
+ {icon}
30
+ {typeof children === 'string' ? <Text>{children}</Text> : children}
31
+ </Pressable>
32
+ )
33
+ }
34
+
35
+ // Usage is ambiguous
36
+ <Button icon={<Icon />}>Save</Button>
37
+ <Button><CustomText>Save</CustomText></Button>
38
+ ```
39
+
40
+ **Correct (compound components):**
41
+
42
+ ```tsx
43
+ import { Pressable, Text } from 'react-native'
44
+
45
+ function Button({ children }: { children: React.ReactNode }) {
46
+ return <Pressable>{children}</Pressable>
47
+ }
48
+
49
+ function ButtonText({ children }: { children: React.ReactNode }) {
50
+ return <Text>{children}</Text>
51
+ }
52
+
53
+ function ButtonIcon({ children }: { children: React.ReactNode }) {
54
+ return <>{children}</>
55
+ }
56
+
57
+ // Usage is explicit and composable
58
+ <Button>
59
+ <ButtonIcon><SaveIcon /></ButtonIcon>
60
+ <ButtonText>Save</ButtonText>
61
+ </Button>
62
+
63
+ <Button>
64
+ <ButtonText>Cancel</ButtonText>
65
+ </Button>
66
+ ```
@@ -0,0 +1,71 @@
1
+ ---
2
+ title: Load fonts natively at build time
3
+ impact: LOW
4
+ impactDescription: fonts available at launch, no async loading
5
+ tags: fonts, expo, performance, config-plugin
6
+ ---
7
+
8
+ ## Use Expo Config Plugin for Font Loading
9
+
10
+ Use the `expo-font` config plugin to embed fonts at build time instead of
11
+ `useFonts` or `Font.loadAsync`. Embedded fonts are more efficient.
12
+
13
+ **Incorrect (async font loading):**
14
+
15
+ ```tsx
16
+ import { useFonts } from 'expo-font'
17
+ import { Text, View } from 'react-native'
18
+
19
+ function App() {
20
+ const [fontsLoaded] = useFonts({
21
+ 'Geist-Bold': require('./assets/fonts/Geist-Bold.otf'),
22
+ })
23
+
24
+ if (!fontsLoaded) {
25
+ return null
26
+ }
27
+
28
+ return (
29
+ <View>
30
+ <Text style={{ fontFamily: 'Geist-Bold' }}>Hello</Text>
31
+ </View>
32
+ )
33
+ }
34
+ ```
35
+
36
+ **Correct (config plugin, fonts embedded at build):**
37
+
38
+ ```json
39
+ // app.json
40
+ {
41
+ "expo": {
42
+ "plugins": [
43
+ [
44
+ "expo-font",
45
+ {
46
+ "fonts": ["./assets/fonts/Geist-Bold.otf"]
47
+ }
48
+ ]
49
+ ]
50
+ }
51
+ }
52
+ ```
53
+
54
+ ```tsx
55
+ import { Text, View } from 'react-native'
56
+
57
+ function App() {
58
+ // No loading state needed—font is already available
59
+ return (
60
+ <View>
61
+ <Text style={{ fontFamily: 'Geist-Bold' }}>Hello</Text>
62
+ </View>
63
+ )
64
+ }
65
+ ```
66
+
67
+ After adding fonts to the config plugin, run `npx expo prebuild` and rebuild the
68
+ native app.
69
+
70
+ Reference:
71
+ [Expo Font Documentation](https://docs.expo.dev/versions/latest/sdk/font/)
@@ -0,0 +1,68 @@
1
+ ---
2
+ title: Import from Design System Folder
3
+ impact: LOW
4
+ impactDescription: enables global changes and easy refactoring
5
+ tags: imports, architecture, design-system
6
+ ---
7
+
8
+ ## Import from Design System Folder
9
+
10
+ Re-export dependencies from a design system folder. App code imports from there,
11
+ not directly from packages. This enables global changes and easy refactoring.
12
+
13
+ **Incorrect (imports directly from package):**
14
+
15
+ ```tsx
16
+ import { View, Text } from 'react-native'
17
+ import { Button } from '@ui/button'
18
+
19
+ function Profile() {
20
+ return (
21
+ <View>
22
+ <Text>Hello</Text>
23
+ <Button>Save</Button>
24
+ </View>
25
+ )
26
+ }
27
+ ```
28
+
29
+ **Correct (imports from design system):**
30
+
31
+ ```tsx
32
+ // components/view.tsx
33
+ import { View as RNView } from 'react-native'
34
+
35
+ // ideal: pick the props you will actually use to control implementation
36
+ export function View(
37
+ props: Pick<React.ComponentProps<typeof RNView>, 'style' | 'children'>
38
+ ) {
39
+ return <RNView {...props} />
40
+ }
41
+ ```
42
+
43
+ ```tsx
44
+ // components/text.tsx
45
+ export { Text } from 'react-native'
46
+ ```
47
+
48
+ ```tsx
49
+ // components/button.tsx
50
+ export { Button } from '@ui/button'
51
+ ```
52
+
53
+ ```tsx
54
+ import { View } from '@/components/view'
55
+ import { Text } from '@/components/text'
56
+ import { Button } from '@/components/button'
57
+
58
+ function Profile() {
59
+ return (
60
+ <View>
61
+ <Text>Hello</Text>
62
+ <Button>Save</Button>
63
+ </View>
64
+ )
65
+ }
66
+ ```
67
+
68
+ Start by simply re-exporting. Customize later without changing app code.
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: Hoist Intl Formatter Creation
3
+ impact: LOW-MEDIUM
4
+ impactDescription: avoids expensive object recreation
5
+ tags: javascript, intl, optimization, memoization
6
+ ---
7
+
8
+ ## Hoist Intl Formatter Creation
9
+
10
+ Don't create `Intl.DateTimeFormat`, `Intl.NumberFormat`, or
11
+ `Intl.RelativeTimeFormat` inside render or loops. These are expensive to
12
+ instantiate. Hoist to module scope when the locale/options are static.
13
+
14
+ **Incorrect (new formatter every render):**
15
+
16
+ ```tsx
17
+ function Price({ amount }: { amount: number }) {
18
+ const formatter = new Intl.NumberFormat('en-US', {
19
+ style: 'currency',
20
+ currency: 'USD',
21
+ })
22
+ return <Text>{formatter.format(amount)}</Text>
23
+ }
24
+ ```
25
+
26
+ **Correct (hoisted to module scope):**
27
+
28
+ ```tsx
29
+ const currencyFormatter = new Intl.NumberFormat('en-US', {
30
+ style: 'currency',
31
+ currency: 'USD',
32
+ })
33
+
34
+ function Price({ amount }: { amount: number }) {
35
+ return <Text>{currencyFormatter.format(amount)}</Text>
36
+ }
37
+ ```
38
+
39
+ **For dynamic locales, memoize:**
40
+
41
+ ```tsx
42
+ const dateFormatter = useMemo(
43
+ () => new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }),
44
+ [locale]
45
+ )
46
+ ```
47
+
48
+ **Common formatters to hoist:**
49
+
50
+ ```tsx
51
+ // Module-level formatters
52
+ const dateFormatter = new Intl.DateTimeFormat('en-US', { dateStyle: 'medium' })
53
+ const timeFormatter = new Intl.DateTimeFormat('en-US', { timeStyle: 'short' })
54
+ const percentFormatter = new Intl.NumberFormat('en-US', { style: 'percent' })
55
+ const relativeFormatter = new Intl.RelativeTimeFormat('en-US', {
56
+ numeric: 'auto',
57
+ })
58
+ ```
59
+
60
+ Creating `Intl` objects is significantly more expensive than `RegExp` or plain
61
+ objects—each instantiation parses locale data and builds internal lookup tables.
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: Hoist callbacks to the root of lists
3
+ impact: MEDIUM
4
+ impactDescription: Fewer re-renders and faster lists
5
+ tags: tag1, tag2
6
+ ---
7
+
8
+ ## List performance callbacks
9
+
10
+ **Impact: HIGH (Fewer re-renders and faster lists)**
11
+
12
+ When passing callback functions to list items, create a single instance of the
13
+ callback at the root of the list. Items should then call it with a unique
14
+ identifier.
15
+
16
+ **Incorrect (creates a new callback on each render):**
17
+
18
+ ```typescript
19
+ return (
20
+ <LegendList
21
+ renderItem={({ item }) => {
22
+ // bad: creates a new callback on each render
23
+ const onPress = () => handlePress(item.id)
24
+ return <Item key={item.id} item={item} onPress={onPress} />
25
+ }}
26
+ />
27
+ )
28
+ ```
29
+
30
+ **Correct (a single function instance passed to each item):**
31
+
32
+ ```typescript
33
+ const onPress = useCallback(() => handlePress(item.id), [handlePress, item.id])
34
+
35
+ return (
36
+ <LegendList
37
+ renderItem={({ item }) => (
38
+ <Item key={item.id} item={item} onPress={onPress} />
39
+ )}
40
+ />
41
+ )
42
+ ```
43
+
44
+ Reference: [Link to documentation or resource](https://example.com)
@@ -0,0 +1,132 @@
1
+ ---
2
+ title: Optimize List Performance with Stable Object References
3
+ impact: CRITICAL
4
+ impactDescription: virtualization relies on reference stability
5
+ tags: lists, performance, flatlist, virtualization
6
+ ---
7
+
8
+ ## Optimize List Performance with Stable Object References
9
+
10
+ Don't map or filter data before passing to virtualized lists. Virtualization
11
+ relies on object reference stability to know what changed—new references cause
12
+ full re-renders of all visible items. Attempt to prevent frequent renders at the
13
+ list-parent level.
14
+
15
+ Where needed, use context selectors within list items.
16
+
17
+ **Incorrect (creates new object references on every keystroke):**
18
+
19
+ ```tsx
20
+ function DomainSearch() {
21
+ const { keyword, setKeyword } = useKeywordZustandState()
22
+ const { data: tlds } = useTlds()
23
+
24
+ // Bad: creates new objects on every render, reparenting the entire list on every keystroke
25
+ const domains = tlds.map((tld) => ({
26
+ domain: `${keyword}.${tld.name}`,
27
+ tld: tld.name,
28
+ price: tld.price,
29
+ }))
30
+
31
+ return (
32
+ <>
33
+ <TextInput value={keyword} onChangeText={setKeyword} />
34
+ <LegendList
35
+ data={domains}
36
+ renderItem={({ item }) => <DomainItem item={item} keyword={keyword} />}
37
+ />
38
+ </>
39
+ )
40
+ }
41
+ ```
42
+
43
+ **Correct (stable references, transform inside items):**
44
+
45
+ ```tsx
46
+ const renderItem = ({ item }) => <DomainItem tld={item} />
47
+
48
+ function DomainSearch() {
49
+ const { data: tlds } = useTlds()
50
+
51
+ return (
52
+ <LegendList
53
+ // good: as long as the data is stable, LegendList will not re-render the entire list
54
+ data={tlds}
55
+ renderItem={renderItem}
56
+ />
57
+ )
58
+ }
59
+
60
+ function DomainItem({ tld }: { tld: Tld }) {
61
+ // good: transform within items, and don't pass the dynamic data as a prop
62
+ // good: use a selector function from zustand to receive a stable string back
63
+ const domain = useKeywordZustandState((s) => s.keyword + '.' + tld.name)
64
+ return <Text>{domain}</Text>
65
+ }
66
+ ```
67
+
68
+ **Updating parent array reference:**
69
+
70
+ Creating a new array instance can be okay, as long as its inner object
71
+ references are stable. For instance, if you sort a list of objects:
72
+
73
+ ```tsx
74
+ // good: creates a new array instance without mutating the inner objects
75
+ // good: parent array reference is unaffected by typing and updating "keyword"
76
+ const sortedTlds = tlds.toSorted((a, b) => a.name.localeCompare(b.name))
77
+
78
+ return <LegendList data={sortedTlds} renderItem={renderItem} />
79
+ ```
80
+
81
+ Even though this creates a new array instance `sortedTlds`, the inner object
82
+ references are stable.
83
+
84
+ **With zustand for dynamic data (avoids parent re-renders):**
85
+
86
+ ```tsx
87
+ const useSearchStore = create<{ keyword: string }>(() => ({ keyword: '' }))
88
+
89
+ function DomainSearch() {
90
+ const { data: tlds } = useTlds()
91
+
92
+ return (
93
+ <>
94
+ <SearchInput />
95
+ <LegendList
96
+ data={tlds}
97
+ // if you aren't using React Compiler, wrap renderItem with useCallback
98
+ renderItem={({ item }) => <DomainItem tld={item} />}
99
+ />
100
+ </>
101
+ )
102
+ }
103
+
104
+ function DomainItem({ tld }: { tld: Tld }) {
105
+ // Select only what you need—component only re-renders when keyword changes
106
+ const keyword = useSearchStore((s) => s.keyword)
107
+ const domain = `${keyword}.${tld.name}`
108
+ return <Text>{domain}</Text>
109
+ }
110
+ ```
111
+
112
+ Virtualization can now skip items that haven't changed when typing. Only visible
113
+ items (~20) re-render on keystroke, rather than the parent.
114
+
115
+ **Deriving state within list items based on parent data (avoids parent
116
+ re-renders):**
117
+
118
+ For components where the data is conditional based on the parent state, this
119
+ pattern is even more important. For example, if you are checking if an item is
120
+ favorited, toggling favorites only re-renders one component if the item itself
121
+ is in charge of accessing the state rather than the parent:
122
+
123
+ ```tsx
124
+ function DomainItemFavoriteButton({ tld }: { tld: Tld }) {
125
+ const isFavorited = useFavoritesStore((s) => s.favorites.has(tld.id))
126
+ return <TldFavoriteButton isFavorited={isFavorited} />
127
+ }
128
+ ```
129
+
130
+ Note: if you're using the React Compiler, you can read React Context values
131
+ directly within list items. Although this is slightly slower than using a
132
+ Zustand selector in most cases, the effect may be negligible.