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

@pyrx/synapse-react-native

v0.3.0

Published

PYRX Synapse SDK — React Native wrapper for events, identity, push, in-app messaging, and privacy controls (iOS + Android). Thin TurboModule bridge around the published PYRXSynapse (iOS) and tech.pyrx.synapse:synapse-{core,push,inapp} (Android) native SDK

Readme

@pyrx/synapse-react-native

PYRX Synapse SDK for React Native. Events, identity, push notifications, in-app messaging, and privacy controls — for iOS and Android, with a unified TypeScript surface and React hooks.

This package is a thin TurboModule wrapper around the published native SDKs:

The RN package owns the JS bridge, the React ergonomics (hooks, provider, typed errors), the Expo config plugin, and the documentation. The event queue, network layer, identity manager, privacy cascade, and push registration all live in the native SDKs — so the RN package inherits every native-SDK bug fix and tuning automatically.

| Concern | Where it lives | |---|---| | Public TS API | @pyrx/synapse-react-native (this package) | | iOS native code (queue, network, push) | PYRXSynapse Pod | | Android native code (queue, network, push) | tech.pyrx.synapse:synapse-* AARs | | Backend (events, push delivery) | synapse-events.pyrx.tech |


✨ What's new in 0.3.0 (2026-07-01)

In-app messaging lands. The cross-SDK symmetric Synapse.inApp.* namespace + three new React hooks (useInAppMessage, useInAppMessageReceived, useInAppMessageDismissed) wire the host app into the in-app delivery surface that shipped in PYRXSynapse 0.2.0 (iOS) and tech.pyrx.synapse:synapse-{core,inapp}:0.2.0 (Android).

The SDK hands you typed InAppMessage data; your host app renders it via a controlled <Modal> / <View> per your design system. The SDK does NOT render — PYRX UI Kit pre-built components are deferred to a later release.

useInAppMessage('home_banner', (msg) => setActiveMessage(msg));
// later, on dismiss:
Synapse.inApp.dismiss(activeMessage.id, 'user_dismissed');
// when a CTA is tapped:
Synapse.inApp.markInteracted(activeMessage.id, cta.id);

See docs/IN-APP.md for the full integration guide and CHANGELOG.md for the complete 0.3.0 changelog.

What's new in 0.2.0 (2026-06-27)

The three push-event hooks that were stubbed in 0.1.x — usePushReceived, usePushClicked, useDeepLinknow fire against the just-shipped observer surfaces in PYRXSynapse 0.1.2 (iOS) and tech.pyrx.synapse:synapse-{core,push}:0.1.4 (Android).

Two new hooks join them:

  • usePushReceivedColdStart(callback) — fires when the OS launched the app from a notification tap. Distinct from useDeepLink because cold-start routing often needs to wait for navigation to mount, and the native SDKs replay-buffer up to 4 most-recent events so late JS subscribers still catch it. Mutually exclusive with usePushClicked for the same tap (the native SDKs dedup by push_log_id over a 5-second window).

  • useIdentityChanged(callback) — fires when the SDK's resolved identity transitions via identify, alias, or logout. Carries { before, after } snapshots so dashboard-style apps can refetch user data on login state change without polling useIdentify in a useEffect.

See CHANGELOG.md for the full 0.2.0 changelog. Cross-link to the native SDK observer-API docs:

Supported platforms

  • React Native 0.76+ (New Architecture only — TurboModules)
  • Expo SDK 52+ (Expo Dev Build only — Expo Go is not supported because this package ships native modules)
  • iOS 14.0+
  • Android API 24+ (Android 7.0 Nougat and up)

Bare React Native and Expo Dev Build are both supported. For RN Web, use @pyrx/synapse-browser directly — this package targets native iOS and Android only.


Install

Expo Dev Build (recommended for new apps)

# In your Expo app
npx expo install @pyrx/synapse-react-native

Then add the config plugin to your app.json / app.config.ts:

{
  "expo": {
    "plugins": [
      [
        "@pyrx/synapse-react-native",
        {
          "iosMode": "development",
          "androidPostNotificationsPermission": true
        }
      ]
    ]
  }
}

Plugin options:

| Option | Default | What it does | |---|---|---| | iosMode | "development" | Sets the aps-environment entitlement. Use "production" for App Store / TestFlight builds; "development" for simulator and Ad Hoc / EAS development builds. | | androidPostNotificationsPermission | true | Adds <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> to your Android manifest. Required to show push on Android 13+. Set to false only if another plugin already adds it. |

Then prebuild and run a dev build:

npx expo prebuild --clean
eas build --profile development --platform ios
eas build --profile development --platform android

Install the resulting build on a device or simulator and start the dev server with npx expo start --dev-client.

Bare React Native (existing apps without Expo)

npm install @pyrx/synapse-react-native
cd ios && pod install

Then make the two native edits documented in docs/INSTALL-BARE.md:

  • iOS: change your AppDelegate.swift (or .mm) inheritance to PyrxSynapseAppDelegate. Add the aps-environment entitlement and UIBackgroundModes: [remote-notification] to your Info.plist.
  • Android: add POST_NOTIFICATIONS to your AndroidManifest.xml. No service registration needed — the synapse-push AAR's manifest declares PyrxMessagingService and Android's manifest merger picks it up.

For both paths, you also need:


Quick start

// App.tsx
import { SynapseProvider } from '@pyrx/synapse-react-native';
import Home from './src/Home';

