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-fallback-ads

v2.0.0

Published

Fallback ads for React Native & Expo (JS only)

Readme

react-native-fallback-ads

Lightweight, JS-only fallback ad components for React Native & Expo — no native modules, no native linking required.

npm version license peer: react-native ≥ 0.83 TypeScript

When your primary ad SDK fails to load — network errors, no fill, SDK initialisation issues, ad blockers — react-native-fallback-ads lets you drop in a polished, self-contained ad unit in seconds. All components are written in pure JavaScript/TypeScript with zero native dependencies.


Table of Contents


Features

  • Zero native code — pure JS/TS, works with Expo Go and managed workflow
  • 🎨 Light / dark / auto theme support on every component
  • 🔁 Multi-image cycling with smooth animations (flip, 3d-flip, fade, none)
  • 🖼 Fullscreen interstitial with configurable close-button delay and countdown badge
  • 🎁 Rewarded video ad support with custom watch-to-end or close-delay modes
  • Accessible — every component ships with proper accessibilityRole and accessibilityLabel
  • 🔧 Fully typed — complete TypeScript definitions included

Installation

npm install react-native-fallback-ads
# or
yarn add react-native-fallback-ads

No pod install, no expo prebuild, no npx react-native link needed.


Components

FallbackBannerAd

A smart banner that accepts an array of mixed text/image ad configs and randomly selects one to display. Exposes a ref with a refresh() method to pick a new random ad on demand.

import { useRef } from 'react';
import { FallbackBannerAd, FallbackBannerAdRef } from 'react-native-fallback-ads';

const bannerRef = useRef<FallbackBannerAdRef>(null);

<FallbackBannerAd
  ref={bannerRef}
  theme="auto"
  data={[
    {
      type: 'text',
      icon: require('./assets/app-icon.png'),
      title: 'My Awesome App',
      subtitle: 'Download it free today',
      link: 'https://example.com/app',
    },
    {
      type: 'image',
      image: require('./assets/banner.png'),
      link: 'https://example.com/promo',
    },
  ]}
/>

// Refresh the displayed ad at any time:
bannerRef.current?.refresh();

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | data | BannerAdItem[] | required | Array of text or image ad configs | | style | ViewStyle | — | Override container styles | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Color scheme | | mode | 'manual' \| 'auto' | 'manual' | Refresh mode. If 'auto', the ad will automatically refresh every refreshInterval ms | | refreshInterval | number | 5000 | Refresh interval in milliseconds (applicable when mode is 'auto') | | testID | string | — | Test identifier |

Ref methods

| Method | Description | |--------|-------------| | refresh() | Randomly selects a new ad from data |


FallbackTextBannerAd

A compact 300 × 50 banner with an icon, title, and subtitle row. Best used as a house-ad or cross-promotion unit.

import { FallbackTextBannerAd } from 'react-native-fallback-ads';

<FallbackTextBannerAd
  icon={require('./assets/icon.png')}
  title="Try Our Pro Plan"
  subtitle="Unlock all features — starting at $2.99"
  link="https://example.com/pro"
  onPress={(url) => console.log('Opened:', url)}
  onError={(err) => console.warn('Ad error:', err)}
  theme="auto"
/>

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | icon | ImageSourcePropType | required | App icon or logo displayed on the left | | title | string | required | Primary text (bold) | | subtitle | string | required | Secondary text | | link | string | — | The destination link to open when the ad is tapped | | onPress | (url: string) => void | — | Called after the link is successfully opened | | onError | (err: AdError) => void | — | Called when the link cannot be resolved or opened | | style | ViewStyle | — | Override container styles | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Color scheme | | testID | string | — | Test identifier |


FallbackImageBannerAd

A 320 × 50 image banner that supports a single image or an array of images that cycle automatically with smooth animations.

import { FallbackImageBannerAd } from 'react-native-fallback-ads';

// Single image
<FallbackImageBannerAd
  image={require('./assets/banner.png')}
  link="https://example.com"
  theme="auto"
/>

// Cycling images with 3D flip transition
<FallbackImageBannerAd
  images={[
    require('./assets/banner1.png'),
    require('./assets/banner2.png'),
    require('./assets/banner3.png'),
  ]}
  switchInterval={4000}
  animationType="3d-flip"
  link="https://example.com"
  onPress={(url) => console.log('Tapped:', url)}
