@wazir-dev/cli 1.0.0

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 (629) hide show
  1. package/AGENTS.md +111 -0
  2. package/CHANGELOG.md +14 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +21 -0
  5. package/README.md +314 -0
  6. package/assets/composition-engine.mmd +34 -0
  7. package/assets/demo-script.sh +17 -0
  8. package/assets/logo-dark.svg +14 -0
  9. package/assets/logo.svg +14 -0
  10. package/assets/pipeline.mmd +39 -0
  11. package/assets/record-demo.sh +51 -0
  12. package/docs/README.md +51 -0
  13. package/docs/adapters/context-mode.md +60 -0
  14. package/docs/concepts/architecture.md +87 -0
  15. package/docs/concepts/artifact-model.md +60 -0
  16. package/docs/concepts/composition-engine.md +36 -0
  17. package/docs/concepts/indexing-and-recall.md +160 -0
  18. package/docs/concepts/observability.md +41 -0
  19. package/docs/concepts/roles-and-workflows.md +59 -0
  20. package/docs/concepts/terminology-policy.md +27 -0
  21. package/docs/getting-started/01-installation.md +78 -0
  22. package/docs/getting-started/02-first-run.md +102 -0
  23. package/docs/getting-started/03-adding-to-project.md +15 -0
  24. package/docs/getting-started/04-host-setup.md +15 -0
  25. package/docs/guides/ci-integration.md +15 -0
  26. package/docs/guides/creating-skills.md +15 -0
  27. package/docs/guides/expertise-module-authoring.md +15 -0
  28. package/docs/guides/hook-development.md +15 -0
  29. package/docs/guides/memory-and-learnings.md +34 -0
  30. package/docs/guides/multi-host-export.md +15 -0
  31. package/docs/guides/troubleshooting.md +101 -0
  32. package/docs/guides/writing-custom-roles.md +15 -0
  33. package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
  34. package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
  35. package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
  36. package/docs/readmes/INDEX.md +99 -0
  37. package/docs/readmes/features/expertise/README.md +171 -0
  38. package/docs/readmes/features/exports/README.md +222 -0
  39. package/docs/readmes/features/hooks/README.md +103 -0
  40. package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
  41. package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
  42. package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
  43. package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
  44. package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
  45. package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
  46. package/docs/readmes/features/hooks/session-start.md +119 -0
  47. package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
  48. package/docs/readmes/features/roles/README.md +157 -0
  49. package/docs/readmes/features/roles/clarifier.md +152 -0
  50. package/docs/readmes/features/roles/content-author.md +190 -0
  51. package/docs/readmes/features/roles/designer.md +193 -0
  52. package/docs/readmes/features/roles/executor.md +184 -0
  53. package/docs/readmes/features/roles/learner.md +210 -0
  54. package/docs/readmes/features/roles/planner.md +182 -0
  55. package/docs/readmes/features/roles/researcher.md +164 -0
  56. package/docs/readmes/features/roles/reviewer.md +184 -0
  57. package/docs/readmes/features/roles/specifier.md +162 -0
  58. package/docs/readmes/features/roles/verifier.md +215 -0
  59. package/docs/readmes/features/schemas/README.md +178 -0
  60. package/docs/readmes/features/skills/README.md +63 -0
  61. package/docs/readmes/features/skills/brainstorming.md +96 -0
  62. package/docs/readmes/features/skills/debugging.md +148 -0
  63. package/docs/readmes/features/skills/design.md +120 -0
  64. package/docs/readmes/features/skills/prepare-next.md +109 -0
  65. package/docs/readmes/features/skills/run-audit.md +159 -0
  66. package/docs/readmes/features/skills/scan-project.md +109 -0
  67. package/docs/readmes/features/skills/self-audit.md +176 -0
  68. package/docs/readmes/features/skills/tdd.md +137 -0
  69. package/docs/readmes/features/skills/using-skills.md +92 -0
  70. package/docs/readmes/features/skills/verification.md +120 -0
  71. package/docs/readmes/features/skills/writing-plans.md +104 -0
  72. package/docs/readmes/features/tooling/README.md +320 -0
  73. package/docs/readmes/features/workflows/README.md +186 -0
  74. package/docs/readmes/features/workflows/author.md +181 -0
  75. package/docs/readmes/features/workflows/clarify.md +154 -0
  76. package/docs/readmes/features/workflows/design-review.md +171 -0
  77. package/docs/readmes/features/workflows/design.md +169 -0
  78. package/docs/readmes/features/workflows/discover.md +162 -0
  79. package/docs/readmes/features/workflows/execute.md +173 -0
  80. package/docs/readmes/features/workflows/learn.md +167 -0
  81. package/docs/readmes/features/workflows/plan-review.md +165 -0
  82. package/docs/readmes/features/workflows/plan.md +170 -0
  83. package/docs/readmes/features/workflows/prepare-next.md +167 -0
  84. package/docs/readmes/features/workflows/review.md +169 -0
  85. package/docs/readmes/features/workflows/run-audit.md +191 -0
  86. package/docs/readmes/features/workflows/spec-challenge.md +159 -0
  87. package/docs/readmes/features/workflows/specify.md +160 -0
  88. package/docs/readmes/features/workflows/verify.md +177 -0
  89. package/docs/readmes/packages/README.md +50 -0
  90. package/docs/readmes/packages/ajv.md +117 -0
  91. package/docs/readmes/packages/context-mode.md +118 -0
  92. package/docs/readmes/packages/gray-matter.md +116 -0
  93. package/docs/readmes/packages/node-test.md +137 -0
  94. package/docs/readmes/packages/yaml.md +112 -0
  95. package/docs/reference/configuration-reference.md +159 -0
  96. package/docs/reference/expertise-index.md +52 -0
  97. package/docs/reference/git-flow.md +43 -0
  98. package/docs/reference/hooks.md +87 -0
  99. package/docs/reference/host-exports.md +50 -0
  100. package/docs/reference/launch-checklist.md +172 -0
  101. package/docs/reference/marketplace-listings.md +76 -0
  102. package/docs/reference/release-process.md +34 -0
  103. package/docs/reference/roles-reference.md +77 -0
  104. package/docs/reference/skills.md +33 -0
  105. package/docs/reference/templates.md +29 -0
  106. package/docs/reference/tooling-cli.md +94 -0
  107. package/docs/truth-claims.yaml +222 -0
  108. package/expertise/PROGRESS.md +63 -0
  109. package/expertise/README.md +18 -0
  110. package/expertise/antipatterns/PROGRESS.md +56 -0
  111. package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
  112. package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
  113. package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
  114. package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
  115. package/expertise/antipatterns/backend/index.md +24 -0
  116. package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
  117. package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
  118. package/expertise/antipatterns/code/async-antipatterns.md +622 -0
  119. package/expertise/antipatterns/code/code-smells.md +1186 -0
  120. package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
  121. package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
  122. package/expertise/antipatterns/code/index.md +27 -0
  123. package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
  124. package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
  125. package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
  126. package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
  127. package/expertise/antipatterns/design/dark-patterns.md +1121 -0
  128. package/expertise/antipatterns/design/index.md +22 -0
  129. package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
  130. package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
  131. package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
  132. package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
  133. package/expertise/antipatterns/frontend/index.md +23 -0
  134. package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
  135. package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
  136. package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
  137. package/expertise/antipatterns/index.md +31 -0
  138. package/expertise/antipatterns/performance/index.md +20 -0
  139. package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
  140. package/expertise/antipatterns/performance/premature-optimization.md +623 -0
  141. package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
  142. package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
  143. package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
  144. package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
  145. package/expertise/antipatterns/process/index.md +23 -0
  146. package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
  147. package/expertise/antipatterns/security/index.md +20 -0
  148. package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
  149. package/expertise/antipatterns/security/security-theater.md +843 -0
  150. package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
  151. package/expertise/architecture/PROGRESS.md +70 -0
  152. package/expertise/architecture/data/caching-architecture.md +671 -0
  153. package/expertise/architecture/data/data-consistency.md +574 -0
  154. package/expertise/architecture/data/data-modeling.md +536 -0
  155. package/expertise/architecture/data/event-streams-and-queues.md +634 -0
  156. package/expertise/architecture/data/index.md +25 -0
  157. package/expertise/architecture/data/search-architecture.md +663 -0
  158. package/expertise/architecture/data/sql-vs-nosql.md +708 -0
  159. package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
  160. package/expertise/architecture/decisions/build-vs-buy.md +616 -0
  161. package/expertise/architecture/decisions/index.md +23 -0
  162. package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
  163. package/expertise/architecture/decisions/technology-selection.md +616 -0
  164. package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
  165. package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
  166. package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
  167. package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
  168. package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
  169. package/expertise/architecture/distributed/index.md +25 -0
  170. package/expertise/architecture/distributed/saga-pattern.md +797 -0
  171. package/expertise/architecture/foundations/architectural-thinking.md +460 -0
  172. package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
  173. package/expertise/architecture/foundations/design-principles-solid.md +649 -0
  174. package/expertise/architecture/foundations/domain-driven-design.md +719 -0
  175. package/expertise/architecture/foundations/index.md +25 -0
  176. package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
  177. package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
  178. package/expertise/architecture/index.md +34 -0
  179. package/expertise/architecture/integration/api-design-graphql.md +638 -0
  180. package/expertise/architecture/integration/api-design-grpc.md +804 -0
  181. package/expertise/architecture/integration/api-design-rest.md +892 -0
  182. package/expertise/architecture/integration/index.md +25 -0
  183. package/expertise/architecture/integration/third-party-integration.md +795 -0
  184. package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
  185. package/expertise/architecture/integration/websockets-realtime.md +791 -0
  186. package/expertise/architecture/mobile-architecture/index.md +22 -0
  187. package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
  188. package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
  189. package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
  190. package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
  191. package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
  192. package/expertise/architecture/patterns/event-driven.md +797 -0
  193. package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
  194. package/expertise/architecture/patterns/index.md +27 -0
  195. package/expertise/architecture/patterns/layered-architecture.md +736 -0
  196. package/expertise/architecture/patterns/microservices.md +753 -0
  197. package/expertise/architecture/patterns/modular-monolith.md +692 -0
  198. package/expertise/architecture/patterns/monolith.md +626 -0
  199. package/expertise/architecture/patterns/plugin-architecture.md +735 -0
  200. package/expertise/architecture/patterns/serverless.md +780 -0
  201. package/expertise/architecture/scaling/database-scaling.md +615 -0
  202. package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
  203. package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
  204. package/expertise/architecture/scaling/index.md +24 -0
  205. package/expertise/architecture/scaling/multi-tenancy.md +800 -0
  206. package/expertise/architecture/scaling/stateless-design.md +787 -0
  207. package/expertise/backend/embedded-firmware.md +625 -0
  208. package/expertise/backend/go.md +853 -0
  209. package/expertise/backend/index.md +24 -0
  210. package/expertise/backend/java-spring.md +448 -0
  211. package/expertise/backend/node-typescript.md +625 -0
  212. package/expertise/backend/python-fastapi.md +724 -0
  213. package/expertise/backend/rust.md +458 -0
  214. package/expertise/backend/solidity.md +711 -0
  215. package/expertise/composition-map.yaml +443 -0
  216. package/expertise/content/foundations/content-modeling.md +395 -0
  217. package/expertise/content/foundations/editorial-standards.md +449 -0
  218. package/expertise/content/foundations/index.md +24 -0
  219. package/expertise/content/foundations/microcopy.md +455 -0
  220. package/expertise/content/foundations/terminology-governance.md +509 -0
  221. package/expertise/content/index.md +34 -0
  222. package/expertise/content/patterns/accessibility-copy.md +518 -0
  223. package/expertise/content/patterns/index.md +24 -0
  224. package/expertise/content/patterns/notification-content.md +433 -0
  225. package/expertise/content/patterns/sample-content.md +486 -0
  226. package/expertise/content/patterns/state-copy.md +439 -0
  227. package/expertise/design/PROGRESS.md +58 -0
  228. package/expertise/design/disciplines/dark-mode-theming.md +577 -0
  229. package/expertise/design/disciplines/design-systems.md +595 -0
  230. package/expertise/design/disciplines/index.md +25 -0
  231. package/expertise/design/disciplines/information-architecture.md +800 -0
  232. package/expertise/design/disciplines/interaction-design.md +788 -0
  233. package/expertise/design/disciplines/responsive-design.md +552 -0
  234. package/expertise/design/disciplines/usability-testing.md +516 -0
  235. package/expertise/design/disciplines/user-research.md +792 -0
  236. package/expertise/design/foundations/accessibility-design.md +796 -0
  237. package/expertise/design/foundations/color-theory.md +797 -0
  238. package/expertise/design/foundations/iconography.md +795 -0
  239. package/expertise/design/foundations/index.md +26 -0
  240. package/expertise/design/foundations/motion-and-animation.md +653 -0
  241. package/expertise/design/foundations/rtl-design.md +585 -0
  242. package/expertise/design/foundations/spacing-and-layout.md +607 -0
  243. package/expertise/design/foundations/typography.md +800 -0
  244. package/expertise/design/foundations/visual-hierarchy.md +761 -0
  245. package/expertise/design/index.md +32 -0
  246. package/expertise/design/patterns/authentication-flows.md +474 -0
  247. package/expertise/design/patterns/content-consumption.md +789 -0
  248. package/expertise/design/patterns/data-display.md +618 -0
  249. package/expertise/design/patterns/e-commerce.md +1494 -0
  250. package/expertise/design/patterns/feedback-and-states.md +642 -0
  251. package/expertise/design/patterns/forms-and-input.md +819 -0
  252. package/expertise/design/patterns/gamification.md +801 -0
  253. package/expertise/design/patterns/index.md +31 -0
  254. package/expertise/design/patterns/microinteractions.md +449 -0
  255. package/expertise/design/patterns/navigation.md +800 -0
  256. package/expertise/design/patterns/notifications.md +705 -0
  257. package/expertise/design/patterns/onboarding.md +700 -0
  258. package/expertise/design/patterns/search-and-filter.md +601 -0
  259. package/expertise/design/patterns/settings-and-preferences.md +768 -0
  260. package/expertise/design/patterns/social-and-community.md +748 -0
  261. package/expertise/design/platforms/desktop-native.md +612 -0
  262. package/expertise/design/platforms/index.md +25 -0
  263. package/expertise/design/platforms/mobile-android.md +825 -0
  264. package/expertise/design/platforms/mobile-cross-platform.md +983 -0
  265. package/expertise/design/platforms/mobile-ios.md +699 -0
  266. package/expertise/design/platforms/tablet.md +794 -0
  267. package/expertise/design/platforms/web-dashboard.md +790 -0
  268. package/expertise/design/platforms/web-responsive.md +550 -0
  269. package/expertise/design/psychology/behavioral-nudges.md +449 -0
  270. package/expertise/design/psychology/cognitive-load.md +1191 -0
  271. package/expertise/design/psychology/error-psychology.md +778 -0
  272. package/expertise/design/psychology/index.md +22 -0
  273. package/expertise/design/psychology/persuasive-design.md +736 -0
  274. package/expertise/design/psychology/user-mental-models.md +623 -0
  275. package/expertise/design/tooling/open-pencil.md +266 -0
  276. package/expertise/frontend/angular.md +1073 -0
  277. package/expertise/frontend/desktop-electron.md +546 -0
  278. package/expertise/frontend/flutter.md +782 -0
  279. package/expertise/frontend/index.md +27 -0
  280. package/expertise/frontend/native-android.md +409 -0
  281. package/expertise/frontend/native-ios.md +490 -0
  282. package/expertise/frontend/react-native.md +1160 -0
  283. package/expertise/frontend/react.md +808 -0
  284. package/expertise/frontend/vue.md +1089 -0
  285. package/expertise/humanize/domain-rules-code.md +79 -0
  286. package/expertise/humanize/domain-rules-content.md +67 -0
  287. package/expertise/humanize/domain-rules-technical-docs.md +56 -0
  288. package/expertise/humanize/index.md +35 -0
  289. package/expertise/humanize/self-audit-checklist.md +87 -0
  290. package/expertise/humanize/sentence-patterns.md +218 -0
  291. package/expertise/humanize/vocabulary-blacklist.md +105 -0
  292. package/expertise/i18n/PROGRESS.md +65 -0
  293. package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
  294. package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
  295. package/expertise/i18n/advanced/complex-scripts.md +30 -0
  296. package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
  297. package/expertise/i18n/advanced/testing-i18n.md +28 -0
  298. package/expertise/i18n/content/content-adaptation.md +23 -0
  299. package/expertise/i18n/content/locale-specific-formatting.md +23 -0
  300. package/expertise/i18n/content/machine-translation-integration.md +28 -0
  301. package/expertise/i18n/content/translation-management.md +29 -0
  302. package/expertise/i18n/foundations/date-time-calendars.md +67 -0
  303. package/expertise/i18n/foundations/i18n-architecture.md +272 -0
  304. package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
  305. package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
  306. package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
  307. package/expertise/i18n/foundations/string-externalization.md +236 -0
  308. package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
  309. package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
  310. package/expertise/i18n/index.md +38 -0
  311. package/expertise/i18n/platform/backend-i18n.md +31 -0
  312. package/expertise/i18n/platform/flutter-i18n.md +148 -0
  313. package/expertise/i18n/platform/native-android-i18n.md +36 -0
  314. package/expertise/i18n/platform/native-ios-i18n.md +36 -0
  315. package/expertise/i18n/platform/react-i18n.md +103 -0
  316. package/expertise/i18n/platform/web-css-i18n.md +81 -0
  317. package/expertise/i18n/rtl/arabic-specific.md +175 -0
  318. package/expertise/i18n/rtl/hebrew-specific.md +149 -0
  319. package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
  320. package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
  321. package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
  322. package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
  323. package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
  324. package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
  325. package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
  326. package/expertise/i18n/rtl/rtl-typography.md +160 -0
  327. package/expertise/index.md +113 -0
  328. package/expertise/index.yaml +216 -0
  329. package/expertise/infrastructure/cloud-aws.md +597 -0
  330. package/expertise/infrastructure/cloud-gcp.md +599 -0
  331. package/expertise/infrastructure/cybersecurity.md +816 -0
  332. package/expertise/infrastructure/database-mongodb.md +447 -0
  333. package/expertise/infrastructure/database-postgres.md +400 -0
  334. package/expertise/infrastructure/devops-cicd.md +787 -0
  335. package/expertise/infrastructure/index.md +27 -0
  336. package/expertise/performance/PROGRESS.md +50 -0
  337. package/expertise/performance/backend/api-latency.md +1204 -0
  338. package/expertise/performance/backend/background-jobs.md +506 -0
  339. package/expertise/performance/backend/connection-pooling.md +1209 -0
  340. package/expertise/performance/backend/database-query-optimization.md +515 -0
  341. package/expertise/performance/backend/index.md +23 -0
  342. package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
  343. package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
  344. package/expertise/performance/foundations/caching-strategies.md +489 -0
  345. package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
  346. package/expertise/performance/foundations/index.md +24 -0
  347. package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
  348. package/expertise/performance/foundations/memory-management.md +964 -0
  349. package/expertise/performance/foundations/performance-budgets.md +1314 -0
  350. package/expertise/performance/index.md +31 -0
  351. package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
  352. package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
  353. package/expertise/performance/infrastructure/index.md +22 -0
  354. package/expertise/performance/infrastructure/load-balancing.md +1081 -0
  355. package/expertise/performance/infrastructure/observability.md +1079 -0
  356. package/expertise/performance/mobile/index.md +23 -0
  357. package/expertise/performance/mobile/mobile-animations.md +544 -0
  358. package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
  359. package/expertise/performance/mobile/mobile-network.md +452 -0
  360. package/expertise/performance/mobile/mobile-rendering.md +599 -0
  361. package/expertise/performance/mobile/mobile-startup-time.md +505 -0
  362. package/expertise/performance/platform-specific/flutter-performance.md +647 -0
  363. package/expertise/performance/platform-specific/index.md +22 -0
  364. package/expertise/performance/platform-specific/node-performance.md +1307 -0
  365. package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
  366. package/expertise/performance/platform-specific/react-performance.md +1403 -0
  367. package/expertise/performance/web/bundle-optimization.md +1239 -0
  368. package/expertise/performance/web/image-and-media.md +636 -0
  369. package/expertise/performance/web/index.md +24 -0
  370. package/expertise/performance/web/network-optimization.md +1133 -0
  371. package/expertise/performance/web/rendering-performance.md +1098 -0
  372. package/expertise/performance/web/ssr-and-hydration.md +918 -0
  373. package/expertise/performance/web/web-vitals.md +1374 -0
  374. package/expertise/quality/accessibility.md +985 -0
  375. package/expertise/quality/evidence-based-verification.md +499 -0
  376. package/expertise/quality/index.md +24 -0
  377. package/expertise/quality/ml-model-audit.md +614 -0
  378. package/expertise/quality/performance.md +600 -0
  379. package/expertise/quality/testing-api.md +891 -0
  380. package/expertise/quality/testing-mobile.md +496 -0
  381. package/expertise/quality/testing-web.md +849 -0
  382. package/expertise/security/PROGRESS.md +54 -0
  383. package/expertise/security/agentic-identity.md +540 -0
  384. package/expertise/security/compliance-frameworks.md +601 -0
  385. package/expertise/security/data/data-encryption.md +364 -0
  386. package/expertise/security/data/data-privacy-gdpr.md +692 -0
  387. package/expertise/security/data/database-security.md +1171 -0
  388. package/expertise/security/data/index.md +22 -0
  389. package/expertise/security/data/pii-handling.md +531 -0
  390. package/expertise/security/foundations/authentication.md +1041 -0
  391. package/expertise/security/foundations/authorization.md +603 -0
  392. package/expertise/security/foundations/cryptography.md +1001 -0
  393. package/expertise/security/foundations/index.md +25 -0
  394. package/expertise/security/foundations/owasp-top-10.md +1354 -0
  395. package/expertise/security/foundations/secrets-management.md +1217 -0
  396. package/expertise/security/foundations/secure-sdlc.md +700 -0
  397. package/expertise/security/foundations/supply-chain-security.md +698 -0
  398. package/expertise/security/index.md +31 -0
  399. package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
  400. package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
  401. package/expertise/security/infrastructure/container-security.md +721 -0
  402. package/expertise/security/infrastructure/incident-response.md +1295 -0
  403. package/expertise/security/infrastructure/index.md +24 -0
  404. package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
  405. package/expertise/security/infrastructure/network-security.md +1337 -0
  406. package/expertise/security/mobile/index.md +23 -0
  407. package/expertise/security/mobile/mobile-android-security.md +1218 -0
  408. package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
  409. package/expertise/security/mobile/mobile-data-storage.md +1265 -0
  410. package/expertise/security/mobile/mobile-ios-security.md +1401 -0
  411. package/expertise/security/mobile/mobile-network-security.md +1520 -0
  412. package/expertise/security/smart-contract-security.md +594 -0
  413. package/expertise/security/testing/index.md +22 -0
  414. package/expertise/security/testing/penetration-testing.md +1258 -0
  415. package/expertise/security/testing/security-code-review.md +1765 -0
  416. package/expertise/security/testing/threat-modeling.md +1074 -0
  417. package/expertise/security/testing/vulnerability-scanning.md +1062 -0
  418. package/expertise/security/web/api-security.md +586 -0
  419. package/expertise/security/web/cors-and-headers.md +433 -0
  420. package/expertise/security/web/csrf.md +562 -0
  421. package/expertise/security/web/file-upload.md +1477 -0
  422. package/expertise/security/web/index.md +25 -0
  423. package/expertise/security/web/injection.md +1375 -0
  424. package/expertise/security/web/session-management.md +1101 -0
  425. package/expertise/security/web/xss.md +1158 -0
  426. package/exports/README.md +17 -0
  427. package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
  428. package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
  429. package/exports/hosts/claude/.claude/agents/designer.md +55 -0
  430. package/exports/hosts/claude/.claude/agents/executor.md +55 -0
  431. package/exports/hosts/claude/.claude/agents/learner.md +51 -0
  432. package/exports/hosts/claude/.claude/agents/planner.md +53 -0
  433. package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
  434. package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
  435. package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
  436. package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
  437. package/exports/hosts/claude/.claude/commands/author.md +42 -0
  438. package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
  439. package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
  440. package/exports/hosts/claude/.claude/commands/design.md +44 -0
  441. package/exports/hosts/claude/.claude/commands/discover.md +37 -0
  442. package/exports/hosts/claude/.claude/commands/execute.md +48 -0
  443. package/exports/hosts/claude/.claude/commands/learn.md +38 -0
  444. package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
  445. package/exports/hosts/claude/.claude/commands/plan.md +39 -0
  446. package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
  447. package/exports/hosts/claude/.claude/commands/review.md +40 -0
  448. package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
  449. package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
  450. package/exports/hosts/claude/.claude/commands/specify.md +38 -0
  451. package/exports/hosts/claude/.claude/commands/verify.md +37 -0
  452. package/exports/hosts/claude/.claude/settings.json +34 -0
  453. package/exports/hosts/claude/CLAUDE.md +19 -0
  454. package/exports/hosts/claude/export.manifest.json +38 -0
  455. package/exports/hosts/claude/host-package.json +67 -0
  456. package/exports/hosts/codex/AGENTS.md +19 -0
  457. package/exports/hosts/codex/export.manifest.json +38 -0
  458. package/exports/hosts/codex/host-package.json +41 -0
  459. package/exports/hosts/cursor/.cursor/hooks.json +16 -0
  460. package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
  461. package/exports/hosts/cursor/export.manifest.json +38 -0
  462. package/exports/hosts/cursor/host-package.json +42 -0
  463. package/exports/hosts/gemini/GEMINI.md +19 -0
  464. package/exports/hosts/gemini/export.manifest.json +38 -0
  465. package/exports/hosts/gemini/host-package.json +41 -0
  466. package/hooks/README.md +18 -0
  467. package/hooks/definitions/loop_cap_guard.yaml +21 -0
  468. package/hooks/definitions/post_tool_capture.yaml +24 -0
  469. package/hooks/definitions/pre_compact_summary.yaml +19 -0
  470. package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
  471. package/hooks/definitions/protected_path_write_guard.yaml +19 -0
  472. package/hooks/definitions/session_start.yaml +19 -0
  473. package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
  474. package/hooks/loop-cap-guard +17 -0
  475. package/hooks/post-tool-lint +36 -0
  476. package/hooks/protected-path-write-guard +17 -0
  477. package/hooks/session-start +41 -0
  478. package/llms-full.txt +2355 -0
  479. package/llms.txt +43 -0
  480. package/package.json +79 -0
  481. package/roles/README.md +20 -0
  482. package/roles/clarifier.md +42 -0
  483. package/roles/content-author.md +63 -0
  484. package/roles/designer.md +55 -0
  485. package/roles/executor.md +55 -0
  486. package/roles/learner.md +51 -0
  487. package/roles/planner.md +53 -0
  488. package/roles/researcher.md +43 -0
  489. package/roles/reviewer.md +54 -0
  490. package/roles/specifier.md +47 -0
  491. package/roles/verifier.md +71 -0
  492. package/schemas/README.md +24 -0
  493. package/schemas/accepted-learning.schema.json +20 -0
  494. package/schemas/author-artifact.schema.json +156 -0
  495. package/schemas/clarification.schema.json +19 -0
  496. package/schemas/design-artifact.schema.json +80 -0
  497. package/schemas/docs-claim.schema.json +18 -0
  498. package/schemas/export-manifest.schema.json +20 -0
  499. package/schemas/hook.schema.json +67 -0
  500. package/schemas/host-export-package.schema.json +18 -0
  501. package/schemas/implementation-plan.schema.json +19 -0
  502. package/schemas/proposed-learning.schema.json +19 -0
  503. package/schemas/research.schema.json +18 -0
  504. package/schemas/review.schema.json +29 -0
  505. package/schemas/run-manifest.schema.json +18 -0
  506. package/schemas/spec-challenge.schema.json +18 -0
  507. package/schemas/spec.schema.json +20 -0
  508. package/schemas/usage.schema.json +102 -0
  509. package/schemas/verification-proof.schema.json +29 -0
  510. package/schemas/wazir-manifest.schema.json +173 -0
  511. package/skills/README.md +40 -0
  512. package/skills/brainstorming/SKILL.md +77 -0
  513. package/skills/debugging/SKILL.md +50 -0
  514. package/skills/design/SKILL.md +61 -0
  515. package/skills/dispatching-parallel-agents/SKILL.md +128 -0
  516. package/skills/executing-plans/SKILL.md +70 -0
  517. package/skills/finishing-a-development-branch/SKILL.md +169 -0
  518. package/skills/humanize/SKILL.md +123 -0
  519. package/skills/init-pipeline/SKILL.md +124 -0
  520. package/skills/prepare-next/SKILL.md +20 -0
  521. package/skills/receiving-code-review/SKILL.md +123 -0
  522. package/skills/requesting-code-review/SKILL.md +105 -0
  523. package/skills/requesting-code-review/code-reviewer.md +108 -0
  524. package/skills/run-audit/SKILL.md +197 -0
  525. package/skills/scan-project/SKILL.md +41 -0
  526. package/skills/self-audit/SKILL.md +153 -0
  527. package/skills/subagent-driven-development/SKILL.md +154 -0
  528. package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
  529. package/skills/subagent-driven-development/implementer-prompt.md +102 -0
  530. package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
  531. package/skills/tdd/SKILL.md +23 -0
  532. package/skills/using-git-worktrees/SKILL.md +163 -0
  533. package/skills/using-skills/SKILL.md +95 -0
  534. package/skills/verification/SKILL.md +22 -0
  535. package/skills/wazir/SKILL.md +463 -0
  536. package/skills/writing-plans/SKILL.md +30 -0
  537. package/skills/writing-skills/SKILL.md +157 -0
  538. package/skills/writing-skills/anthropic-best-practices.md +122 -0
  539. package/skills/writing-skills/persuasion-principles.md +50 -0
  540. package/templates/README.md +20 -0
  541. package/templates/artifacts/README.md +10 -0
  542. package/templates/artifacts/accepted-learning.md +19 -0
  543. package/templates/artifacts/accepted-learning.template.json +12 -0
  544. package/templates/artifacts/author.md +74 -0
  545. package/templates/artifacts/author.template.json +19 -0
  546. package/templates/artifacts/clarification.md +21 -0
  547. package/templates/artifacts/clarification.template.json +12 -0
  548. package/templates/artifacts/execute-notes.md +19 -0
  549. package/templates/artifacts/implementation-plan.md +21 -0
  550. package/templates/artifacts/implementation-plan.template.json +11 -0
  551. package/templates/artifacts/learning-proposal.md +19 -0
  552. package/templates/artifacts/next-run-handoff.md +21 -0
  553. package/templates/artifacts/plan-review.md +19 -0
  554. package/templates/artifacts/proposed-learning.template.json +12 -0
  555. package/templates/artifacts/research.md +21 -0
  556. package/templates/artifacts/research.template.json +12 -0
  557. package/templates/artifacts/review-findings.md +19 -0
  558. package/templates/artifacts/review.template.json +11 -0
  559. package/templates/artifacts/run-manifest.template.json +8 -0
  560. package/templates/artifacts/spec-challenge.md +19 -0
  561. package/templates/artifacts/spec-challenge.template.json +11 -0
  562. package/templates/artifacts/spec.md +21 -0
  563. package/templates/artifacts/spec.template.json +12 -0
  564. package/templates/artifacts/verification-proof.md +19 -0
  565. package/templates/artifacts/verification-proof.template.json +11 -0
  566. package/templates/examples/accepted-learning.example.json +14 -0
  567. package/templates/examples/author.example.json +152 -0
  568. package/templates/examples/clarification.example.json +15 -0
  569. package/templates/examples/docs-claim.example.json +8 -0
  570. package/templates/examples/export-manifest.example.json +7 -0
  571. package/templates/examples/host-export-package.example.json +11 -0
  572. package/templates/examples/implementation-plan.example.json +17 -0
  573. package/templates/examples/proposed-learning.example.json +13 -0
  574. package/templates/examples/research.example.json +15 -0
  575. package/templates/examples/research.example.md +6 -0
  576. package/templates/examples/review.example.json +17 -0
  577. package/templates/examples/run-manifest.example.json +9 -0
  578. package/templates/examples/spec-challenge.example.json +14 -0
  579. package/templates/examples/spec.example.json +21 -0
  580. package/templates/examples/verification-proof.example.json +21 -0
  581. package/templates/examples/wazir-manifest.example.yaml +65 -0
  582. package/templates/task-definition-schema.md +99 -0
  583. package/tooling/README.md +20 -0
  584. package/tooling/src/adapters/context-mode.js +50 -0
  585. package/tooling/src/capture/command.js +376 -0
  586. package/tooling/src/capture/store.js +99 -0
  587. package/tooling/src/capture/usage.js +270 -0
  588. package/tooling/src/checks/branches.js +50 -0
  589. package/tooling/src/checks/brand-truth.js +110 -0
  590. package/tooling/src/checks/changelog.js +231 -0
  591. package/tooling/src/checks/command-registry.js +36 -0
  592. package/tooling/src/checks/commits.js +102 -0
  593. package/tooling/src/checks/docs-drift.js +103 -0
  594. package/tooling/src/checks/docs-truth.js +201 -0
  595. package/tooling/src/checks/runtime-surface.js +156 -0
  596. package/tooling/src/cli.js +116 -0
  597. package/tooling/src/command-options.js +56 -0
  598. package/tooling/src/commands/validate.js +320 -0
  599. package/tooling/src/doctor/command.js +91 -0
  600. package/tooling/src/export/command.js +77 -0
  601. package/tooling/src/export/compiler.js +498 -0
  602. package/tooling/src/guards/loop-cap-guard.js +52 -0
  603. package/tooling/src/guards/protected-path-write-guard.js +67 -0
  604. package/tooling/src/index/command.js +152 -0
  605. package/tooling/src/index/storage.js +1061 -0
  606. package/tooling/src/index/summarizers.js +261 -0
  607. package/tooling/src/loaders.js +18 -0
  608. package/tooling/src/project-root.js +22 -0
  609. package/tooling/src/recall/command.js +225 -0
  610. package/tooling/src/schema-validator.js +30 -0
  611. package/tooling/src/state-root.js +40 -0
  612. package/tooling/src/status/command.js +71 -0
  613. package/wazir.manifest.yaml +135 -0
  614. package/workflows/README.md +19 -0
  615. package/workflows/author.md +42 -0
  616. package/workflows/clarify.md +38 -0
  617. package/workflows/design-review.md +46 -0
  618. package/workflows/design.md +44 -0
  619. package/workflows/discover.md +37 -0
  620. package/workflows/execute.md +48 -0
  621. package/workflows/learn.md +38 -0
  622. package/workflows/plan-review.md +42 -0
  623. package/workflows/plan.md +39 -0
  624. package/workflows/prepare-next.md +37 -0
  625. package/workflows/review.md +40 -0
  626. package/workflows/run-audit.md +41 -0
  627. package/workflows/spec-challenge.md +41 -0
  628. package/workflows/specify.md +38 -0
  629. package/workflows/verify.md +37 -0
