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

@rocapine/rn-referral

v0.1.0

Published

Headless referral engine for React Native / Expo apps: referral codes, reward ladder, RevenueCat attribution — pure shared core, injected-seam client, Supabase backend templates.

Readme

@rocapine/rn-referral

Headless referral engine for React Native / Expo apps: deterministic referral codes, a configurable reward ladder, and RevenueCat-attributed conversions — the package owns the domain logic and wire protocol, you own the UI, storage, and analytics. Ships with Supabase backend templates so a new app can go from npx rn-referral init to a working referral loop without hand-writing the attribution math.

Install

npm install @rocapine/rn-referral

The only peer dependency is react. It's designed for React Native apps, but react-native itself is not a peer dependency. The ./core subpath has no peer dependencies and works outside React Native too (e.g. from the Supabase Edge Function, via Deno's npm: specifier).

Quick start

import { createReferralClient, useReferral } from "@rocapine/rn-referral";

const referralClient = createReferralClient({
  ladder: [{ id: "first", threshold: 1, type: "collectible" }],
  linkBase: "https://<your-domain>",
  transport: (action, payload) => myBackend.invoke("referral-engine", payload),
  storage: myAsyncStorageSeam,
  subscription: myRevenueCatSeam,
});
function ReferralScreen() {
  const { state, rewards, nextReward, refresh, acknowledge } =
    useReferral(referralClient);
  // render state.code, rewards[].isUnlocked, nextReward, ...
}

See docs/integration.md for the full seam-by-seam wiring example (Supabase transport, AsyncStorage storage, RevenueCat subscription), deep link configuration, and the EAS/Detour gotchas.

Backend setup

npx rn-referral init

Copies the Supabase Edge Function + SQL migration templates into your app repo. Edit ladder.config.ts, supabase db push, deploy, and wire the RevenueCat webhook — the full walkthrough is in docs/integration.md.

Architecture

./core is pure, isomorphic TypeScript — no React, no RN, no I/O. It's imported by both the RN client (.) and the Supabase Edge Function (via Deno's npm:@rocapine/rn-referral/core), so the code format and attribution math can never drift between client and server.

The main entry (.) is CJS-only, deliberately — an ESM build breaks Metro's lazy require() calls at runtime (the same lesson learned shipping @rocapine/rn-social-share). Don't add an ESM output without re-verifying that.

Events

onEvent receives typed events; the package never logs analytics itself — map these to your own analytics names.

| Event | Payload | Fires when | | --------------------- | ----------------------- | -------------------------------------------- | | state_synced | { refereesConverted } | Server read-through succeeds in getState() | | redeem_attempted | { code, ok } | redeemCode() resolves (valid or not) | | reward_acknowledged | { rewardId } | acknowledgeReward() is called |

Link formats

The canonical format for new apps is query-style, one static landing page per site: ${linkBase}/referral?code=${code} (the buildReferralLink default). Override it with formatLink(base, code) in createReferralClient if you need a different shape (e.g. an app with live links already in the wild using /invite/${code}).

parseReferralCode(url) (from @rocapine/rn-referral/core) is the tolerant counterpart — it accepts the canonical ?code= query and the legacy /invite/{code} / /referral/{code} path segments, on full URLs or bare paths, so old and new links all resolve.