npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@umituz/react-native-onboarding

v2.8.1

Published

Advanced onboarding flow for React Native apps with personalization questions, theme-aware colors, animations, and customizable slides. SOLID, DRY, KISS principles applied.

Downloads

3,674

Readme

@umituz/react-native-onboarding

Advanced onboarding flow for React Native apps with personalization questions, gradient backgrounds, animations, and customizable slides. Built with SOLID, DRY, KISS principles.

✨ Features

  • 🎨 Beautiful gradient backgrounds with smooth transitions
  • Personalization questions - Get to know your users
  • 📝 Multiple question types - Single choice, multiple choice, text input, slider, rating
  • Built-in validation - Required fields, min/max values, custom validators
  • 🔄 Conditional slides - Skip slides based on previous answers
  • 💾 Persistent storage - Save user answers and onboarding state
  • 🎯 Type-safe - Full TypeScript support
  • 🎭 Customizable - Custom header, footer, and slide components
  • 📱 Universal - Works on iOS, Android, and Web
  • 🚀 Production-ready - Used in hundreds of apps

📦 Installation

npm install @umituz/react-native-onboarding

Peer Dependencies

npm install \
  @umituz/react-native-storage \
  @umituz/react-native-localization \
  @umituz/react-native-design-system-theme \
  @umituz/react-native-design-system \
  @umituz/react-native-design-system-atoms \
  @react-native-community/slider \
  expo-linear-gradient \
  react-native-safe-area-context \
  zustand

🚀 Quick Start

Basic Onboarding (Info Slides Only)

import { OnboardingScreen } from '@umituz/react-native-onboarding';

const slides = [
  {
    id: '1',
    title: 'Welcome to Our App',
    description: 'Discover amazing features',
    icon: '👋',
    gradient: ['#667eea', '#764ba2'],
  },
  {
    id: '2',
    title: 'Stay Organized',
    description: 'Keep track of everything',
    icon: '📋',
    gradient: ['#f093fb', '#f5576c'],
  },
];

<OnboardingScreen
  slides={slides}
  onComplete={() => console.log('Onboarding completed')}
/>

Advanced Onboarding (With Personalization Questions)

import { OnboardingScreen, OnboardingSlide } from '@umituz/react-native-onboarding';

const slides: OnboardingSlide[] = [
  // Welcome slide
  {
    id: '1',
    type: 'welcome',
    title: 'Welcome to FishWise',
    description: 'Your personal aquarium assistant',
    icon: '🐠',
    gradient: ['#667eea', '#764ba2'],
  },
  
  // Question: Experience level
  {
    id: '2',
    type: 'question',
    title: 'What\'s your experience level?',
    description: 'Help us personalize your experience',
    icon: '🎯',
    gradient: ['#f093fb', '#f5576c'],
    question: {
      id: 'experience_level',
      type: 'single_choice',
      question: 'Select your experience level',
      storageKey: '@user_experience_level',
      validation: { required: true },
      options: [
        { id: 'beginner', label: 'Beginner', icon: '🌱' },
        { id: 'intermediate', label: 'Intermediate', icon: '🌿' },
        { id: 'expert', label: 'Expert', icon: '🌳' },
      ],
    },
  },
  
  // Question: Tank size
  {
    id: '3',
    type: 'question',
    title: 'What\'s your tank size?',
    description: 'This helps us recommend suitable fish',
    icon: '📏',
    gradient: ['#4facfe', '#00f2fe'],
    question: {
      id: 'tank_size',
      type: 'slider',
      question: 'Select your tank size (gallons)',
      storageKey: '@user_tank_size',
      validation: { required: true, min: 10, max: 500 },
      defaultValue: 50,
    },
  },
  
  // Question: Interests
  {
    id: '4',
    type: 'question',
    title: 'What interests you most?',
    description: 'Select all that apply',
    icon: '❤️',
    gradient: ['#fa709a', '#fee140'],
    question: {
      id: 'interests',
      type: 'multiple_choice',
      question: 'Choose your interests',
      storageKey: '@user_interests',
      validation: { required: true, minSelections: 1, maxSelections: 3 },
      options: [
        { id: 'freshwater', label: 'Freshwater Fish', icon: '🐟' },
        { id: 'saltwater', label: 'Saltwater Fish', icon: '🐠' },
        { id: 'plants', label: 'Aquatic Plants', icon: '🌿' },
        { id: 'equipment', label: 'Equipment & Tech', icon: '⚙️' },
      ],
    },
  },
  
  // Completion slide
  {
    id: '5',
    type: 'completion',
    title: 'You\'re All Set!',
    description: 'Let\'s start your aquarium journey',
    icon: '🎉',
    gradient: ['#30cfd0', '#330867'],
  },
];

import Slider from '@react-native-community/slider';

<OnboardingScreen
  slides={slides}
  SliderComponent={Slider}
  onComplete={async () => {
    const userData = onboardingStore.getUserData();
    console.log('User answers:', userData.answers);
    // Save to backend, navigate to home, etc.
  }}
