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

@neko-os/rc-subscription

v0.3.0

Published

Drop-in RevenueCat subscription module for React Native (Expo) apps built with `@neko-os/ui`. Provides a full paywall, subscription gating, and subscription management — with i18n support for 26 languages.

Downloads

342

Readme

neko-rc-subscription

Drop-in RevenueCat subscription module for React Native (Expo) apps built with @neko-os/ui. Provides a full paywall, subscription gating, and subscription management — with i18n support for 26 languages.

Peer Dependencies

  • react-native-purchases (RevenueCat SDK)
  • @neko-os/ui
  • @react-navigation/native
  • react-native-reanimated
  • react-native-safe-area-context
  • i18next
  • dayjs

Configuration

Environment variables (or defaults):

| Variable | Default | Description | |----------|---------|-------------| | EXPO_PUBLIC_RC_API_KEY_IOS | — | RevenueCat API key for iOS | | EXPO_PUBLIC_RC_API_KEY_ANDROID | — | RevenueCat API key for Android | | EXPO_PUBLIC_RC_ENTITLEMENT_ID | premium | RevenueCat entitlement identifier |

Platform-specific API key selected automatically via Platform.OS.

Setup

1. Register locales

Call once at app boot, after i18n is initialized:

import { registerSubscriptionLocales } from 'neko-rc-subscription'

registerSubscriptionLocales(i18n)

2. Wrap your app

import { SubscriptionHandler } from 'neko-rc-subscription'

<SubscriptionHandler
  paywallConfig={{
    title: 'Unlock Full Access',
    subtitle: 'Track your habits without limits',
    image: require('./assets/paywall-hero.png'),
    features: [
      { label: 'paywall.unlimitedGoals', icon: 'flag-fill', free: false },
      { label: 'paywall.analytics', icon: 'bar-chart-fill', free: false },
      { label: 'paywall.basicTracking', icon: 'check-line', free: true },
    ],
  }}
>
  <App />
</SubscriptionHandler>

3. Add routes

import { ActiveSubscriptionView } from 'neko-rc-subscription'

// Stack navigator
<Stack.Screen name="subscription/active" component={ActiveSubscriptionView} />

Exports

Components

| Export | Description | |--------|-------------| | SubscriptionHandler | Context provider. Configures RevenueCat, fetches offerings and customer info, provides subscription state to the tree. | | SubscriptionRequired | Gate component. Shows children if subscribed, otherwise renders the Paywall. | | SubscriptionRequiredCTA | Soft gate. Renders children with a blurred overlay and "Unlock" button when not subscribed. | | Paywall | Full paywall screen with hero image, feature comparison, plan selection, purchase and restore. | | ActiveSubscriptionView | Subscription management screen showing plan details and expiry. |

Hooks

| Export | Description | |--------|-------------| | useSubscription() | Full subscription context: { isSubscribed, isLoading, customerInfo, offerings, paywallConfig, refresh } | | useIsSubscribed() | Shorthand boolean — true when active entitlement exists. | | useSubscribedAction(fn?) | Returns an action wrapper that runs fn when subscribed, otherwise opens the paywall. See Gating an action. |

Functions

| Export | Description | |--------|-------------| | registerSubscriptionLocales(i18n) | Registers the subscription namespace into an existing i18next instance for all 26 supported languages. |

SubscriptionHandler Props

| Prop | Type | Description | |------|------|-------------| | paywallConfig | object | Optional paywall customization (see below). |

paywallConfig

| Key | Type | Description | |-----|------|-------------| | title | string | Hero title. Falls back to t('paywall.title'). | | subtitle | string | Hero subtitle. Falls back to t('paywall.subtitle'). | | image | ImageSource | Hero image (parallax). Omit for text-only hero. | | features | Feature[] | Feature comparison rows. Each: { label, icon?, free? }. label is a i18n key. free marks whether available on the free plan. |

SubscriptionRequired Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | disabled | bool | false | Bypass the gate (always show children). | | modal | bool | — | Paywall rendered as modal (close icon instead of back arrow). | | showReturn | bool | — | Show return icon on the paywall. | | footerPaddingB | number | — | Override footer bottom padding. |

SubscriptionRequiredCTA Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | disabled | bool | false | Bypass the gate. | | size | string | 'xs' | Button size. | | buttonProps | object | — | Extra props forwarded to the unlock Button. |

Gating an action

useSubscribedAction wraps any callback so it only fires for subscribed users — otherwise the paywall opens (navigates to subscription/active). Use it for one-off actions that don't warrant a full gate component (SubscriptionRequired / SubscriptionRequiredCTA).

Two equivalent call styles:

import { useSubscribedAction } from 'neko-rc-subscription'

// Bind the fn up front
function ExportButton() {
  const exportData = useSubscribedAction(() => doExport())
  return <Button label="Export" onPress={exportData} />
}

// Bind nothing — pass the fn at call time (handy when the callback varies)
function Row({ item }) {
  const run = useSubscribedAction()
  return <Button label="Pin" onPress={() => run(() => pin(item))} />
}

While subscription state is still loading (isLoading), the action is a no-op — it neither runs the fn nor opens the paywall, so an already-subscribed user is never bounced to the paywall during init.

Arguments are forwarded to the wrapped fn, and its return value is passed through (or undefined when the paywall is shown instead):

const save = useSubscribedAction(saveReport)
save(reportId)            // -> saveReport(reportId) when subscribed

Package Support

The paywall auto-renders available packages from the current RevenueCat offering. Supported package types:

  • Annual — shows per-month price and save percentage vs monthly
  • Monthly — base reference price
  • Lifetime — one-time purchase

Free trial detection is automatic from introPrice metadata.

i18n

Namespace: subscription

26 languages: cs, da, de, el, en, es, fi, fr, hi, hu, id, it, ja, ko, nl, no, pl, pt, ro, ru, sv, th, tr, uk, vi, zh.

Translation keys are organized under settings, paywall, cta, and active groups. See locales/en.js for the full key reference.