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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@raymardev/react-native-intersection-observer

v1.0.0

Published

A powerful React Native hook for detecting scroll intersections with ScrollView, FlatList, and SectionList components

Downloads

28

Readme

React Native Intersection Observer

npm version npm downloads License TypeScript React Native

A powerful and flexible React Native hook for detecting scroll intersections with ScrollView, FlatList, and SectionList components. This library provides an easy-to-use API similar to the web's Intersection Observer API, but specifically designed for React Native's scroll components.

📖 Documentation💡 Examples🐛 Issues💬 Discussions

✨ Features

  • 🎯 Multiple Detection Positions: Detect intersections at top, bottom, center, or custom element positions
  • 📱 Cross-Platform: Works with ScrollView, FlatList, and SectionList components
  • 🔧 TypeScript Support: Full TypeScript support with comprehensive type definitions
  • Performance Optimized: Efficient scroll event handling with minimal re-renders
  • 🎨 Flexible API: Multiple convenience hooks for common use cases
  • 📊 Custom Thresholds: Configurable intersection thresholds
  • 🔄 Callback Support: Rich callback system for intersection events
  • 🚀 Zero Dependencies: No external dependencies, lightweight and fast
  • 📚 Comprehensive Docs: Detailed documentation and examples

📦 Installation

npm install @raymardev/react-native-intersection-observer

or

yarn add @raymardev/react-native-intersection-observer

Requirements

  • React Native 0.60+
  • React 16.8+ (hooks support required)
  • TypeScript 4.0+ (optional but recommended)

🚀 Quick Start

import React from 'react';
import { ScrollView, Text, View } from 'react-native';
import { useScrollToBottom } from '@raymardev/react-native-intersection-observer';

export default function App() {
  const { isIntersecting, ref, handleScroll } = useScrollToBottom(50, {
    type: 'scrollview',
    callbacks: {
      onIntersect: () => console.log('Reached bottom!'),
      onVisible: () => console.log('Left bottom area'),
    },
  });

  return (
    <ScrollView ref={ref} onScroll={handleScroll} scrollEventThrottle={16}>
      <View style={{ height: 2000 }}>
        <Text>Scroll to bottom to trigger intersection</Text>
        {isIntersecting && <Text>🎉 You reached the bottom!</Text>}
      </View>
    </ScrollView>
  );
}

📚 Documentation

🔧 API Reference

Core Hook

useIntersectionObserver(options)

The main hook that provides intersection detection functionality.

Parameters:

  • options (object):
    • threshold?: number - Distance threshold for intersection detection (default: 20)
    • position?: 'top' | 'bottom' | 'center' | 'custom' | 'element' - Position to detect (default: 'bottom')
    • element?: React.RefObject<View> - Element ref for position: 'element'
    • onIntersect?: () => void - Callback when intersection starts
    • onVisible?: () => void - Callback when intersection ends
    • onIntersectionChange?: (isIntersecting: boolean) => void - Callback for any intersection change

Returns:

  • isIntersecting: boolean - Current intersection state
  • ref: React.RefObject<ScrollView | FlatList | SectionList> - Ref for the scroll component
  • handleScroll: (event: any) => void - Scroll event handler
  • handleElementLayout: (event: any) => void - Layout handler for element positioning
  • reset: () => void - Reset intersection state

Convenience Hooks

useScrollToBottom(threshold?, options?)

Detects when the user has scrolled to the bottom of the scroll view.

const { isIntersecting, ref, handleScroll } = useScrollToBottom(50, {
  type: 'scrollview', // or 'flatlist', 'sectionlist'
  callbacks: {
    onIntersect: () => console.log('Bottom reached!'),
  },
});

useScrollToTop(threshold?, options?)

Detects when the user has scrolled to the top of the scroll view.

const { isIntersecting, ref, handleScroll } = useScrollToTop(50, {
  type: 'flatlist',
  callbacks: {
    onIntersect: () => console.log('Top reached!'),
  },
});

useScrollToCenter(threshold?, options?)

Detects when the user has scrolled to the center of the scroll view.

const { isIntersecting, ref, handleScroll } = useScrollToCenter(100, {
  type: 'sectionlist',
  callbacks: {
    onIntersect: () => console.log('Center reached!'),
  },
});

useElementIntersection(element, threshold?, callbacks?)

Detects when a specific element becomes visible in the scroll view.

const elementRef = useRef<View>(null);
const { isIntersecting, ref, handleScroll, handleElementLayout } =
  useElementIntersection(elementRef, 50, {
    onIntersect: () => console.log('Element is visible!'),
  });

return (
  <ScrollView ref={ref} onScroll={handleScroll}>
    <View ref={elementRef} onLayout={handleElementLayout}>
      <Text>This element will be tracked</Text>
    </View>
  </ScrollView>
);

💡 Common Use Cases

Infinite Scroll with FlatList

import React, { useState, useCallback } from 'react';
import { FlatList, View, Text, ActivityIndicator } from 'react-native';
import { useScrollToBottom } from '@raymardev/react-native-intersection-observer';

