Skip to content

Best Practices

The best practices skill contains 46 rules sourced from vercel-labs/agent-skills (MIT License) plus rules discovered through plugin testing. Each rule has full incorrect/correct code examples in reference files.

Activated during Phase 4 (Architecture) to constrain design decisions and during Phase 6 (Review) Pass 4 for code quality checks. Also loaded when reviewing React Native code, optimizing list performance, implementing animations, or auditing UI components.

These are checked regardless of review scope.

RN-1.1: Never use && with potentially falsy values

Section titled “RN-1.1: Never use && with potentially falsy values”

{count && <Badge />} renders “0” as text when count is 0, crashing React Native.

Use {count > 0 && <Badge />} or {count ? <Badge /> : null} instead.

A string as a direct child of <View> causes a runtime crash. Always wrap in <Text>.

RN-16.1: Don’t define components inside components

Section titled “RN-16.1: Don’t define components inside components”

Creates a new type every render, causing React to remount (destroying state, views, animations). Symptoms: TextInput loses focus, animations restart, scroll resets.

RN-16.3: Use Promise.all() for independent async operations

Section titled “RN-16.3: Use Promise.all() for independent async operations”

Sequential await on independent calls wastes 2-10x time.

PriorityCategoryIDsKey Patterns
1Core Rendering1.1, 1.2&& conditionals, bare strings in Views
2List Performance2.1-2.8FlatList, renderItem, inline objects, virtualization
3Animation3.1-3.3Reanimated, transform/opacity only, GestureDetector
4Scroll4.1Never store scroll position in useState
5Navigation5.1Only native navigators (native-stack, native tabs)
6React State6.1-6.3Minimize state, derive values, dispatch updaters
7State Architecture7.1State = ground truth, visuals = derived
8React Compiler8.1-8.2Destructure functions early, .get()/.set() for shared values
9UI9.1-9.9expo-image, Pressable, native modals, native menus, onLayout
10Design System10.1Compound components over polymorphic children
11Monorepo11.1-11.2Native deps in app dir, single dep versions
12Third-Party12.1Import from design system folder
13JavaScript13.1Hoist Intl formatter creation
14Fonts14.1Load fonts natively at build time
15Queries/Animations15.1-15.3Reactive query hooks, no Reanimated layout anims in lists, theme hooks inside items
16Re-renders/Async16.1-16.7No inline components, lazy state init, Promise.all, Set/Map lookups
RuleConstraint
2.1-2.8All scrollable data uses FlashList/LegendList. List items receive primitives, not objects. Callbacks hoisted to root. No queries or heavy hooks inside items. Compressed images. Item types for heterogeneous lists.
3.1Only animate transform and opacity (GPU-accelerated). Never animate width, height, margin, padding.
4.1Never store scroll position in useState. Use Reanimated shared values or refs.
5.1Only native navigators: native-stack, native bottom tabs. No JS-based stack/tab navigators.
9.5Use expo-image for all images (not Image from react-native).
9.7Use native menus (zeego) for dropdowns instead of JS pickers.
9.8Use native modals over JS bottom sheets.
15.1Use reactive query hooks, not imperative queryClient.getQueryData cache reads.

The architect reads CRITICAL and HIGH rules relevant to the feature and applies constraints to the blueprint.

  1. Always check CRITICAL rules 1.1, 1.2, 16.1
  2. Scan code for patterns matching HIGH/MEDIUM/LOW categories
  3. Read the full reference file for each matched rule
  4. Report findings with citation: [RN-2.1] Rule Name -- IMPACT (confidence N)