/>

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | image | ImageSourcePropType | — | Single image to display | | images | ImageSourcePropType[] | — | Array of images to cycle (overrides image) | | switchInterval | number | 5000 | Milliseconds between image switches | | animationType | 'flip' \| '3d-flip' \| 'fade' \| 'none' | 'flip' | Transition animation | | link | string | — | The destination link to open when the ad is tapped | | onPress | (url: string) => void | — | Called after the link is successfully opened | | onError | (err: AdError) => void | — | Called on link or image errors | | style | ViewStyle | — | Override container styles | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Color scheme | | testID | string | — | Test identifier |


FallbackMrecAd

A 300 × 250 medium rectangle (MREC) image ad — the industry-standard "box" format. Supports all the same cycling and animation options as FallbackImageBannerAd, plus a horizontal 3D flip variant.

import { FallbackMrecAd } from 'react-native-fallback-ads';

<FallbackMrecAd
  images={[
    require('./assets/mrec1.png'),
    require('./assets/mrec2.png'),
  ]}
  switchInterval={6000}
  animationType="3d-flip-horizontal"
  link={
    Platform.select({
      android: 'market://details?id=com.example.app',
      ios: 'https://apps.apple.com/app/id123456789',
      default: 'https://example.com',
    })
  }
  onPress={(url) => console.log('Opened:', url)}
  theme="dark"
/>

Props

Same as FallbackImageBannerAd, with one additional animationType option:

| Prop | Type | Default | Description | |------|------|---------|-------------| | animationType | 'flip' \| '3d-flip' \| '3d-flip-horizontal' \| 'fade' \| 'none' | 'flip' | Transition animation (adds horizontal 3D flip) |

All other props are identical to FallbackImageBannerAd.


FallbackFullscreenAd

A unified, full-screen interstitial ad component rendered inside a React Native Modal. Under the hood, it automatically delegates to either FallbackFullscreenImageAd or FallbackFullscreenVideoAd based on whether video props (portraitVideo or landscapeVideo) are provided.

import { useState } from 'react';
import { FallbackFullscreenAd } from 'react-native-fallback-ads';

const [adVisible, setAdVisible] = useState(false);

// Automatically renders FallbackFullscreenImageAd
<FallbackFullscreenAd
  visible={adVisible}
  portraitImage={require('./assets/interstitial-portrait.png')}
  landscapeImage={require('./assets/interstitial-landscape.png')}
  showCloseButton={true}
  closeDelay={5}
  link="https://example.com/promo"
  onDismiss={() => setAdVisible(false)}
/>

// Automatically renders FallbackFullscreenVideoAd
<FallbackFullscreenAd
  visible={adVisible}
  portraitVideo={require('./assets/video-portrait.mp4')}
  landscapeVideo={require('./assets/video-landscape.mp4')}
  showCloseButton={true}
  closeDelay={5}
  link="https://example.com/promo"
  onDismiss={() => setAdVisible(false)}
/>

Props

Since FallbackFullscreenAd serves as a wrapper, it accepts all props for both image and video fullscreen ads:

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | boolean | true | Controls modal visibility | | portraitImage | ImageSourcePropType | — | Portrait image source. (Used for Image Ads) | | landscapeImage | ImageSourcePropType | — | Landscape image source. Falls back to portraitImage. (Used for Image Ads) | | portraitVideo | any | — | Portrait video source (require or URI object). (Used for Video Ads) | | landscapeVideo | any | — | Landscape video source. Falls back to portraitVideo. (Used for Video Ads) | | onDismiss | () => void | — | Called when the close button is pressed or ad is dismissed | | link | string | — | Destination URL when the ad is tapped | | onPress | (resolvedUrl: string) => void | — | Callback after the link is successfully opened | | onError | (err: AdError) => void | — | Callback on link, image, or video loading/playback errors | | showCloseButton | boolean | true | Show/hide the close button | | closeDelay | number | 5 | Countdown in seconds before close button is active | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Theme scheme | | testID | string | — | Test identifier |


FallbackFullscreenImageAd

Specifically renders a fullscreen image ad.