export default function InfiniteScrollList() {
  const [data, setData] = useState(
    Array.from({ length: 20 }, (_, i) => ({ id: i, text: `Item ${i}` }))
  );
  const [loading, setLoading] = useState(false);

  const loadMore = useCallback(async () => {
    if (loading) return;

    setLoading(true);
    // Simulate API call
    await new Promise(resolve => setTimeout(resolve, 1000));

    const newData = Array.from({ length: 10 }, (_, i) => ({
      id: data.length + i,
      text: `Item ${data.length + i}`,
    }));

    setData(prev => [...prev, ...newData]);
    setLoading(false);
  }, [data.length, loading]);

  const { ref, handleScroll } = useScrollToBottom(100, {
    type: 'flatlist',
    callbacks: {
      onIntersect: loadMore,
    },
  });

  const renderItem = ({ item }: { item: any }) => (
    <View style={{ padding: 20, borderBottomWidth: 1 }}>
      <Text>{item.text}</Text>
    </View>
  );

  const renderFooter = () =>
    loading ? <ActivityIndicator style={{ padding: 20 }} /> : null;

  return (
    <FlatList
      ref={ref}
      data={data}
      renderItem={renderItem}
      onScroll={handleScroll}
      scrollEventThrottle={16}
      ListFooterComponent={renderFooter}
    />
  );
}

Pull-to-Refresh Detection

import React from 'react';
import { ScrollView, View, Text } from 'react-native';
import { useScrollToTop } from '@raymardev/react-native-intersection-observer';

export default function PullToRefresh() {
  const { isIntersecting, ref, handleScroll } = useScrollToTop(10, {
    type: 'scrollview',
    callbacks: {
      onIntersect: () => {
        console.log('Ready for pull-to-refresh!');
        // Trigger your refresh logic here
      },
    },
  });

  return (
    <ScrollView ref={ref} onScroll={handleScroll} scrollEventThrottle={16}>
      <View style={{ height: 2000 }}>
        <Text>Pull down to refresh</Text>
        {isIntersecting && <Text>🔄 Ready to refresh!</Text>}
      </View>
    </ScrollView>
  );
}

Element Visibility Tracking

import React, { useRef } from 'react';
import { ScrollView, View, Text } from 'react-native';
import { useElementIntersection } from '@raymardev/react-native-intersection-observer';

export default function ElementTracking() {
  const targetRef = useRef<View>(null);

  const { isIntersecting, ref, handleScroll, handleElementLayout } =
    useElementIntersection(targetRef, 50, {
      onIntersect: () => console.log('Target element is visible!'),
      onVisible: () => console.log('Target element is hidden!'),
    });

  return (
    <ScrollView ref={ref} onScroll={handleScroll} scrollEventThrottle={16}>
      <View style={{ height: 1000 }}>
        <Text>Scroll down to see the target element</Text>
      </View>

      <View
        ref={targetRef}
        onLayout={handleElementLayout}
        style={{
          height: 200,
          backgroundColor: isIntersecting ? '#4CAF50' : '#FF5722',
          justifyContent: 'center',
          alignItems: 'center',
        }}
      >
        <Text style={{ color: 'white', fontSize: 18 }}>
          {isIntersecting ? 'I am visible! 🎉' : 'I am hidden 👻'}
        </Text>
      </View>

      <View style={{ height: 1000 }}>
        <Text>More content below</Text>
      </View>
    </ScrollView>
  );
}

⚡ Performance Considerations

  • Use scrollEventThrottle={16} for smooth 60fps scroll events
  • The hook automatically optimizes re-renders by only updating state when intersection status changes
  • For large lists, consider using the convenience hooks which are optimized for specific use cases
  • Element intersection tracking requires layout measurements, so use sparingly for performance

🔧 TypeScript Support

This library is written in TypeScript and provides full type definitions. All hooks and their parameters are fully typed for the best development experience.

import {
  useIntersectionObserver,
  UseIntersectionObserverOptions,
  UseIntersectionObserverReturn,
} from '@raymardev/react-native-intersection-observer';

const options: UseIntersectionObserverOptions = {
  threshold: 50,
  position: 'bottom',
  onIntersect: () => console.log('Intersected!'),
};

const result: UseIntersectionObserverReturn = useIntersectionObserver(options);

👨‍💻 About the Author

This library is created and maintained by Ray Martin, a full-stack developer specializing in React Native, Next.js, and modern web technologies.

  • 🌐 Personal Website: raymartin.es (available in English and Spanish)
  • 💼 Professional Profile: Full-stack developer with expertise in enterprise-grade applications
  • 🚀 Open Source: Active contributor to the React Native ecosystem
  • 📧 Contact: Available for consulting and collaboration

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details on how to get started.

Quick Start for Contributors

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Run tests: npm test
  5. Commit your changes: git commit -m 'feat: add amazing feature'
  6. Push to the branch: git push origin feature/amazing-feature
  7. Open a Pull Request

🐛 Issues & Support

📄 License

MIT © Ray MartinGitHub

📈 Changelog

See CHANGELOG.md for a complete list of changes.

Recent Updates

  • v1.0.0 - Initial release with full feature set
  • Comprehensive documentation and examples
  • TypeScript support with full type definitions
  • Performance optimizations
  • Cross-platform compatibility

⭐ Star this repository if you find it helpful!


🌟 Connect with the Author

Ray Martin • Full-Stack Developer

Website GitHub NPM

Available for consulting and collaborationWebsite available in English and Spanish

Made with ❤️ by Ray Martin