/>

📖 API Reference

OnboardingScreen Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | slides | OnboardingSlide[] | Required | Array of slides to display | | onComplete | () => void \| Promise<void> | - | Callback when onboarding is completed | | onSkip | () => void \| Promise<void> | - | Callback when onboarding is skipped | | skipButtonText | string | "Skip" | Custom skip button text | | nextButtonText | string | "Next" | Custom next button text | | getStartedButtonText | string | "Get Started" | Custom get started button text | | showSkipButton | boolean | true | Show skip button | | showBackButton | boolean | true | Show back button | | showProgressBar | boolean | true | Show progress bar | | showDots | boolean | true | Show dots indicator | | showProgressText | boolean | true | Show progress text (1 of 5) | | storageKey | string | - | Custom storage key for completion state | | autoComplete | boolean | false | Auto-complete on last slide | | SliderComponent | React.ComponentType | - | Required if using slider questions. Import from @react-native-community/slider |

OnboardingSlide Interface

interface OnboardingSlide {
  id: string;
  type?: 'info' | 'question' | 'welcome' | 'completion';
  title: string;
  description: string;
  icon: string; // Emoji or Lucide icon name
  gradient: string[]; // [startColor, endColor] or [color1, color2, color3]
  image?: string;
  features?: string[];
  question?: OnboardingQuestion;
  skipIf?: (answers: Record<string, any>) => boolean;
}

Question Types

Single Choice

{
  type: 'single_choice',
  question: 'What is your goal?',
  options: [
    { id: 'weight_loss', label: 'Weight Loss', icon: '🏃' },
    { id: 'muscle_gain', label: 'Muscle Gain', icon: '💪' },
  ],
}

Multiple Choice

{
  type: 'multiple_choice',
  question: 'Select your interests',
  validation: { minSelections: 1, maxSelections: 3 },
  options: [
    { id: 'yoga', label: 'Yoga', icon: '🧘' },
    { id: 'running', label: 'Running', icon: '🏃' },
    { id: 'swimming', label: 'Swimming', icon: '🏊' },
  ],
}

Text Input

{
  type: 'text_input',
  question: 'What is your name?',
  placeholder: 'Enter your name',
  validation: { required: true, minLength: 2, maxLength: 50 },
}

Slider

⚠️ Important: When using slider questions, you must provide the SliderComponent prop to OnboardingScreen:

import Slider from '@react-native-community/slider';

<OnboardingScreen
  slides={slides}
  SliderComponent={Slider}
  onComplete={handleComplete}
/>
{
  type: 'slider',
  question: 'What is your age?',
  validation: { min: 18, max: 100 },
  defaultValue: 25,
}

Note: Make sure @react-native-community/slider is installed and properly linked (run pod install for iOS).

Rating

{
  type: 'rating',
  question: 'Rate your experience',
  validation: { max: 5 },
}

🎨 Customization

Custom Header

<OnboardingScreen
  slides={slides}
  renderHeader={({ isFirstSlide, onBack, onSkip }) => (
    <View>
      {!isFirstSlide && <Button onPress={onBack}>Back</Button>}
      <Button onPress={onSkip}>Skip</Button>
    </View>
  )}
/>

Custom Footer

<OnboardingScreen
  slides={slides}
  renderFooter={({ currentIndex, totalSlides, isLastSlide, onNext }) => (
    <View>
      <Text>{currentIndex + 1} / {totalSlides}</Text>
      <Button onPress={onNext}>
        {isLastSlide ? 'Get Started' : 'Next'}
      </Button>
    </View>
  )}
/>

Conditional Slides

{
  id: '3',
  title: 'Advanced Features',
  description: 'Only for experienced users',
  icon: '⚡',
  gradient: ['#667eea', '#764ba2'],
  skipIf: (answers) => answers.experience_level === 'beginner',
}

💾 Accessing User Data

import { useOnboarding } from '@umituz/react-native-onboarding';

const { userData, getAnswer } = useOnboarding();

// Get specific answer
const experienceLevel = getAnswer('experience_level');

// Get all answers
const allAnswers = userData.answers;

// Check if onboarding was completed
const isComplete = userData.completedAt !== undefined;

// Check if onboarding was skipped
const wasSkipped = userData.skipped === true;

🔄 Resetting Onboarding

import { useOnboarding } from '@umituz/react-native-onboarding';

const { reset } = useOnboarding();

// Reset onboarding (useful for testing or settings)
await reset();

📱 Platform Support

  • ✅ iOS
  • ✅ Android
  • ✅ Web

🏗️ Architecture

Built with Domain-Driven Design (DDD):

  • Domain Layer: Entities and interfaces (business logic)
  • Infrastructure Layer: Storage and hooks (state management)
  • Presentation Layer: Components and screens (UI)

📄 License

MIT

🤝 Contributing

Contributions are welcome! Please open an issue or PR.

📧 Support

For issues and questions, please open an issue on GitHub.