import { FallbackFullscreenImageAd } from 'react-native-fallback-ads';

<FallbackFullscreenImageAd
  visible={visible}
  portraitImage={require('./assets/portrait.png')}
  landscapeImage={require('./assets/landscape.png')}
  onDismiss={() => setVisible(false)}
/>

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | boolean | true | Controls modal visibility | | portraitImage | ImageSourcePropType | — | Portrait image source | | landscapeImage | ImageSourcePropType | — | Landscape image source. Falls back to portraitImage | | onDismiss | () => void | — | Called when the close button is pressed | | link | string | — | Destination URL when the ad is tapped | | onPress | (resolvedUrl: string) => void | — | Callback after the link is successfully opened | | onError | (err: { type: 'NO_LINK' \| 'LINK_FAILED' \| 'NO_IMAGE'; message?: string }) => void | — | Callback on link or image load errors | | showCloseButton | boolean | true | Show/hide the close button | | closeDelay | number | 5 | Countdown in seconds before close button is active | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Theme scheme | | testID | string | — | Test identifier |


FallbackFullscreenVideoAd

Specifically renders a fullscreen video ad.

Supported Video Players

To keep this library lightweight and avoid native linking conflicts, video players are not bundled directly. Instead, FallbackFullscreenVideoAd dynamically detects and supports the following player libraries if they are installed in the host project:

  • react-native-video
  • expo-video

[!IMPORTANT] You must install either react-native-video or expo-video to use the fullscreen video ad component.

Steps to Use the Fullscreen Video Component:

  1. Install a supported video library: Choose and install one of the supported video players in your host project:
    • React Native CLI (or bare Expo):
      npm install react-native-video
      # or
      yarn add react-native-video
      Note: Ensure the library is properly linked. For modern React Native versions, this is done automatically. If you're on an older version, run pod install inside the ios directory.
    • Expo Managed Workflow:
      npx expo install expo-video
  2. Import the component:
    import { FallbackFullscreenVideoAd } from 'react-native-fallback-ads';
  3. Provide Video Sources: Pass local requires (e.g., require('./assets/ad.mp4')) or remote source objects (e.g., { uri: 'https://example.com/ad.mp4' }) to portraitVideo and landscapeVideo props.
  4. Orientation Lock Behavior: To prevent visual glitches and layout shifts, the component locks its orientation to whichever mode (portrait or landscape) the device is in when the video begins playing. Rotating the phone during playback scales the video but does not switch the active source or reset playback progress.
import { FallbackFullscreenVideoAd } from 'react-native-fallback-ads';

<FallbackFullscreenVideoAd
  visible={visible}
  portraitVideo={require('./assets/video-portrait.mp4')}
  landscapeVideo={require('./assets/video-landscape.mp4')}
  onDismiss={() => setVisible(false)}
  closeDelay={5}
/>

Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | visible | boolean | true | Controls modal visibility | | portraitVideo | any | — | Portrait video source (require or URI object) | | landscapeVideo | any | — | Landscape video source. Falls back to portraitVideo | | onDismiss | () => void | — | Called when the close button is pressed | | link | string | — | Destination URL when the ad is tapped | | onPress | (resolvedUrl: string) => void | — | Callback after the link is successfully opened | | onError | (err: { type: 'NO_LINK' \| 'LINK_FAILED' \| 'NO_VIDEO'; message?: string }) => void | — | Callback on link or video loading/playback errors | | showCloseButton | boolean | true | Show/hide the close button | | closeDelay | number | 5 | Countdown in seconds before close button is active | | theme | 'light' \| 'dark' \| 'auto' | 'auto' | Theme scheme | | forceWatchToEnd | boolean | false | If true, countdown doesn't run and the close button is hidden until the video ends or parent dismisses the ad | | onVideoEnd | () => void | — | Callback when the video finishes playing | | onCountdownEnd | () => void | — | Callback when the close delay countdown reaches 0 | | closeButtonAccessory | React.ReactNode | — | Optional React node to render next to the close button (e.g. badges) | | testID | string | — | Test identifier |


FallbackRewardedVideoAd

A specialized wrapper around FallbackFullscreenVideoAd tailored for rewarded ad placements. It provides reward hooks and supports two modes of interaction.

