Overview
All three stack types share the same animation API, but each has specific trade-offs. Understanding these limitations helps you choose the right stack for your use case.Stack Type Comparison
| Stack | Best For |
|---|---|
| Blank Stack | Most apps. Full control, all features. |
| Native Stack | When you need native screen primitives. |
| Component Stack | Embedded flows, isolated from React Navigation. (Experimental) |
Blank Stack
This is the recommended stack type for most applications.
How It Works
Usesreact-native-screens for native screen containers, with animations powered by Reanimated worklets running on the UI thread (not the JS thread).
Advantages
- Full feature support – All gestures, snap points, shared elements work seamlessly
- Native performance – Animations run on UI thread via Reanimated
- Reliable touch handling – No modal-related touch delays
- React Navigation integration – Full compatibility with React Navigation ecosystem
Limitations
- Slightly less “native” – Uses custom animations instead of platform defaults
- Bundle size – Includes Reanimated (though most RN apps already use it)
When to Use
- You need custom animations, gestures, or shared elements
- You want reliable touch handling and gesture coordination
- You’re building any app that needs more than basic push/pop transitions
Native Stack
How It Works
Extends@react-navigation/native-stack and uses transparent modal presentation to intercept transitions. Requires enableTransitions: true on screens with custom animations.
Advantages
- Native screen primitives – Uses platform-native screen containers
- Fallback to native transitions – Screens without
enableTransitions: trueuse platform defaults - React Navigation compatibility – Extends official native-stack navigator
Limitations
Delayed touch events
Delayed touch events
Exiting screens may have briefly delayed touch response due to modal presentation layer.Impact: Users might notice a ~50-100ms delay when tapping on the previous screen during/after a transition.Workaround: Use Blank Stack if this affects your UX.
beforeRemove listeners
beforeRemove listeners
The Native Stack relies on React Navigation lifecycle events for
beforeRemove listeners.Impact: If you have complex beforeRemove logic (e.g., “unsaved changes” prompts), behavior may differ slightly from standard native-stack.Workaround: Test your beforeRemove logic thoroughly, or use Blank Stack.Rapid navigation edge cases
Rapid navigation edge cases
Requires enableTransitions flag
Requires enableTransitions flag
You must explicitly enable custom transitions on each screen:Impact: Extra configuration step. Easy to forget.Benefit: Screens without the flag use platform-native transitions automatically.
When to Use
- You need native screen primitives for specific platform features
- You want to mix custom and native transitions in the same stack
- Touch delay and edge cases don’t affect your app’s UX
When to Avoid
- Touch responsiveness is critical (e.g., games, creative tools)
- You have complex
beforeRemovelogic - You’re using rapid programmatic navigation
Component Stack (Experimental)
How It Works
Standalone navigator, not connected to React Navigation. Ideal for embedded flows that don’t need routing integration.Advantages
- Isolated state – Doesn’t affect parent navigation
- Embeddable – Can be used inside any component
- Simple API – No React Navigation setup required
- Touch pass-through – Uses
pointerEvents="box-none"by default
Limitations
No deep linking
No deep linking
Routes aren’t part of your URL structure.Impact: Can’t link directly to screens inside the component stack. Not suitable for top-level navigation.Workaround: Use Blank Stack or Native Stack for top-level navigation. Use Component Stack only for embedded flows.
Isolated from React Navigation
Isolated from React Navigation
Touch event handling
Touch event handling
Uses
pointerEvents="box-none" by default to allow touch pass-through.Impact: Touch events pass through empty areas to content below. This is usually desired for embedded stacks, but may cause unexpected behavior if not understood.Workaround: Adjust pointerEvents prop if needed.Experimental API
Experimental API
The API may change in future versions based on community feedback.Impact: Breaking changes possible in minor/patch releases.Recommendation: Pin your version and test thoroughly before upgrading.
When to Use
- Embedded multi-step forms or wizards
- Modal flows that don’t need routing
- Isolated feature flows inside a screen
- Prototypes and experiments
When to Avoid
- Top-level app navigation
- Any flow that needs deep linking
- Production apps requiring API stability
- Integration with React Navigation state
Performance Comparison
| Metric | Blank Stack | Native Stack | Component Stack |
|---|---|---|---|
| Animation performance | Excellent | Excellent | Excellent |
| Touch responsiveness | Excellent | Good* | Excellent |
| Memory usage | Low | Low | Lowest |
| Bundle size impact | Medium | Medium | Small |
*Native Stack touch responsiveness is “Good” due to modal-related delays. For most apps, this is not noticeable.
Choosing the Right Stack
Use Blank Stack if:
- You’re building a new app (default choice)
- You need custom animations, gestures, or shared elements
- Touch responsiveness is important
- You want the fewest limitations
Use Native Stack if:
- You specifically need native screen primitives
- You want to mix custom and platform-native transitions
- Touch delay doesn’t affect your UX
- You’re migrating from
@react-navigation/native-stack
Use Component Stack if:
- You’re building embedded flows (wizards, onboarding)
- You don’t need routing/deep linking
- You’re okay with experimental API
- You want isolation from parent navigation
Migration Path
All three stacks share the same animation API, making migration straightforward:All animation options, presets, and hooks work identically across stack types.
Related Resources
- Stack Types - Detailed API documentation for each stack
- Installation - Setup instructions
- Quick Start - Get started with Blank Stack
