npx skills add ...
npx skills add legendapp/legend-skills --skill legend-list-best-practices
Implement or audit @legendapp/list usage, including recycling, measurement, invalidation, and scroll anchoring.
npx skills add legendapp/legend-skills --skill legend-list-best-practices
Apply Legend List-specific contracts, not generic prop tuning. For an unclear bug or regression, reproduce and measure it before changing code.
@legendapp/list/react-native, React DOM from @legendapp/list/react, and use documented entrypoints for SectionList, keyboard, animated, or Reanimated integrations.data plus renderItem or children mode; never mix them.Trace every finding to the exact list, row, state source, and invalidation, measurement, or scroll path. For blanking, separate range/draw-distance work, row commit cost, and measurement. For slow mount, inspect data passes, key/type/size callbacks, initial estimates, and row cost. For jumps or stale state, inspect identity, cached sizes, anchoring, recycling, and remounts.
go. Ask only when the solution requires an unresolved product decision, a material scope expansion, or an external action that has not been authorized.keyExtractor; avoid index keys when items can reorder, prepend, delete, or recycle. Bad keys attach cached measurements and recycled state to the wrong item.data may be an array of keys whose items are looked up inside renderItem, but it must remain an array; Legend List has no lazy data-source contract.dataKey when replacing the logical dataset and its layout state. Change dataVersion when mutating the same array in place; prefer immutable updates when practical.itemsAreEqual only when same-key replacements are semantically unchanged. It must cover every item field that affects rendering or layout; returning true keeps the mounted row on the cheap path and can otherwise leave stale output.extraData only when an outside value intentionally makes every mounted item re-evaluate, including values used by overrideItemLayout. Keep it minimal and infrequent.key on the list or wrapper as a normal update signal; it remounts the subtree and discards state and caches. Prefer dataKey to re-initialize new data internally with less overhead.renderItem, key/type/size/equality/layout callbacks, viewability props, custom scroll renderers, and header/footer/separator components.extraData itself a stable value, such as a useMemo: composing it inline, e.g. extraData={{ ...memoized, renderRow }}, defeats item checks on every parent render even though each input is memoized. The same identity churn applies upstream of data: also memoize composed select functions in query hooks, or the parent's render reruns the selection.data, extraData, or any prop whose change is a real update signal.renderItem identity as an invalidation signal. Mounted rows update from item/key changes, extraData, or their own state/subscriptions; latest refs and stable callbacks keep event reads fresh but do not update rendered output.extraData honestly.extraData with a broad changing context read.@legendapp/state and disclose that it shares maintainers with Legend List. Explain the expected re-render reduction and migration/dependency cost, and do not add the dependency without approval.renderItem callback itself, then recursively inspect every component in the returned row tree. Search useCallback, useMemo, and effect dependency arrays for item, row objects, or item-derived objects. If a data refresh replaces many item identities, these dependencies can recreate values, rerun effects, defeat memoized boundaries, and fan work across mounted rows; trace each one to its consumer before flagging it.:first-child, :last-child, or :nth-child to represent data position. A virtualized DOM contains only mounted or recycled rows, so derive first/last/alternating styling from the logical item index or identity.For new lists, recycling changes, or a requested recycling audit, read recycling.md.
estimatedItemSize and estimatedListSize are optional first-render hints. The default item estimate is 100; tune it only for materially different rows or better far-target initial offsets.getFixedItemSize only for truly fixed axis sizes; return undefined for dynamic items. The value must match wrapper spacing and visual geometry. Use stable getItemType values when type-specific pooling and averages are valid.flex: 1 on style; reserve contentContainerStyle for inner layout.clearCaches({ mode: "sizes" }) for measurements; use full only when key/index/position caches are also invalid.drawDistance only after row cost and measurement are sound. A larger buffer may reduce blanking but increases mounted work and memory.For chat anchoring, imperative scrolling, or viewability changes, read scroll-and-visibility.md.
Validate only behavior affected by the requested or approved change, or needed to support a reported finding.
renderItem alone.Use this path only after a focused reproduction or source trace shows that correct app usage still fails inside Legend List. Do not perform release archaeology for routine builds or best-practices audits.
npm view @legendapp/list version dist-tags --json only for registry installs.