Skip to main content
Creates a standalone component stack navigator that is isolated from React Navigation. Ideal for embedded flows within your app that don’t need to be part of the main navigation tree.
Experimental Feature: This API is experimental and may change based on community feedback. Use with caution in production applications.

Function Signature

function createComponentStackNavigator<
  ParamList extends ParamListBase = ParamListBase,
  NavigatorID extends string | undefined = undefined
>(config?: StaticConfig): TypedNavigator<TypeBag, Config>

Type Parameters

ParamList
ParamListBase
default:"ParamListBase"
The parameter list for the navigator, defining route names and their parameters
NavigatorID
string | undefined
default:"undefined"
Optional unique identifier for the navigator instance

Parameters

config
StaticConfig
Optional static configuration for the navigator (rarely needed)

Return Value

TypedNavigator
TypedNavigator<TypeBag, Config>
Returns a typed navigator object containing:
  • Navigator: The navigator component
  • Screen: The screen component for defining routes
  • Group: Component for grouping screens with shared options

Import

import { createComponentStackNavigator } from "react-native-screen-transitions/component-stack";

Usage

Basic Setup

import { createComponentStackNavigator } from "react-native-screen-transitions/component-stack";
import Transition from "react-native-screen-transitions";

const Stack = createComponentStackNavigator();

function OnboardingFlow() {
  return (
    <Stack.Navigator initialRouteName="step1">
      <Stack.Screen name="step1" component={Step1} />
      <Stack.Screen
        name="step2"
        component={Step2}
        options={{
          ...Transition.Presets.SlideFromBottom(),
        }}
      />
      <Stack.Screen name="step3" component={Step3} />
    </Stack.Navigator>
  );
}

Embedded in Parent App

import { View } from 'react-native';

function MainApp() {
  return (
    <View style={{ flex: 1 }}>
      {/* This Component Stack is isolated from Expo Router / React Navigation */}
      <OnboardingFlow />
    </View>
  );
}

With TypeScript

import { createComponentStackNavigator } from "react-native-screen-transitions/component-stack";
import type { ComponentStackNavigationProp } from "react-native-screen-transitions/component-stack";

type OnboardingParamList = {
  step1: undefined;
  step2: { name: string };
  step3: { complete: boolean };
};

const Stack = createComponentStackNavigator<OnboardingParamList>();

type Step1Props = {
  navigation: ComponentStackNavigationProp<OnboardingParamList, 'step1'>;
};

function Step1({ navigation }: Step1Props) {
  return (
    <Button
      title="Next"
      onPress={() => navigation.navigate('step2', { name: 'John' })}
    />
  );
}

Nested Component Stacks

Component Stacks can be nested within each other, and goBack() will work correctly:
function ParentFlow() {
  return (
    <ParentStack.Navigator>
      <ParentStack.Screen name="main" component={MainScreen} />
      <ParentStack.Screen name="nested" component={NestedFlow} />
    </ParentStack.Navigator>
  );
}

function NestedFlow() {
  return (
    <NestedStack.Navigator>
      <NestedStack.Screen name="a" component={ScreenA} />
      <NestedStack.Screen name="b" component={ScreenB} />
    </NestedStack.Navigator>
  );
}

Features

Full Animation Control

Supports all transition features:
<Stack.Screen
  name="step2"
  component={Step2}
  options={{
    screenStyleInterpolator: ({ progress }) => {
      "worklet";
      return {
        contentStyle: {
          opacity: interpolate(progress, [0, 1, 2], [0, 1, 0]),
        },
      };
    },
  }}
/>

Gestures and Snap Points

All gesture and snap point features work:
<Stack.Screen
  name="sheet"
  options={{
    gestureEnabled: true,
    gestureDirection: "vertical",
    snapPoints: [0.5, 1],
    ...Transition.Presets.SlideFromBottom(),
  }}
/>

Shared Elements

Shared element transitions work within the Component Stack:
<Stack.Screen
  name="detail"
  options={{
    ...Transition.Presets.SharedAppleMusic({
      sharedBoundTag: "image"
    }),
  }}
/>

When to Use

Perfect For

  • Onboarding flows
  • Multi-step forms
  • Embedded tutorials
  • Isolated feature flows
  • Components with internal navigation

Not Ideal For

  • Main app navigation
  • Deep linking required
  • URL-based routing needed
  • Integration with Expo Router

Isolation

The Component Stack is completely isolated from your main navigation tree:
  • No deep linking: Routes aren’t part of your URL structure
  • Isolated state: Doesn’t affect parent navigation
  • Independent: Works without Expo Router or React Navigation
  • Self-contained: Has its own navigation state and history

Architecture

  • Navigation Tree: Uses NavigationIndependentTree to isolate from parent
  • Container: Wrapped in NavigationContainer (top-level only)
  • Nesting: Nested Component Stacks share the parent’s tree
  • Touch Behavior: Uses pointerEvents="box-none" by default

Limitations

Component Stack has intentional limitations due to its isolation:
  • No deep linking: Cannot be accessed via URLs or deep links
  • No parent integration: Isolated from Expo Router / React Navigation
  • No global navigation: Can’t navigate to parent routes
  • Experimental API: May change in future versions

Comparison with Other Stacks

FeatureComponent StackBlank StackNative Stack
Custom animations✓ (with flag)
Deep linking
Isolated state
Embedded use
React Navigation integration
URL routing

Use Cases

Onboarding Flow

import { createComponentStackNavigator } from "react-native-screen-transitions/component-stack";

const OnboardingStack = createComponentStackNavigator();

function OnboardingFlow() {
  return (
    <OnboardingStack.Navigator initialRouteName="welcome">
      <OnboardingStack.Screen name="welcome" component={WelcomeScreen} />
      <OnboardingStack.Screen name="signup" component={SignupScreen} />
      <OnboardingStack.Screen name="complete" component={CompleteScreen} />
    </OnboardingStack.Navigator>
  );
}

// Use anywhere in your app
function App() {
  const [showOnboarding, setShowOnboarding] = useState(true);
  
  if (showOnboarding) {
    return <OnboardingFlow />;
  }
  
  return <MainApp />;
}

Multi-Step Form

const FormStack = createComponentStackNavigator();

function CheckoutFlow() {
  return (
    <FormStack.Navigator>
      <FormStack.Screen name="cart" component={CartScreen} />
      <FormStack.Screen name="shipping" component={ShippingScreen} />
      <FormStack.Screen name="payment" component={PaymentScreen} />
      <FormStack.Screen name="confirm" component={ConfirmScreen} />
    </FormStack.Navigator>
  );
}

Exported Types

import type {
  ComponentStackNavigationOptions,
  ComponentStackNavigationProp,
  ComponentStackScreenProps,
  ComponentStackNavigatorProps,
  ComponentStackNavigationEventMap,
  ComponentStackOverlayProps,
  ComponentStackOptionsArgs,
} from "react-native-screen-transitions/component-stack";