@@ -0,0 +1,1160 @@
1
+ # React Native — Expertise Module
2
+
3
+ > A React Native specialist builds cross-platform iOS and Android applications using TypeScript
4
+ > and the React Native framework (currently React Native 0.79, shipped in Expo SDK 53). The scope
5
+ > covers Expo-managed workflows, TypeScript architecture, state management (TanStack Query v5 +
6
+ > Zustand v5), navigation (Expo Router v4), native module boundaries, performance tuning (Hermes,
7
+ > New Architecture, FlashList v2, Reanimated 4), testing (Jest + React Native Testing Library,
8
+ > Maestro/Detox), CI/CD (EAS Build + EAS Update + EAS Submit), and delivery to iOS App Store
9
+ > and Google Play.
10
+
11
+ ---
12
+
13
+ ## Core Patterns & Conventions
14
+
15
+ ### Project Structure
16
+
17
+ Use **feature-first** organization for apps beyond a single feature. Each feature owns its routes,
18
+ components, hooks, and store slices. Shared code lives in `components/`, `hooks/`, `services/`,
19
+ and `stores/`.
20
+
21
+ ```
22
+ app/ # Expo Router v4 file-based routes
23
+ (auth)/ # Guarded Group — unauthenticated routes
24
+ login.tsx
25
+ register.tsx
26
+ (app)/ # Guarded Group — authenticated routes
27
+ _layout.tsx
28
+ index.tsx
29
+ profile.tsx
30
+ _layout.tsx # Root layout: providers + auth guard
31
+ components/
32
+ ui/ # Reusable presentational components
33
+ forms/
34
+ features/
35
+ auth/
36
+ hooks/
37
+ stores/
38
+ feed/
39
+ hooks/
40
+ stores/
41
+ hooks/ # Shared cross-feature hooks
42
+ services/ # API clients, native wrappers
43
+ stores/ # Zustand store slices
44
+ constants/ # SCREAMING_SNAKE values, theme tokens
45
+ .maestro/ # Maestro E2E flows
46
+ ```
47
+
48
+ Import `SafeAreaProvider` and `react-native-edge-to-edge` setup in the root `app/_layout.tsx`.
49
+ Wire `react-native-safe-area-context` for all inset-aware padding.
50
+
51
+ ### Naming Conventions
52
+
53
+ | Element | Convention | Example |
54
+ |---------|-----------|---------|
55
+ | Files | `kebab-case` | `user-profile.tsx` |
56
+ | Components | `PascalCase` | `UserProfileCard` |
57
+ | Custom hooks | `use` prefix | `useAuthStore`, `useUserProfile` |
58
+ | Stores | camelCase + `Store` suffix | `authStore`, `feedStore` |
59
+ | Constants | `SCREAMING_SNAKE_CASE` | `MAX_RETRY_COUNT` |
60
+ | Types / Interfaces | `PascalCase` | `UserProfile`, `ApiResponse<T>` |
61
+ | Route files | `kebab-case` | `user-settings.tsx` |
62
+ | Test files | `*.test.tsx` | `user-profile.test.tsx` |
63
+
64
+ ### Architecture Patterns
65
+
66
+ Follow a **feature-slice** architecture:
67
+ - **Screens** own composition only — no inline business logic.
68
+ - **Custom hooks** own data fetching (via TanStack Query) and derived state.
69
+ - **Zustand store slices** own persistent client state (auth tokens in memory, preferences, UI flags).
70
+ - **Services** own network calls and native module interactions.
71
+ - No God components. No prop drilling beyond two levels — pass a callback or use a store.
72
+
73
+ The three-tier state split is mandatory:
74
+ 1. **Server state** — TanStack Query v5 (caching, sync, pagination, background refetch).
75
+ 2. **App/client state** — Zustand v5 (auth session, user settings, cross-screen flags).
76
+ 3. **Component-local state** — `useState` / `useReducer` (form fields, toggles, modal visibility).
77
+
78
+ ### State Management
79
+
80
+ **TanStack Query v5** for all server-derived state:
81
+ - Unified object API: `useQuery({ queryKey: ['user', id], queryFn: fetchUser })`.
82
+ - **`onlineManager` wiring is required** — TanStack Query does not use `navigator.onLine` on React Native:
83
+
84
+ ```ts
85
+ import NetInfo from '@react-native-community/netinfo';
86
+ import { onlineManager } from '@tanstack/react-query';
87
+
88
+ // Wire once at app startup (before QueryClientProvider renders)
89
+ onlineManager.setEventListener((setOnline) =>
90
+ NetInfo.addEventListener((state) => setOnline(!!state.isConnected))
91
+ );
92
+ ```
93
+
94
+ - **`focusManager` wiring** for AppState foreground refetch:
95
+
96
+ ```ts
97
+ import { AppState, AppStateStatus } from 'react-native';
98
+ import { focusManager } from '@tanstack/react-query';
99
+
100
+ AppState.addEventListener('change', (status: AppStateStatus) =>
101
+ focusManager.setFocused(status === 'active')
102
+ );
103
+ ```
104
+
105
+ **Zustand v5** for client/app state:
106
+ - **`useShallow` is mandatory for object selectors** — v5 crashes (not just re-renders) without it:
107
+
108
+ ```ts
109
+ import { useShallow } from 'zustand/react/shallow';
110
+
111
+ // WRONG in v5 — crashes with "Maximum update depth exceeded"
112
+ const { user, token } = useAuthStore((s) => ({ user: s.user, token: s.token }));
113
+
114
+ // CORRECT
115
+ const { user, token } = useAuthStore(useShallow((s) => ({ user: s.user, token: s.token })));
116
+ ```
117
+
118
+ - Outside-React access via `store.getState()` — use in navigation guards, request interceptors, app init.
119
+ - Keep store state flat — avoid deeply nested objects for frequently-updated data.
120
+
121
+ ### Routing & Navigation
122
+
123
+ **Expo Router v4** (bundled with Expo SDK 53) is the default. File-based routing with typed routes
124
+ generated automatically by Expo CLI.
125
+
126
+ - Use **Guarded Groups** for auth flows — the canonical pattern in v4. A `guard` function on the
127
+ group checks state synchronously and redirects to an anchor route. Never use `useEffect` + manual
128
+ `router.replace()` for auth redirects.
129
+ - Guards call `useAuthStore.getState()` (not hooks) because the guard function runs outside the
130
+ React render cycle.
131
+ - Use `<Link prefetch />` or the imperative prefetch API for performance-sensitive transitions.
132
+ - Use typed `href` values from `expo-router` — the compiler catches broken routes.
133
+
134
+ **React Navigation v7** is the escape hatch for legacy projects or when Expo Router's file-based
135
+ model cannot express the required navigation structure.
136
+
137
+ ### Data Flow
138
+
139
+ Unidirectional data flow only:
140
+
141
+ ```
142
+ API → TanStack Query cache → screen hook → component props
143
+ ↑ |
144
+ └──────── mutations (invalidateQueries) ─┘
145
+
146
+ Cross-screen shared state: API → TanStack Query → Zustand action → component
147
+ ```
148
+
149
+ No circular data flows. Screens never call services directly — they call hooks that call services.
150
+
151
+ ### Error Handling
152
+
153
+ Define typed error states at every boundary:
154
+
155
+ ```ts
156
+ // Narrow unknown errors to a displayable message
157
+ function toErrorMessage(err: unknown): string {
158
+ if (err instanceof Error) return err.message;
159
+ if (typeof err === 'string') return err;
160
+ return 'An unexpected error occurred';
161
+ }
162
+
163
+ // TanStack Query exposes typed error state
164
+ const { data, error, isError } = useQuery({
165
+ queryKey: ['profile'],
166
+ queryFn: fetchProfile,
167
+ });
168
+ if (isError) return <ErrorScreen message={toErrorMessage(error)} />;
169
+ ```
170
+
171
+ - Mount an `ErrorBoundary` at screen level to catch render errors.
172
+ - Use Zod to validate API response shapes at the boundary — parse, don't trust.
173
+ - Never let raw network errors surface to users without transformation.
174
+
175
+ ### Logging & Observability
176
+
177
+ - **Sentry** (`@sentry/react-native`) for crash reporting and performance traces. Wire
178
+ `Sentry.init()` before `<App />` renders. Use `@sentry/expo` for Expo projects — it provides
179
+ automatic source map upload.
180
+ - **Firebase Crashlytics** as alternative for Firebase-first projects.
181
+ - Development: **Reactotron** for state/API inspection, or React Native Debugger.
182
+ - Never ship `console.log()` in production. Use a leveled logger that is a no-op in release builds.
183
+
184
+ ---
185
+
186
+ ## Anti-Patterns & Pitfalls
187
+
188
+ ### 1. Treating Server State as Client State
189
+
190
+ **Why it's a problem:** Fetching data from an API and storing it in Zustand or `useState` manually
191
+ means you own all the complexity TanStack Query already handles — caching, background refetch,
192
+ deduplication, stale-while-revalidate, error retries, and loading states. Duplication leads to
193
+ stale data, extra network calls, and cache inconsistency.
194
+ **Instead:** Use TanStack Query v5 for all server-derived state. Only put in Zustand what the API
195
+ does not own: session data, user preferences, UI state, transient cross-screen flags.
196
+
197
+ ### 2. Overusing Context for High-Frequency State
198
+
199
+ **Why it's a problem:** React Context triggers a re-render of every consumer on every value change.
200
+ Using Context for state that changes frequently (auth token, theme, cart contents) causes
201
+ full-subtree re-renders, degrading performance on lower-end Android devices where frame budget is
202
+ already tight.
203
+ **Instead:** Use Zustand with granular selectors for shared high-frequency state. Context is
204
+ appropriate for static or rarely-changing values (locale, color scheme). For everything dynamic,
205
+ prefer Zustand + `useShallow`.
206
+
207
+ ### 3. Blocking the JS Thread with Synchronous Work
208
+
209
+ **Why it's a problem:** React Native's JS thread is single-threaded. Heavy synchronous operations
210
+ (JSON parsing of large payloads, cryptographic operations, string processing loops) block the JS
211
+ thread and cause dropped frames. New Architecture JSI enables synchronous JS↔native calls —
212
+ but synchronous JS work still blocks the JS thread regardless.
213
+ **Instead:** Offload heavy computation to a Web Worker equivalent via `react-native-workers`, or
214
+ batch processing using `InteractionManager.runAfterInteractions()` to yield the thread after
215
+ animation frames complete. Use streaming JSON parsers for large payloads.
216
+
217
+ ### 4. Using ScrollView for Large or Infinite Collections
218
+
219
+ **Why it's a problem:** `ScrollView` renders all children eagerly, regardless of visibility.
220
+ For lists with more than ~20 items, this causes slow initial render, high memory usage, and janky
221
+ scrolling. The problem scales directly with list size.
222
+ **Instead:** Use **FlashList v2** (requires New Architecture — React Native 0.76+ / Expo SDK 53+).
223
+ FlashList v2 is a pure-JS implementation that uses New Architecture's synchronous layout
224
+ measurement for pixel-perfect cell recycling with no `estimatedItemSize` required. For projects
225
+ still on Legacy Architecture, use **FlashList v1**. Never use `FlatList` for performance-sensitive
226
+ lists — FlashList is a drop-in replacement with significantly better throughput.
227
+
228
+ ### 5. Ignoring Safe Areas, Insets, and Keyboard Avoidance
229
+
230
+ **Why it's a problem:** Ignoring safe areas causes content to appear behind notches, home
231
+ indicators, status bars, and the soft keyboard. Expo SDK 53 enables `react-native-edge-to-edge`
232
+ by default for new Android projects, making edge-to-edge the default layout model. Android 16
233
+ (API 36) makes edge-to-edge mandatory for all apps — opting out will not be possible.
234
+ **Instead:** Wrap the app root with `SafeAreaProvider` from `react-native-safe-area-context`.
235
+ Use `SafeAreaView` or `useSafeAreaInsets()` in layouts that need inset-aware padding. Install
236
+ `react-native-edge-to-edge` for correct edge-to-edge Android behavior. Use `KeyboardAvoidingView`
237
+ or `react-native-keyboard-controller` for forms.
238
+
239
+ ### 6. Sprinkling Platform Checks Throughout UI
240
+
241
+ **Why it's a problem:** `Platform.OS === 'ios'` scattered through components creates invisible
242
+ platform-specific code paths, makes components harder to test, and accumulates into unmaintainable
243
+ conditionals over time.
244
+ **Instead:** Extract platform differences into dedicated abstraction layers. Use `Platform.select()`
245
+ for concise conditional values. Create platform-specific file variants (`Component.ios.tsx`,
246
+ `Component.android.tsx`) when the component differs substantially between platforms. Keep
247
+ components themselves platform-agnostic.
248
+
249
+ ### 7. Storing Secrets in AsyncStorage
250
+
251
+ **Why it's a problem:** `AsyncStorage` is unencrypted plain text stored on the device filesystem.
252
+ Auth tokens, API keys, and session credentials stored there are trivially extractable via file
253
+ system access on rooted/jailbroken devices or via ADB on non-production builds.
254
+ **Instead:** Use `expo-secure-store` for Expo managed projects (backed by iOS Keychain Services
255
+ and Android Keystore AES encryption, 2048-byte limit per value on iOS). Use
256
+ `react-native-keychain` for bare React Native projects when biometric auth is needed. Store a
257
+ pointer — not the data itself — if the payload exceeds the size limit.
258
+
259
+ ### 8. Leaking AppState, Navigation, and Native Event Subscriptions
260
+
261
+ **Why it's a problem:** Event listeners and subscriptions registered in `useEffect` without a
262
+ cleanup function leak memory across screen unmounts. On long user sessions, leaked subscriptions
263
+ cause duplicate callbacks, background battery drain, and eventual OOM on low-memory devices.
264
+ **Instead:** Always return a cleanup function from every `useEffect` that registers a subscription.
265
+ For AppState, `NetInfo`, and `Keyboard` listeners, call the returned `remove()` function or
266
+ `subscription.remove()` in the cleanup. For navigation event listeners, call `navigation.addListener`
267
+ and return the returned unsubscribe function.
268
+
269
+ ### 9. Re-rendering Heavy Screens Without Memo Boundaries
270
+
271
+ **Why it's a problem:** A parent state change (e.g., scroll position, timer tick) propagates
272
+ through the component tree and re-renders every child that lacks a memo boundary. On screens with
273
+ complex lists, charts, or media, this causes frame drops.
274
+ **Instead:** Wrap expensive child components in `React.memo()`. Stabilize callback props with
275
+ `useCallback`. Stabilize object props with `useMemo`. Verify with React Native DevTools component
276
+ profiler before applying memos — over-memoization is also a performance cost.
277
+
278
+ ### 10. Running Complex Animations on the JS Thread
279
+
280
+ **Why it's a problem:** `Animated` API (Legacy Architecture) runs animations through a JS→bridge
281
+ →native round-trip per frame. At 60fps this is 16ms — any JS jank drops the animation. Even with
282
+ `useNativeDriver: true`, the animation definition still originates on the JS thread.
283
+ **Instead:** Use **Reanimated 4** (requires New Architecture). Worklets declared with `'worklet'`
284
+ directive run entirely on the UI thread with no JS involvement per frame. Reanimated 4 also adds
285
+ CSS-style animations and transitions as a first-class API. For projects on Legacy Architecture,
286
+ use **Reanimated 3.x** — which supports worklets but requires the bridge for initial setup.
287
+
288
+ ### 11. Mixing Expo-Managed and Bare-Native Assumptions
289
+
290
+ **Why it's a problem:** Expo-managed workflow hides `ios/` and `android/` directories. Bare
291
+ React Native exposes them. Packages that modify native files (e.g., add `AppDelegate.swift`
292
+ entries, modify `AndroidManifest.xml`) require either an Expo Config Plugin (managed) or manual
293
+ native edit (bare). Conflating the two leads to broken builds that work locally but fail on CI.
294
+ **Instead:** FlashList v2 and Reanimated 4 both require New Architecture — verify before adopting.
295
+ In Expo managed, use `app.config.js` plugins only. Run `npx expo prebuild` deliberately when
296
+ switching to bare. Never manually edit `ios/` and `android/` in a managed project.
297
+
298
+ ### 12. Weak Offline, Loading, and Error State Design
299
+
300
+ **Why it's a problem:** Rendering nothing (blank screen) during loading, crashing on API errors,
301
+ and ignoring offline state are the most common RN UX failures. Mobile networks are unreliable;
302
+ offline is not an edge case.
303
+ **Instead:** Always handle three explicit states: `isLoading` → skeleton/shimmer, `isError` →
304
+ error screen with retry action, `isSuccess` → data. Wire TanStack Query's `onlineManager` so
305
+ queries automatically pause when offline and refetch on reconnect. Consider
306
+ `architecture/mobile-architecture/offline-first.md` for apps requiring local-first data.
307
+
308
+ ### 13. Fragile Deep Linking and Push Navigation Wiring
309
+
310
+ **Why it's a problem:** Manually wiring deep links via `Linking.getInitialURL()` + AppState
311
+ listeners is error-prone, misses cold-start edge cases, and breaks when the app is killed.
312
+ Push notifications that navigate to content can land on wrong screens or fail silently.
313
+ **Instead:** Use Expo Router v4's built-in universal links support — file-based routes map
314
+ directly to URLs with zero configuration. For push notification navigation, use
315
+ `expo-notifications` `addNotificationResponseReceivedListener` and resolve the route before the
316
+ app finishes loading to avoid navigation timing bugs.
317
+
318
+ ### 14. Profiling Only in Debug or Remote-Dev Mode
319
+
320
+ **Why it's a problem:** Debug builds with remote JS debugging enabled run JavaScript on the host
321
+ machine VM, not Hermes. Performance characteristics are completely different. Startup times,
322
+ memory usage, and animation smoothness in debug mode do not represent production behaviour.
323
+ **Instead:** Profile on a Release build using Hermes. Use the Hermes profiler for JS startup
324
+ traces. Use Xcode Instruments (iOS) and Android Studio Profiler (Android) for native-layer
325
+ profiling. Use React Native DevTools component profiler on a development build (not debug). Only
326
+ data from release-mode profiles is actionable.
327
+
328
+ ---
329
+
330
+ ## Testing Strategy
331
+
332
+ ### Testing Pyramid
333
+
334
+ | Layer | Framework | Speed | Quantity | Purpose |
335
+ |-------|-----------|-------|----------|---------|
336
+ | Unit | Jest | ~ms | Many | Hooks, store actions, utilities, validators |
337
+ | Component | React Native Testing Library | ~100ms | Moderate | UI rendering, interactions, state transitions |
338
+ | Integration | Jest + MSW | ~seconds | Few | API integration, navigation flows, form submit |
339
+ | E2E | Maestro (default) / Detox | ~minutes | Critical paths only | Full user flows on real devices |
340
+
341
+ ### Frameworks & Tools
342
+
343
+ - **Jest** — default test runner. Use `jest-expo` preset for Expo projects.
344
+ - **React Native Testing Library (RNTL)** — component tests. Prefer `getByRole` and `getByText`
345
+ queries over `testID` — they test behaviour, not implementation.
346
+ - **MSW (Mock Service Worker)** — intercept API calls in integration tests without mocking `fetch`.
347
+ Use `msw/node` server adapter for Jest.
348
+ - **Maestro** — recommended default for E2E. YAML-based, black-box, no app code changes required.
349
+ Test files live in `.maestro/` at project root. New projects, startups, and QA-driven teams
350
+ should default to Maestro.
351
+ - **Detox** — gray-box alternative. Communicates with the app process directly, enabling internal
352
+ state access. Use when you need to assert on React Native internals or your team already has
353
+ significant Detox investment.
354
+
355
+ ### What to Test
356
+
357
+ **Always test:**
358
+ - Custom hooks (business logic, data transformations, derived state).
359
+ - Zustand store actions and selectors.
360
+ - Utility functions and validators (pure functions — trivially testable).
361
+ - Form validation schemas (Zod schemas, `@hookform/resolvers` integration).
362
+ - Navigation guards and auth redirect logic.
363
+ - Error boundary fallback rendering.
364
+
365
+ **Skip or deprioritize:**
366
+ - Rendering of third-party library components (e.g., testing that a `Button` renders text).
367
+ - Implementation details (internal state, private functions).
368
+ - Snapshot tests — they break on trivial UI changes and provide no behavioural signal.
369
+ - Platform-level rendering — covered by the React Native engine tests.
370
+
371
+ ### Mocking Patterns
372
+
373
+ ```ts
374
+ // jest.setup.ts — mock native modules that have no JS implementation in Jest
375
+ jest.mock('@react-native-community/netinfo', () => ({
376
+ addEventListener: jest.fn(() => jest.fn()),
377
+ fetch: jest.fn(() => Promise.resolve({ isConnected: true })),
378
+ }));
379
+
380
+ jest.mock('expo-secure-store', () => ({
381
+ getItemAsync: jest.fn(),
382
+ setItemAsync: jest.fn(),
383
+ deleteItemAsync: jest.fn(),
384
+ }));
385
+
386
+ jest.mock('@react-native-async-storage/async-storage', () =>
387
+ require('@react-native-async-storage/async-storage/jest/async-storage-mock')
388
+ );
389
+ ```
390
+
391
+ Use MSW `http` handlers for API-level integration test mocking — avoids coupling tests to
392
+ `fetch` implementation details.
393
+
394
+ ### Test File Organization
395
+
396
+ ```
397
+ features/
398
+ auth/
399
+ hooks/
400
+ __tests__/
401
+ use-auth.test.ts
402
+ stores/
403
+ __tests__/
404
+ auth-store.test.ts
405
+ components/
406
+ __tests__/
407
+ login-form.test.tsx
408
+ .maestro/
409
+ login_flow.yaml
410
+ checkout_flow.yaml
411
+ jest.config.ts
412
+ jest.setup.ts
413
+ ```
414
+
415
+ Co-locate `__tests__/` directories next to source files. E2E flows in `.maestro/` at project root.
416
+
417
+ ### Coverage Expectations
418
+
419
+ - **Business logic** (hooks, stores, utilities): 80%+ statement coverage.
420
+ - **UI-only components** (no logic): no coverage target — component tests at this layer test
421
+ rendering, not coverage.
422
+ - Enforce thresholds in `jest.config.ts`:
423
+
424
+ ```ts
425
+ // jest.config.ts
426
+ export default {
427
+ preset: 'jest-expo',
428
+ coverageThreshold: {
429
+ './features/**/*.ts': { statements: 80 },
430
+ },
431
+ };
432
+ ```
433
+
434
+ ---
435
+
436
+ ## Performance Considerations
437
+
438
+ ### Common Bottlenecks
439
+
440
+ 1. **JS thread blocking** — synchronous heavy computation, large JSON parsing on the main thread.
441
+ 2. **Large list rendering** — using `ScrollView` or `FlatList` for lists of 50+ items; no cell
442
+ recycling; re-rendering all rows on parent state change.
443
+ 3. **Missing memo boundaries** — heavy screen children re-rendering on unrelated state changes.
444
+ 4. **Unoptimized images** — full-resolution downloads without caching; no decode-size hints.
445
+ 5. **Heavy synchronous module imports** — large dependencies imported at the top-level slow Hermes
446
+ startup; use `require()` inside functions for lazy loading.
447
+ 6. **Bridge churn (Legacy Architecture only)** — high-frequency JS↔native data transfer across
448
+ the async bridge. Eliminated by JSI in New Architecture.
449
+
450
+ ### Profiling Tools
451
+
452
+ | Tool | What It Measures | When to Use |
453
+ |------|-----------------|-------------|
454
+ | React Native DevTools (component profiler) | Component render count and timing | Find unnecessary re-renders |
455
+ | Flipper | Network requests, layout hierarchy, crashes | General inspection during development |
456
+ | Reactotron | State changes, API calls, async storage | Development-time state/API debugging |
457
+ | Hermes profiler | JS startup trace, function execution time | Slow cold start investigation |
458
+ | Xcode Instruments | CPU, memory, energy impact (iOS) | Native-layer profiling on iOS |
459
+ | Android Studio Profiler | CPU, memory, network, battery (Android) | Native-layer profiling on Android |
460
+
461
+ **Always profile on a Release build.** Debug builds with JS remote debugging run on the host VM,
462
+ not Hermes. Startup times and animation smoothness differ dramatically.
463
+
464
+ ### Optimization Patterns
465
+
466
+ - **Hermes AOT compilation** — default since React Native 0.70+. Pre-compiles JS to bytecode at
467
+ build time, reducing startup time and memory usage.
468
+ - **New Architecture JSI** — eliminates bridge JSON serialization for JS↔native calls. Enables
469
+ synchronous native calls. Default in React Native 0.76+ and Expo SDK 53+.
470
+ - **FlashList v2** — cell recycling + adaptive buffer (adjusts based on scroll velocity).
471
+ Requires New Architecture. No `estimatedItemSize` needed. Drop-in `FlatList` replacement with
472
+ significantly lower per-frame render cost for complex items.
473
+ - **Reanimated 4 worklets** — animations run entirely on the UI thread. Declare animation logic
474
+ with `'worklet'` directive; it never touches the JS thread per frame.
475
+ - **`React.memo` + `useCallback`** — wrap list row components in `React.memo`; stabilize callbacks
476
+ passed to rows with `useCallback` to prevent unnecessary row re-renders.
477
+ - **Lazy-load heavy screens** — use `React.lazy()` + `Suspense` or route-level lazy loading in
478
+ Expo Router to defer loading large screen bundles.
479
+ - **`metro.config.js` bundle splitting** — use `createDevServerMiddleware` and `unstable_enablePackageExports`
480
+ for tree-shaking; consider `@expo/metro-config` async bundles for tab-based apps.
481
+ - **Edge-to-edge** — Expo SDK 53 enables `react-native-edge-to-edge` by default for new Android
482
+ projects. Use `react-native-safe-area-context` for inset-aware layouts. Android 16 (API 36)
483
+ makes edge-to-edge mandatory.
484
+
485
+ ### Metrics & Thresholds
486
+
487
+ | Metric | Target |
488
+ |--------|--------|
489
+ | TTI — cold start (mid-range device) | < 2 seconds |
490
+ | List scroll frame drops | < 2 per 100 frames |
491
+ | JS bundle size | < 1 MB (warn above 2 MB) |
492
+ | Crash-free sessions | > 99.5% |
493
+ | Memory (idle, mid-range device) | < 200 MB |
494
+
495
+ ---
496
+
497
+ ## Security Considerations
498
+
499
+ ### Secure Storage
500
+
501
+ Never store secrets, tokens, or credentials in `AsyncStorage` — it is unencrypted plain text on
502
+ the device filesystem.
503
+
504
+ | Library | Workflow | Backing | Limit | Biometric |
505
+ |---------|---------|---------|-------|-----------|
506
+ | `expo-secure-store` | Expo managed | iOS Keychain + Android Keystore AES | 2048 bytes per value (iOS) | Limited |
507
+ | `react-native-keychain` | Bare RN | iOS Keychain + Android CipherStorage | No fixed limit | Full (Face ID, Touch ID, biometric prompt) |
508
+
509
+ - Use **`expo-secure-store`** for Expo managed projects — zero config, maintained by Expo team.
510
+ - Use **`react-native-keychain`** for bare React Native or when biometric-gated keychain access
511
+ is required.
512
+ - The `expo-secure-store` 2048-byte iOS limit is sufficient for JWT access tokens. For larger
513
+ payloads (e.g., encrypted blobs), store a pointer/reference to encrypted file storage instead.
514
+ - For encrypted key-value stores with no size limit, `react-native-mmkv` with encryption enabled
515
+ is an alternative for non-credential data.
516
+
517
+ ### Network Security
518
+
519
+ - **HTTPS only** in production. Never disable certificate validation (`rejectUnauthorized: false`
520
+ must not appear in production code).
521
+ - **Certificate pinning** via `react-native-ssl-pinning` or a custom fetch interceptor that
522
+ validates server certificates against embedded public keys.
523
+ - Always validate server certificate chains; implement a pin rotation strategy with backup pins
524
+ to avoid bricking deployed apps during certificate renewal.
525
+
526
+ ### OTA Updates & Code Integrity
527
+
528
+ - **EAS Update** delivers JS bundle and asset changes OTA in minutes.
529
+ - **Runtime versions** define the JS↔native boundary — bump when any native code changes.
530
+ Deploying a JS bundle to a build with a mismatched runtime version causes crashes.
531
+ - Use EAS Update channels (`production` / `staging`) for staged rollouts. Use
532
+ `--rollout-percentage` for gradual deploys. Use `eas update:edit` to adjust or roll back.
533
+ - **CodePush** is the bare React Native alternative to EAS Update.
534
+
535
+ ### Secrets & Environment Configuration
536
+
537
+ - Never embed API keys in the JS bundle — they are extractable from any Hermes bytecode with
538
+ standard tools.
539
+ - Use `app.config.js` for non-sensitive build-time config.
540
+ - Use EAS environment variables (set via `eas secret:create`) for secrets — they are injected
541
+ at build time, not stored in the repo.
542
+ - Proxy sensitive API calls through a backend API. `expo-constants` surfaces EAS env vars at
543
+ runtime for non-secret config values.
544
+
545
+ ### Code Obfuscation
546
+
547
+ - Hermes bytecode compiles JS to binary format — not human-readable source, but reversible with
548
+ tooling. Not a substitute for not embedding secrets.
549
+ - For stronger protection: enable `metro-minify-terser` with identifier mangling enabled.
550
+ - `react-native-obfuscate` applies source-level obfuscation before the Metro bundler runs.
551
+ - Upload source maps to Sentry for symbolicated crash reports despite obfuscation.
552
+
553
+ ### Input Validation
554
+
555
+ - Use **Zod** at every API response boundary — parse the shape before using the data.
556
+ - Validate deep link params before acting on them — they arrive from outside the app.
557
+ - Use React Hook Form + Zod at form boundaries — never trust unvalidated form data.
558
+ - Use parameterized queries for local SQLite — never concatenate user input into SQL strings.
559
+
560
+ ---
561
+
562
+ ## Integration Patterns
563
+
564
+ ### REST API Integration
565
+
566
+ Use `fetch` (built-in) or `axios` as the HTTP client. Wrap all async server state in
567
+ TanStack Query v5.
568
+
569
+ **Critical: wire `onlineManager` at app startup** (see State Management section). Without this,
570
+ TanStack Query will not respond to network connectivity changes on React Native because it cannot
571
+ detect `navigator.onLine`.
572
+
573
+ ```ts
574
+ // services/query-client.ts
575
+ import { QueryClient } from '@tanstack/react-query';
576
+
577
+ export const queryClient = new QueryClient({
578
+ defaultOptions: {
579
+ queries: {
580
+ staleTime: 1000 * 60 * 5, // 5 minutes
581
+ retry: 2,
582
+ refetchOnWindowFocus: true, // works via focusManager wiring
583
+ },
584
+ },
585
+ });
586
+ ```
587
+
588
+ For paginated lists, use `useInfiniteQuery` with `maxPages` to cap memory usage on mobile:
589
+
590
+ ```ts
591
+ useInfiniteQuery({
592
+ queryKey: ['feed'],
593
+ queryFn: ({ pageParam }) => fetchFeed(pageParam),
594
+ getNextPageParam: (last) => last.nextCursor,
595
+ maxPages: 5, // keep at most 5 pages in memory
596
+ initialPageParam: null,
597
+ });
598
+ ```
599
+
600
+ ### Forms & Validation
601
+
602
+ **React Hook Form v7** + **Zod v3** + **`@hookform/resolvers/zod`** is the standard stack.
603
+ Use `Controller` for all React Native inputs — RN inputs are uncontrolled by default and require
604
+ the `Controller` bridge to integrate with RHF's ref-based model.
605
+
606
+ ```ts
607
+ const schema = z.object({
608
+ email: z.string().email('Enter a valid email'),
609
+ password: z.string().min(8, 'Minimum 8 characters'),
610
+ });
611
+ ```
612
+
613
+ Trigger validation `onBlur` for forms with many fields to avoid re-render storms on every
614
+ keystroke. Use `mode: 'onChange'` only when immediate feedback is required (e.g., password
615
+ strength indicator).
616
+
617
+ ### Native Modules & Expo Modules API
618
+
619
+ Use the **Expo Modules API** (`expo-modules-core`) to create custom native modules. Define the
620
+ module using the `ExpoModule` class in Swift (iOS) and Kotlin (Android). Prefer Expo packages
621
+ over community packages when an equivalent exists — they are guaranteed to support New Architecture.
622
+
623
+ Check `reactnative.directory` for the `new-arch: true` badge before adopting any community
624
+ package. A package without New Architecture support will block your upgrade path.
625
+
626
+ ### Local Persistence
627
+
628
+ | Library | Backing | Use Case | Encrypted | Notes |
629
+ |---------|---------|----------|-----------|-------|
630
+ | `expo-sqlite` v15 | SQLite | Relational data, complex queries | Yes (via extension) | Use `SQLiteProvider` + `useSQLiteContext`; WAL mode default; do NOT use `openDatabase` |
631
+ | `react-native-mmkv` | Key-value (memory-mapped) | Fast reads, store persistence | Yes | Optimal for Zustand persist middleware |
632
+ | `AsyncStorage` | Key-value (filesystem) | Non-sensitive only | No | Not for secrets or tokens |
633
+
634
+ `expo-sqlite` v15 API — always use `SQLiteProvider` and `useSQLiteContext`, not the deprecated
635
+ `openDatabase`:
636
+
637
+ ```tsx
638
+ // Correct v15 usage
639
+ import { SQLiteProvider, useSQLiteContext } from 'expo-sqlite';
640
+
641
+ export function App() {
642
+ return (
643
+ <SQLiteProvider databaseName="app.db">
644
+ <FeedScreen />
645
+ </SQLiteProvider>
646
+ );
647
+ }
648
+
649
+ function FeedScreen() {
650
+ const db = useSQLiteContext();
651
+ // db is now available synchronously — WAL mode enabled by default
652
+ }
653
+ ```
654
+
655
+ ### Push Notifications, Deep Links & Background Work
656
+
657
+ - **Push notifications** — `expo-notifications` for token registration, receiving, and display.
658
+ Register the push token with your backend after user permission is granted.
659
+ - **Deep links** — Expo Router v4 handles universal links and custom scheme deep links natively
660
+ via file-based routing. No additional `Linking` wiring required for in-app routes.
661
+ - **Background work** — `expo-background-fetch` + `expo-task-manager` for periodic background
662
+ tasks (data sync, cache refresh). Background time is OS-limited; design tasks to complete in
663
+ under 30 seconds.
664
+
665
+ ---
666
+
667
+ ## DevOps & Deployment
668
+
669
+ ### Environments & Configuration
670
+
671
+ ```js
672
+ // app.config.js — environment-aware build config
673
+ const IS_PROD = process.env.APP_VARIANT === 'production';
674
+
675
+ export default {
676
+ name: IS_PROD ? 'MyApp' : 'MyApp (Dev)',
677
+ ios: { bundleIdentifier: IS_PROD ? 'com.example.myapp' : 'com.example.myapp.dev' },
678
+ android: { package: IS_PROD ? 'com.example.myapp' : 'com.example.myapp.dev' },
679
+ };
680
+ ```
681
+
682
+ ```json
683
+ // eas.json — build profiles
684
+ {
685
+ "build": {
686
+ "production": {
687
+ "channel": "production",
688
+ "env": { "APP_VARIANT": "production" }
689
+ },
690
+ "preview": {
691
+ "channel": "preview",
692
+ "distribution": "internal",
693
+ "env": { "APP_VARIANT": "preview" }
694
+ },
695
+ "development": {
696
+ "developmentClient": true,
697
+ "distribution": "internal"
698
+ }
699
+ }
700
+ }
701
+ ```
702
+
703
+ Set secrets via `eas secret:create --scope project --name API_SECRET --value "..."`. Access at
704
+ runtime via `expo-constants` `expoConfig.extra`.
705
+
706
+ ### CI/CD with EAS
707
+
708
+ EAS Workflows (YAML in `.eas/workflows/`) orchestrate the full pipeline:
709
+
710
+ ```yaml
711
+ # .eas/workflows/production.yml
712
+ on:
713
+ push:
714
+ branches: [main]
715
+ jobs:
716
+ build-ios:
717
+ type: build
718
+ params:
719
+ platform: ios
720
+ profile: production
721
+ build-android:
722
+ type: build
723
+ params:
724
+ platform: android
725
+ profile: production
726
+ submit:
727
+ type: submit
728
+ needs: [build-ios, build-android]
729
+ params:
730
+ profile: production
731
+ ```
732
+
733
+ - **EAS Build** — cloud builds, manages signing credentials, produces `.ipa` and `.apk/.aab`.
734
+ - **EAS Submit** — uploads to App Store Connect and Google Play. Use `--auto-submit` flag on
735
+ `eas build` to trigger submit automatically post-build.
736
+ - **EAS Update** — OTA JS + asset updates. Propagates to users in minutes. Run
737
+ `eas update --channel production --message "Fix login crash"` for emergency patches.
738
+ - Parallel iOS + Android build jobs cut wall-clock CI time roughly in half.
739
+
740
+ ### Expo Prebuild / Bare React Native Escape Hatch
741
+
742
+ Run `npx expo prebuild` to generate `ios/` and `android/` directories from the managed project.
743
+ Use prebuild when:
744
+ - A required native library has no Expo Config Plugin.
745
+ - CI requires native build customization beyond what Config Plugins support.
746
+ - Migrating to bare workflow deliberately.
747
+
748
+ **Warning:** prebuild output is not checked into git — regenerate on every native dependency
749
+ change. Committing `ios/` and `android/` is valid only in fully bare projects.
750
+
751
+ ### Crash Reporting & Observability
752
+
753
+ - **Sentry** (`@sentry/react-native` + `@sentry/expo`) — crash reporting, performance traces,
754
+ symbolicated stack traces via source maps. Wire `Sentry.init()` as the first statement before
755
+ `registerRootComponent()`.
756
+ - **Firebase Crashlytics** — alternative for Firebase-first stacks.
757
+ - Wire `Sentry.setUser()` after auth to correlate crashes with user accounts.
758
+
759
+ ### Store Release Flow
760
+
761
+ - **iOS:** EAS Build → TestFlight (internal test) → External Testing → App Store Review → Release.
762
+ - **Android:** EAS Build → Internal Testing track → Closed Testing → Open Testing → Production.
763
+ - **EAS Submit** automates upload to both stores.
764
+ - Use `autoIncrement: true` in `eas.json` to auto-bump build numbers on each build.
765
+ - OTA updates via EAS Update bypass App Store review for JS-only changes.
766
+
767
+ ---
768
+
769
+ ## Decision Trees
770
+
771
+ ### Expo Managed vs Expo Prebuild vs Bare React Native
772
+
773
+ ```
774
+ START: Does the app require a native library without an Expo Config Plugin?
775
+ |
776
+ +-- Yes
777
+ | |
778
+ | +-- Is the library available as a bare-only package?
779
+ | | --> Expo Prebuild (npx expo prebuild — generates ios/ + android/,
780
+ | | use Config Plugins for everything else)
781
+ | |
782
+ | +-- Can you write an Expo Config Plugin or use a community one?
783
+ | --> Stay Expo Managed with the Config Plugin
784
+ |
785
+ +-- No: Does the app need full native project control (custom Podfile, Gradle scripts,
786
+ | CI native customization, proprietary SDKs with no RN wrapper)?
787
+ | |
788
+ | +-- Yes --> Bare React Native (eject fully — own ios/ and android/)
789
+ | |
790
+ | +-- No --> Expo Managed Workflow (default — least maintenance overhead,
791
+ | EAS Build + EAS Update, no native directories to maintain)
792
+ ```
793
+
794
+ ### Which Navigation Approach?
795
+
796
+ ```
797
+ START: Is the project on Expo SDK 52+ (Expo Router v4 available)?
798
+ |
799
+ +-- Yes
800
+ | |
801
+ | +-- Is file-based routing acceptable for the app's navigation structure?
802
+ | | |
803
+ | | +-- Yes --> Expo Router v4 (typed routes, Guarded Groups, universal links built-in)
804
+ | | |
805
+ | | +-- No (e.g., programmatic dynamic routes, complex nested stacks not
806
+ | | expressible as files)
807
+ | | --> React Navigation v7 (imperative, maximum flexibility)
808
+ | |
809
+ | +-- Does the project already use React Navigation with heavy investment?
810
+ | --> React Navigation v7 (migration cost not justified)
811
+ |
812
+ +-- No (legacy project, bare RN, older SDK)
813
+ --> React Navigation v7
814
+ ```
815
+
816
+ ### Which State Management Tier?
817
+
818
+ ```
819
+ START: Where does the data originate?
820
+ |
821
+ +-- From a server / API (fetched async, needs caching, background sync)
822
+ | --> TanStack Query v5
823
+ | useQuery for reads, useMutation for writes
824
+ | Invalidate query cache on successful mutations
825
+ |
826
+ +-- Client-only: shared across multiple screens or persisted across sessions
827
+ | --> Zustand v5
828
+ | useShallow for all object selectors (mandatory in v5)
829
+ | Persist slice with zustand/middleware persist + react-native-mmkv
830
+ |
831
+ +-- Component-local: ephemeral, not shared beyond this component
832
+ --> useState / useReducer
833
+ No store, no context, no query — keep it local
834
+ ```
835
+
836
+ ### Which Storage Layer?
837
+
838
+ ```
839
+ START: Is the data a secret, token, or credential?
840
+ |
841
+ +-- Yes
842
+ | |
843
+ | +-- Expo managed project --> expo-secure-store (Keychain/Keystore, 2048-byte iOS limit)
844
+ | +-- Bare RN / need biometric --> react-native-keychain
845
+ |
846
+ +-- No: Is the data relational or requires complex queries / joins?
847
+ | |
848
+ | +-- Yes --> expo-sqlite v15 (SQLiteProvider + useSQLiteContext, WAL mode default)
849
+ | | Do NOT use openDatabase API
850
+ | |
851
+ | +-- No: High-frequency key-value reads / writes (e.g., store persistence, settings)?
852
+ | |
853
+ | +-- Yes --> react-native-mmkv (memory-mapped, synchronous, encrypted option)
854
+ | |
855
+ | +-- No (infrequent, non-sensitive key-value)
856
+ | --> AsyncStorage (not for secrets — plain text on filesystem)
857
+ ```
858
+
859
+ ---
860
+
861
+ ## Code Examples
862
+
863
+ ### 1. Expo Router App Shell with Guarded Groups
864
+
865
+ The root layout wires all providers and uses Expo Router v4 Guarded Groups for auth — no
866
+ `useEffect` redirects needed.
867
+
868
+ ```tsx
869
+ // app/_layout.tsx
870
+ import { Slot } from 'expo-router';
871
+ import { QueryClientProvider } from '@tanstack/react-query';
872
+ import { GestureHandlerRootView } from 'react-native-gesture-handler';
873
+ import { SafeAreaProvider } from 'react-native-safe-area-context';
874
+ import { AppState, AppStateStatus } from 'react-native';
875
+ import NetInfo from '@react-native-community/netinfo';
876
+ import { onlineManager, focusManager } from '@tanstack/react-query';
877
+ import { queryClient } from '@/services/query-client';
878
+
879
+ // Wire onlineManager once — TanStack Query cannot use navigator.onLine on RN
880
+ onlineManager.setEventListener((setOnline) =>
881
+ NetInfo.addEventListener((state) => setOnline(!!state.isConnected))
882
+ );
883
+
884
+ // Wire focusManager for foreground refetch
885
+ AppState.addEventListener('change', (status: AppStateStatus) =>
886
+ focusManager.setFocused(status === 'active')
887
+ );
888
+
889
+ export default function RootLayout() {
890
+ return (
891
+ // GestureHandlerRootView must be outermost — it owns the gesture responder context
892
+ <GestureHandlerRootView style={{ flex: 1 }}>
893
+ <SafeAreaProvider>
894
+ <QueryClientProvider client={queryClient}>
895
+ <Slot />
896
+ </QueryClientProvider>
897
+ </SafeAreaProvider>
898
+ </GestureHandlerRootView>
899
+ );
900
+ }
901
+ ```
902
+
903
+ ```tsx
904
+ // app/(app)/_layout.tsx — Guarded Group: authenticated routes only
905
+ import { Redirect, Stack } from 'expo-router';
906
+ import { useAuthStore } from '@/stores/auth-store';
907
+
908
+ export const unstable_settings = {
909
+ // Anchor route: unauthenticated users land here
910
+ anchor: '/(auth)/login',
911
+ };
912
+
913
+ export function guard(): boolean {
914
+ // guard() runs outside render — use getState(), not a hook
915
+ return useAuthStore.getState().isAuthenticated;
916
+ }
917
+
918
+ export default function AppLayout() {
919
+ return <Stack />;
920
+ }
921
+ ```
922
+
923
+ ### 2. TanStack Query + Zustand Screen Pattern
924
+
925
+ A screen demonstrating all three state tiers in one component.
926
+
927
+ ```tsx
928
+ // features/profile/screens/profile-screen.tsx
929
+ import { View, Text, Modal, Pressable } from 'react-native';
930
+ import { useQuery } from '@tanstack/react-query';
931
+ import { useState } from 'react';
932
+ import { useShallow } from 'zustand/react/shallow';
933
+ import { useAuthStore } from '@/stores/auth-store';
934
+ import { fetchUserProfile } from '@/services/user-service';
935
+ import type { UserProfile } from '@/types/user';
936
+
937
+ export function ProfileScreen() {
938
+ // Tier 1 — server state via TanStack Query v5
939
+ // Query key includes userId so cache is scoped per user
940
+ const { userId, token } = useAuthStore(
941
+ useShallow((s) => ({ userId: s.userId, token: s.token })) // useShallow mandatory in v5
942
+ );
943
+
944
+ const { data: profile, isLoading, isError } = useQuery<UserProfile>({
945
+ queryKey: ['profile', userId],
946
+ queryFn: () => fetchUserProfile(userId, token),
947
+ enabled: !!userId, // don't run without a user
948
+ });
949
+
950
+ // Tier 3 — component-local ephemeral state
951
+ const [isEditModalVisible, setEditModalVisible] = useState(false);
952
+
953
+ if (isLoading) return <Text>Loading…</Text>;
954
+ if (isError || !profile) return <Text>Failed to load profile.</Text>;
955
+
956
+ return (
957
+ <View>
958
+ <Text>{profile.displayName}</Text>
959
+ <Pressable onPress={() => setEditModalVisible(true)}>
960
+ <Text>Edit</Text>
961
+ </Pressable>
962
+ <Modal visible={isEditModalVisible} onRequestClose={() => setEditModalVisible(false)}>
963
+ {/* Edit form here */}
964
+ </Modal>
965
+ </View>
966
+ );
967
+ }
968
+ ```
969
+
970
+ ### 3. React Hook Form + Zod Native Form
971
+
972
+ `Controller` is required for React Native inputs — RN inputs are uncontrolled and must be
973
+ bridged via `Controller` for RHF's ref model.
974
+
975
+ ```tsx
976
+ // features/auth/components/login-form.tsx
977
+ import { View, TextInput, Text, Pressable } from 'react-native';
978
+ import { useForm, Controller } from 'react-hook-form';
979
+ import { zodResolver } from '@hookform/resolvers/zod';
980
+ import { z } from 'zod';
981
+
982
+ const loginSchema = z.object({
983
+ email: z.string().email('Enter a valid email address'),
984
+ password: z.string().min(8, 'Password must be at least 8 characters'),
985
+ });
986
+
987
+ type LoginFormValues = z.infer<typeof loginSchema>;
988
+
989
+ interface LoginFormProps {
990
+ onSubmit: (values: LoginFormValues) => Promise<void>;
991
+ }
992
+
993
+ export function LoginForm({ onSubmit }: LoginFormProps) {
994
+ const {
995
+ control,
996
+ handleSubmit,
997
+ formState: { errors, isSubmitting },
998
+ } = useForm<LoginFormValues>({
999
+ resolver: zodResolver(loginSchema),
1000
+ mode: 'onBlur', // validate on blur — avoids re-render storm on every keystroke
1001
+ });
1002
+
1003
+ return (
1004
+ <View>
1005
+ <Controller
1006
+ control={control}
1007
+ name="email"
1008
+ render={({ field: { onChange, onBlur, value } }) => (
1009
+ <TextInput
1010
+ onChangeText={onChange}
1011
+ onBlur={onBlur}
1012
+ value={value}
1013
+ autoCapitalize="none"
1014
+ keyboardType="email-address"
1015
+ placeholder="Email"
1016
+ />
1017
+ )}
1018
+ />
1019
+ {errors.email && <Text>{errors.email.message}</Text>}
1020
+
1021
+ <Controller
1022
+ control={control}
1023
+ name="password"
1024
+ render={({ field: { onChange, onBlur, value } }) => (
1025
+ <TextInput
1026
+ onChangeText={onChange}
1027
+ onBlur={onBlur}
1028
+ value={value}
1029
+ secureTextEntry
1030
+ placeholder="Password"
1031
+ />
1032
+ )}
1033
+ />
1034
+ {errors.password && <Text>{errors.password.message}</Text>}
1035
+
1036
+ <Pressable onPress={handleSubmit(onSubmit)} disabled={isSubmitting}>
1037
+ <Text>{isSubmitting ? 'Signing in…' : 'Sign In'}</Text>
1038
+ </Pressable>
1039
+ </View>
1040
+ );
1041
+ }
1042
+ ```
1043
+
1044
+ ### 4. FlashList Memoized Row Pattern
1045
+
1046
+ FlashList v2 requires New Architecture (React Native 0.76+ / Expo SDK 53+). No
1047
+ `estimatedItemSize` in v2 — removed entirely. Use FlashList v1 on Legacy Architecture.
1048
+
1049
+ ```tsx
1050
+ // features/feed/components/feed-list.tsx
1051
+ import { useCallback, memo } from 'react';
1052
+ import { View, Text, Pressable } from 'react-native';
1053
+ import { FlashList, ListRenderItem } from '@shopify/flash-list';
1054
+
1055
+ interface FeedItem {
1056
+ id: string;
1057
+ title: string;
1058
+ type: 'post' | 'ad'; // heterogeneous list types
1059
+ }
1060
+
1061
+ interface RowProps {
1062
+ item: FeedItem;
1063
+ onPress: (id: string) => void;
1064
+ }
1065
+
1066
+ // Memoize the row: prevents re-render when parent state changes but item is unchanged
1067
+ const FeedRow = memo(function FeedRow({ item, onPress }: RowProps) {
1068
+ return (
1069
+ <Pressable onPress={() => onPress(item.id)}>
1070
+ <Text>{item.title}</Text>
1071
+ </Pressable>
1072
+ );
1073
+ });
1074
+
1075
+ interface FeedListProps {
1076
+ items: FeedItem[];
1077
+ onItemPress: (id: string) => void;
1078
+ }
1079
+
1080
+ export function FeedList({ items, onItemPress }: FeedListProps) {
1081
+ // Stabilize callback — prevents FeedRow memo from being defeated on parent render
1082
+ const handlePress = useCallback((id: string) => onItemPress(id), [onItemPress]);
1083
+
1084
+ // Typed renderItem — ListRenderItem<FeedItem> ensures item type safety
1085
+ const renderItem: ListRenderItem<FeedItem> = useCallback(
1086
+ ({ item }) => <FeedRow item={item} onPress={handlePress} />,
1087
+ [handlePress]
1088
+ );
1089
+
1090
+ return (
1091
+ <FlashList
1092
+ data={items}
1093
+ renderItem={renderItem}
1094
+ // getItemType enables per-type recycling pools — items with different types
1095
+ // never share a recycled cell, preventing layout corruption
1096
+ getItemType={(item) => item.type}
1097
+ // v2: estimatedItemSize is gone — no estimates needed
1098
+ // Cell recycling is pixel-perfect via New Architecture synchronous layout
1099
+ keyExtractor={(item) => item.id}
1100
+ />
1101
+ );
1102
+ }
1103
+ ```
1104
+
1105
+ ### 5. Secure Token Storage Wrapper
1106
+
1107
+ Abstracts `expo-secure-store` with typed functions. Never use `AsyncStorage` for tokens.
1108
+ The 2048-byte iOS Keychain limit is sufficient for JWT access tokens; store a reference
1109
+ pointer for larger payloads.
1110
+
1111
+ ```ts
1112
+ // services/secure-storage.ts
1113
+ import * as SecureStore from 'expo-secure-store';
1114
+
1115
+ const TOKEN_KEY = 'auth_token';
1116
+ const REFRESH_TOKEN_KEY = 'refresh_token';
1117
+
1118
+ // expo-secure-store: iOS Keychain + Android Keystore AES — encrypted at rest
1119
+ // Limit: 2048 bytes per value on iOS (JWT access tokens fit well within this)
1120
+ // For bare RN projects requiring biometric auth, swap to react-native-keychain
1121
+
1122
+ export async function getToken(): Promise<string | null> {
1123
+ return SecureStore.getItemAsync(TOKEN_KEY);
1124
+ }
1125
+
1126
+ export async function setToken(token: string): Promise<void> {
1127
+ // Validate before storing — never persist a malformed token
1128
+ if (!token || token.length === 0) {
1129
+ throw new Error('Cannot store empty token');
1130
+ }
1131
+ await SecureStore.setItemAsync(TOKEN_KEY, token);
1132
+ }
1133
+
1134
+ export async function removeToken(): Promise<void> {
1135
+ await SecureStore.deleteItemAsync(TOKEN_KEY);
1136
+ }
1137
+
1138
+ export async function getRefreshToken(): Promise<string | null> {
1139
+ return SecureStore.getItemAsync(REFRESH_TOKEN_KEY);
1140
+ }
1141
+
1142
+ export async function setRefreshToken(token: string): Promise<void> {
1143
+ if (!token || token.length === 0) {
1144
+ throw new Error('Cannot store empty refresh token');
1145
+ }
1146
+ await SecureStore.setItemAsync(REFRESH_TOKEN_KEY, token);
1147
+ }
1148
+
1149
+ export async function clearAllTokens(): Promise<void> {
1150
+ // Clear both tokens atomically on logout
1151
+ await Promise.all([
1152
+ SecureStore.deleteItemAsync(TOKEN_KEY),
1153
+ SecureStore.deleteItemAsync(REFRESH_TOKEN_KEY),
1154
+ ]);
1155
+ }
1156
+ ```
1157
+
1158
+ ---
1159
+
1160
+ *Researched: 2026-03-12 | Sources: [React Native docs](https://reactnative.dev/docs/getting-started), [RN New Architecture](https://reactnative.dev/architecture/landing-page), [RN 0.79 release blog](https://reactnative.dev/blog/2025/04/08/react-native-0.79), [Expo SDK 53 changelog](https://expo.dev/changelog/sdk-53), [Expo Router docs](https://docs.expo.dev/router/introduction/), [Expo Router typed routes](https://docs.expo.dev/router/reference/typed-routes/), [TanStack Query v5 React Native](https://tanstack.com/query/v5/docs/framework/react/react-native), [TanStack Query v5 migration](https://tanstack.com/query/latest/docs/framework/react/guides/migrating-to-v5), [Zustand GitHub](https://github.com/pmndrs/zustand), [FlashList v2 Shopify blog](https://shopify.engineering/flashlist-v2), [FlashList docs](https://shopify.github.io/flash-list/), [Reanimated 4 migration guide](https://docs.swmansion.com/react-native-reanimated/docs/guides/migration-from-3.x/), [Reanimated 4 stable release](https://blog.swmansion.com/reanimated-4-stable-release-the-future-of-react-native-animations-ba68210c3713), [EAS Build docs](https://docs.expo.dev/build/introduction/), [EAS Update docs](https://docs.expo.dev/eas-update/introduction/), [EAS runtime versions](https://docs.expo.dev/eas-update/runtime-versions/), [EAS Workflows](https://docs.expo.dev/eas/workflows/get-started/), [EAS OTA playbook](https://expo.dev/blog/the-production-playbook-for-ota-updates), [Maestro best RN testing frameworks](https://maestro.dev/insights/best-react-native-testing-frameworks), [Detox vs Maestro](https://www.getpanto.ai/blog/detox-vs-maestro), [QA Wolf 2025 E2E frameworks](https://www.qawolf.com/blog/the-best-mobile-e2e-testing-frameworks-in-2025-strengths-tradeoffs-and-use-cases), [AddJam Maestro experience 2026](https://addjam.com/blog/2026-02-18/our-experience-adding-e2e-testing-react-native-maestro/), [expo-secure-store docs](https://docs.expo.dev/versions/latest/sdk/securestore/), [RN security docs](https://reactnative.dev/docs/security), [React Native Testing Library](https://callstack.github.io/react-native-testing-library/), See also: [mobile-app-architecture.md](../architecture/mobile-architecture/mobile-app-architecture.md), [mobile-antipatterns.md](../antipatterns/frontend/mobile-antipatterns.md), [testing-mobile.md](../quality/testing-mobile.md), [security/mobile/](../security/mobile/)*