Rewarded Behavior and Modes:

  • Watch to End Mode (Default - no closeDelay provided): The user must watch the video until completion to earn the reward. The close button is hidden during playback, and once the video finishes, onReward is triggered and the ad automatically closes.
  • Countdown Mode (with closeDelay provided, e.g. closeDelay={15}): A countdown is shown. When the countdown completes, a green "Rewarded" badge appears next to the close button, indicating they can now close the ad to claim their reward. The ad remains open until the user taps the close button, at which point the onReward callback is triggered.
import { FallbackRewardedVideoAd } from 'react-native-fallback-ads';

<FallbackRewardedVideoAd
  visible={visible}
  portraitVideo={require('./assets/rewarded-portrait.mp4')}
  onReward={() => console.log('User rewarded!')}
  onDismiss={() => setVisible(false)}
/>

Props

Inherits all props from FallbackFullscreenVideoAdProps except onVideoEnd, onCountdownEnd, forceWatchToEnd, and closeButtonAccessory.

| Prop | Type | Default | Description | |------|------|---------|-------------| | onReward | () => void | — | Callback triggered when the reward condition is met | | onDismiss | () => void | — | Callback when the ad is closed (either automatically after completion or manually after countdown) | | closeDelay | number | — | If provided, allows closing after this many seconds to get reward. If omitted, forces watching to completion |


Utilities

resolveLink

A standalone helper that picks the right URL for the current platform. Useful if you want to open the link manually.

import { resolveLink } from 'react-native-fallback-ads';

const url = resolveLink(
  'market://details?id=com.example.app', // androidLink
  'https://apps.apple.com/app/id123',    // iosLink
  'https://example.com',                  // commonLink (fallback)
);

// Returns:
//   Android → 'market://details?id=com.example.app'
//   iOS     → 'https://apps.apple.com/app/id123'
//   Other   → 'https://example.com'
//   No match → null

Link Resolution

You can use React Native's Platform.select directly in the link prop to provide platform-specific URLs, or you can use our included resolveLink helper manually if needed.


Error Handling

All ad components accept an onError callback that receives one of the following error objects:

type AdError =
  | { type: 'NO_LINK';    message?: string }  // No link provided for this platform
  | { type: 'LINK_FAILED'; message?: string } // Linking.openURL failed
  | { type: 'NO_IMAGE';   message?: string }  // Image failed to load
  | { type: 'NO_VIDEO';   message?: string }  // Video failed to load

Theme Support

All components accept a theme prop:

| Value | Behaviour | |-------|-----------| | 'auto' (default) | Follows the device's system color scheme via useColorScheme() | | 'light' | Forces light theme | | 'dark' | Forces dark theme |


TypeScript

All props interfaces and utility types are exported from the package root:

import type {
  // Component props
  FallbackBannerAdProps,
  FallbackBannerAdRef,
  FallbackTextBannerAdProps,
  FallbackImageBannerAdProps,
  FallbackMrecAdProps,
  FallbackFullscreenAdProps,
  FallbackFullscreenImageAdProps,
  FallbackFullscreenVideoAdProps,
  FallbackRewardedVideoAdProps,

  // Data types
  BannerAdItem,
  BannerAdTextData,
  BannerAdImageData,
} from 'react-native-fallback-ads';

Requirements

| Dependency | Minimum version | |------------|----------------| | react | >= 19.2.0 | | react-native | >= 0.83.0 |

Works with Expo SDK 52+ (managed & bare workflow) and plain React Native CLI projects.


Support Us

This library is free and open-source. If it saves you time, please consider supporting the developers by checking out our app:

📒 CashBook — Expense Tracker

A simple, privacy-friendly personal finance tracker for Android.

Get it on Google Play

You can show your support in two easy ways:

  1. ⭐ Try our app & share your feedback — we invite you to try our new app. If you like it, please consider leaving a review or providing us feedback directly from the app. It helps the app reach more people and keeps us motivated to maintain this library.

  2. 💎 Purchase the Premium Add-on — unlock extra features inside CashBook and directly fund continued development of open-source tools like this one.

👉 Open CashBook on Google Play

Thank you — every download and review genuinely makes a difference! 🙏


License

MIT © Inocentum Technologies