export default function App() {
  return (
    <SynapseProvider
      config={{
        workspaceId: process.env.EXPO_PUBLIC_PYRX_WORKSPACE_ID!,
        apiKey: process.env.EXPO_PUBLIC_PYRX_API_KEY!, // psk_live_xxx or psk_test_xxx
        environment: 'production', // 'production' | 'sandbox'
        logLevel: 'info',
        // baseUrl: 'https://synapse-events.pyrx.tech', // optional; defaults to PYRX prod
      }}
    >
      <Home />
    </SynapseProvider>
  );
}
// src/Home.tsx
import { Button, View } from 'react-native';
import {
  useSynapse,
  useIdentify,
  usePushPermission,
  useDeepLink,
} from '@pyrx/synapse-react-native';

export default function Home() {
  const { isInitialized, track } = useSynapse();
  const { identify, isIdentified } = useIdentify();
  const { status: pushStatus, request } = usePushPermission();
  const { lastPushClick } = useDeepLink();

  // Route deep links to your navigator. The SDK does NOT auto-route —
  // see "React Navigation deep-link integration" below for the recipe.

  return (
    <View>
      <Button
        title="Identify"
        disabled={!isInitialized || isIdentified}
        onPress={() => identify('user-123', { email: '[email protected]' })}
      />
      <Button
        title="Track event"
        disabled={!isInitialized}
        onPress={() => track('home.viewed', { plan: 'starter' })}
      />
      <Button
        title={`Enable push (${pushStatus})`}
        onPress={() => request({ alert: true, sound: true, badge: true })}
      />
    </View>
  );
}

That's it. Once request() returns 'granted', the SDK registers the device with synapse-events.pyrx.tech and pushes you send from the PYRX dashboard land on the device.


React Navigation deep-link integration

The useDeepLink() hook surfaces the latest pyrx:push:click payload. The SDK does NOT auto-call Linking.openURL — you decide how to route.

import { Linking } from 'react-native';
import { useEffect } from 'react';
import { useDeepLink } from '@pyrx/synapse-react-native';

function NavigationRoot() {
  const { lastPushClick, clear } = useDeepLink();

  useEffect(() => {
    if (lastPushClick?.deepLink) {
      // React Navigation's Linking config picks this up if your
      // <NavigationContainer linking={{ prefixes, config }} /> is wired.
      Linking.openURL(lastPushClick.deepLink);
      clear(); // Prevent re-firing on re-render
    }
  }, [lastPushClick, clear]);

  return <Stack.Navigator>{/* ... */}</Stack.Navigator>;
}

API reference

| What | Where | |---|---| | Hooks (full signatures and examples) | docs/HOOKS.md | | Event emitter payloads | docs/EVENTS.md | | Full Synapse namespace reference | docs/API.md | | Bare-RN install + manual AppDelegate fallback | docs/INSTALL-BARE.md | | Migrating from the native iOS / Android SDKs | docs/MIGRATING-FROM-NATIVE.md | | Future migration notes | docs/MIGRATION.md | | Sample app | examples/SynapseRNDemo/ |


Sample app

A fully-working Expo Dev Build sample app lives in examples/SynapseRNDemo/. It demonstrates:

  • Initializing the SDK via <SynapseProvider>
  • Identifying a user
  • Tracking an event
  • Requesting push permission
  • Registering for push and displaying the resulting device ID
  • Receiving a foreground push and handling a tap

Run it:

cd examples/SynapseRNDemo
npm install
# Configure your workspace credentials in .env, then:
eas build --profile development --platform ios     # or android
# Install the resulting build, then:
npx expo start --dev-client

Send a push to the device from the PYRX dashboard's push composer and you'll see the receipt logged in-app plus the click logged in the dashboard's push logs.


Troubleshooting

iOS: push permission granted but no token registered

Check that your AppDelegate inherits from PyrxSynapseAppDelegate. If you're on bare RN with a custom AppDelegate parent class, use the manual forwarding pattern in docs/INSTALL-BARE.md.

Verify in the Xcode console that application:didRegisterForRemoteNotificationsWithDeviceToken: is being called. If it isn't, your build is missing the aps-environment entitlement — re-run expo prebuild or check your ios/App.entitlements.

iOS: pushes work on TestFlight but not in Xcode dev builds (or vice-versa)

You probably have the wrong aps-environment. Use "development" for Xcode and EAS development profiles; use "production" for App Store and TestFlight. Pass the value via the plugin option:

[
  "@pyrx/synapse-react-native",
  { "iosMode": "production" }
]

Android: device registers but no push lands

Verify google-services.json is at your Android app's root (or referenced from app.json via android.googleServicesFile). Verify the Firebase project ID in that file matches what the PYRX dashboard shows for your workspace. Verify POST_NOTIFICATIONS is granted at runtime — the SDK does not auto-request it; your app must call PermissionsAndroid.request on Android 13+ before pushes will display.

"The package doesn't seem to be linked"

Run npx expo prebuild --clean, then rebuild via EAS. If you're on bare RN, run cd ios && pod install and verify PyrxSynapseRN appears in your Podfile.lock.

Plugin failed during expo prebuild with "Could not find a recognized AppDelegate parent class"

Your app's AppDelegate.swift / .mm extends a custom parent class that isn't RCTAppDelegate or ExpoAppDelegate. The plugin won't try to guess — use the bare-install path documented in docs/INSTALL-BARE.md, which includes a 5-method-forwarding fallback.


License

MIT. See LICENSE.


Contributing

This package is part of the PYRX ecosystem. See CONTRIBUTING.md for development workflow, CODE_OF_CONDUCT.md, and our pull-request guidelines. The native SDKs live in separate repos: