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

react-native-marquee-animation

v0.1.3

Published

Production-grade generic native marquee for React Native

Readme

React Native Marquee

A production-grade generic marquee for React Native's New Architecture. Render ordinary React Native text, images, icons, badges, charts, and composed views once; native iOS and Android code repeats the visual strip and owns all motion.

There is no per-frame JavaScript, duplicated React state, or list virtualization.

Demo

https://github.com/user-attachments/assets/9f4e1655-0f2c-468f-b0e4-25af40de5631

Compatibility

| Requirement | Supported | | ------------ | ---------------------------------------- | | React Native | 0.85.x | | React | 19.2.x | | Expo | SDK 56 development and production builds | | iOS | 17 and newer | | Android | API 24 and newer | | Architecture | New Architecture (Fabric) only | | Expo Go | No |

Installation

bun add react-native-marquee-animation

Expo applications must regenerate and rebuild the native project:

bunx expo prebuild --clean
bunx expo run:ios
# or: bunx expo run:android

Quick start

import { Image, StyleSheet, Text, View } from 'react-native';
import { Marquee } from 'react-native-marquee-animation';

export const NewsStrip = () => (
  <Marquee
    accessibilityLabel="Latest headlines"
    contentContainerStyle={styles.row}
    spacing={32}
    speed={25}
    style={styles.marquee}
  >
    <View style={styles.card}>
      <Image source={require('./logo.png')} style={styles.image} />
      <Text>Images, text, badges, icons, and custom views</Text>
    </View>
    <View style={styles.card}>
      <Text>React state is mounted exactly once</Text>
    </View>
  </Marquee>
);

const styles = StyleSheet.create({
  card: { alignItems: 'center', flexDirection: 'row', gap: 8 },
  image: { height: 24, width: 24 },
  marquee: { height: 48 },
  row: { alignItems: 'center', gap: 24 },
});

The package wraps children in one non-collapsible horizontal content view, measures that view only when layout changes, and passes one width update to native code. Native motion remains uninterrupted when child pixels change without changing width.

Gesture physics

Dragging, release velocity, decay, and the transition back to automatic motion are native-owned:

<Marquee
  accessibilityLabel="Live activity"
  interaction={{
    maxFlingVelocity: 3200,
    deceleration: 0.9985,
    pauseOnPress: true,
    resumeDelay: 0,
  }}
>
  {content}
</Marquee>

After a fling decelerates, both platforms blend velocity into the configured automatic direction over 350 ms instead of stopping or snapping. pauseOnPress: true pauses immediately on touch-down. resumeDelay controls when automatic motion resumes after release. On iOS, drag, fling, and the blend back to automatic motion are synchronized to the active screen's refresh rate.

Content contract

Supported content includes normal layer/display-list-backed React Native views:

  • Text, View, Image, and expo-image;
  • SVG, icons, badges, gradients, and composed layouts;
  • custom charts that render into the ordinary React Native view hierarchy;
  • child state, asynchronous image loading, and dynamic value changes.

Marquee children are deliberately noninteractive. The host owns horizontal pan, hold, and fling gestures, and repeated pixels are not additional React views. Nested Pressable, TextInput, map, video, camera, SurfaceView, TextureView, Metal, and other external rendering surfaces are outside the contract. Use a separate typed interaction layer when individual repeated items must be clickable.

Main props

| Prop | Default | Meaning | | ----------------------- | -------- | -------------------------------------------- | | accessibilityLabel | required | One semantic description of the strip | | speed | 25 | Logical pixels per second | | direction | left | Automatic motion direction | | spacing | 0 | Empty distance between visual copies | | active | true | Application-level pause control | | shortContentMode | static | Static content or repeated short content | | contentAlignment | start | Alignment while short content is stationary | | contentContainerStyle | — | Style for the one horizontal content wrapper | | reduceMotion | system | system, always, or never |

Native architecture

  • iOS mounts one Fabric child container as the only subview of a CAReplicatorLayer-backed Swift view. Core Animation translates it without a display callback during automatic motion.
  • Android mounts one Fabric child container in a custom ViewGroup and replays the existing hardware display lists at repeated canvas offsets. A monotonic Choreographer clock changes only the translation phase. Missed callbacks advance by at most roughly one current display interval instead of catching up in one visible jump; API 35+ requests a high refresh rate only while active.
  • Same-width visual updates do not restart motion. Width changes preserve the physical offset and velocity while native code recomputes the loop period.
  • Content that fits, active={false}, detached views, backgrounded apps, and Reduced Motion schedule no continuous frame work. Window-attached views use active as the authoritative application-level visibility signal.
  • Only the host is accessible; visually repeated descendants are hidden from VoiceOver and TalkBack.

See architecture, accessibility, testing, and performance.

Fabric and Codegen

src/RNMarqueeViewNativeComponent.ts is the source of truth. The native component is RNMarqueeView, the Codegen library is RNMarqueeViewSpec, and the iOS pod/module is RNMarquee. Generated bindings are consumer-owned and are not published.

Development

The repository uses Bun, React Native Builder Bob, an Expo SDK 56 consumer, Swift and Kotlin tests, Release builds, packed-tarball validation, and Maestro. Start with CONTRIBUTING.md.

Example experience

The Expo example follows the same showcase-first product system as the sibling number-animation package. Release builds open a self-running green-and-cream showcase with product, music, event, finance, image, badge, a Bhagavad Gita verse in Kannada script, and gesture examples. Development builds expose an Open reliability lab button; benchmark deep links open that lab directly in either build.

Use bun run capture:ios or bun run capture:android from example/ for clean Release presentation captures. See example/CAPTURE.md.

License

MIT