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

@swaarm/swaarm-sdk

v2.1.0

Published

Swaarm SDK for React Native

Downloads

8,872

Readme

Swaarm SDK for React Native

The Swaarm SDK for React Native allows for better measurement and tracking of user journeys and activities in apps that use the React Native framework.

Installation

Add the SDK and its peer dependencies to your package.json:

"@swaarm/swaarm-sdk": "^2.1.0",
"@react-native-async-storage/async-storage": "^1.19.1",
"react-native-device-info": "^10.8.0",

If you are already using @react-native-async-storage/async-storage or react-native-device-info in your project, keep your existing versions.

Optional native identifiers

The SDK does not require() identifier packages itself — Metro resolves imports at bundle time, so hiding a require inside a try/catch is not reliable. Instead, install the packages in your host app and pass the modules through init's nativeModules option. That way Metro sees the imports and the SDK simply reads whatever you hand it.

App Set ID (Android vendor id):

npm install react-native-app-set-id

Without this package, the SDK falls back to getUniqueId() (SSAID) on Android. On iOS it always uses identifierForVendor, which needs no extra package.

IDFA / GAID (advertising id):

npm install react-native-idfa-aaid

Without this package, advertisingId is reported as null in every event.

Apple Search Ads attribution (iOS only, optional):

If you run Apple Search Ads campaigns and want install attribution forwarded to Swaarm, supply a native module that exposes the AdServices attribution token (iOS 14.3+). The token cannot be obtained from JavaScript directly — it requires a thin native bridge over Apple's AAAttribution.attributionToken() API.

Two module shapes are supported:

  1. { getAttributionToken(): Promise<string> } (preferred — the SDK then exchanges the token with https://api-adservices.apple.com/api/v1/ and parses the response).
  2. { getAttributionData(): Promise<object> } for packages that already perform the API exchange and return the parsed response object.

Pass the module via nativeModules.adServicesAttribution:

import AppleAdsAttribution from "react-native-apple-ads-attribution"; // or your own bridge

SwaarmClient.init("example.swaarm.com", "<token>", {
    nativeModules: {
        adServicesAttribution: AppleAdsAttribution,
    },
});

The check runs at most once per install (gated by an AsyncStorage flag). On a successful attribution the install event carries installReferrer.referrer as a UTM string of the form utm_source=appleads&utm_campaign=…&utm_adgroup=…&utm_adid=…&utm_keyword=… plus a unix-seconds clickTimestamp. If the install was not attributed to a campaign, installReferrer is omitted.

Companies that do not use Apple Search Ads can simply omit this module — the SDK skips the check entirely and never contacts Apple's servers.

iOS: App Tracking Transparency

On iOS 14.5+ you must request App Tracking Transparency permission from the user before the OS returns a real IDFA; otherwise it returns the zero UUID (00000000-0000-0000-0000-000000000000), which the SDK detects and reports as null. Request ATT from your app (for example via react-native-tracking-transparency) before calling SwaarmClient.init(...), or re-initialize the SDK after the user grants permission.

Remember to add NSUserTrackingUsageDescription to your Info.plist.

Android: ad id permission

On Android 13+ apps that read GAID must declare:

<uses-permission android:name="com.google.android.gms.permission.AD_ID" />

in AndroidManifest.xml.

Install the dependencies:

npm install

iOS

npx pod-install

Android

Make sure the following permission is present in your AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />

Add the Google Play install referrer dependency to your app's build.gradle:

implementation 'com.android.installreferrer:installreferrer:2.2'

allprojects {
    repositories {
        maven { url "https://maven.google.com" }
    }
}

If you are using Proguard, also add:

-keep public class com.android.installreferrer.** { *; }

Configuration

Import the client:

import {SwaarmClient} from "@swaarm/swaarm-sdk";

Initialize the SDK as early as possible in your app (for example in your root component's useEffect). Replace example.swaarm.com with your Swaarm tracking domain and <token> with your app token.

SwaarmClient.init("example.swaarm.com", "<token>");

Enable debug logging during development:

SwaarmClient.init("example.swaarm.com", "<token>", {debug: true});

You can also toggle debug logs dynamically at any point:

SwaarmClient.log(true);

Initialization options

SwaarmClient.init(domain, token, options) accepts the following options:

  • flushFrequency (number, default 2): how often, in seconds, queued events are sent to Swaarm.
  • debug (boolean, default false): enables verbose SDK logging.
  • attributionCallback ((data: AttributionData) => void, default null): invoked once valid attribution data is received.
  • deferredDeepLinkCallback ((route: string) => void, default null): invoked on the first app run with the deferred deep link route, if one was registered.
  • maxQueueSize (number, default 500): maximum number of events kept in the local queue. When full, the oldest event is dropped.
  • nativeModules ({ appSetId?, idfaAaid?, adServicesAttribution? }, default {}): references to the optional react-native-app-set-id, react-native-idfa-aaid, and Apple Search Ads attribution modules (see above).

Example with all the optional identifier modules wired in:

import AppSetID from "react-native-app-set-id";
import ReactNativeIdfaAaid from "react-native-idfa-aaid";

SwaarmClient.init("example.swaarm.com", "<token>", {
    debug: true,
    nativeModules: {
        appSetId: AppSetID,
        idfaAaid: ReactNativeIdfaAaid,
    },
});

Pre-init calls

SwaarmClient.event(...), SwaarmClient.purchase(...) and SwaarmClient.onAttribution(...) are safe to call before init() resolves. Events captured before init are buffered in memory with their original timestamps and replayed into the queue as soon as init completes.

Automatic event tracking

The SDK automatically tracks:

  • Install — fires the first time the app is launched after installation, and includes the Google Play install referrer when available.
  • App open (__open) — fires on every SDK initialization.

These events are enriched with device information: OS version, vendor id, and advertising id when available.

Custom events

Recording a generic event

SwaarmClient.event("registration", 25.0, JSON.stringify({email: "[email protected]"}));

Parameters:

  • typeId — the Swaarm event type id (configured under App → Events).
  • aggregatedValue — a numeric value Swaarm aggregates in reports (coins earned, items purchased, etc.).
  • customValue — a free-form string displayed as-is in reports. JSON is recommended.

Recording a purchase

SwaarmClient.purchase(
    "subscription",
    11.0,
    "USD",
    "base64ReceiptOrPurchaseToken",
    "purchaseOrSubscriptionId"
);

Parameters:

  • typeId — the Swaarm event type id for the purchase.
  • revenue — amount of revenue generated.
  • currency — ISO currency code (e.g. "USD").
  • receiptOrToken — optional. On iOS, the App Store receipt; on Android, the Play purchase token.
  • androidPurchaseId — optional. The Play purchase or subscription id, used for validation.

Deferred deep links

The Swaarm SDK can fetch a deferred deep link for the user on their first app launch. To use this, pass a deferredDeepLinkCallback at init time:

SwaarmClient.init("example.swaarm.com", "<token>", {
    deferredDeepLinkCallback: (route) => {
        navigation.navigate(route);
    },
});

The callback is invoked exactly once, on the first run, if the server has a deep link associated with the device.

Attribution data

The Swaarm SDK periodically contacts the server to retrieve attribution data using an exponential backoff, until a decision is returned. You can either register a callback or read the latest attribution data on demand:

SwaarmClient.init("example.swaarm.com", "<token>", {
    attributionCallback: (data) => {
        if (data.decision === "PASSED") {
            console.log("Attributed to", data);
        }
    },
});

// Or, later:
console.log(SwaarmClient.attributionData);

Attribution data is persisted locally, so subsequent app launches can read it synchronously via SwaarmClient.attributionData as soon as the SDK has finished initializing.

AttributionData schema

+-----------------------------------------------------+
|   AttributionData                                   |
+-----------------------------------------------------+
| - offer: AttributionOffer?                          |
| - publisher: AttributionPublisher?                  |
| - ids: Ids?                                         |
| - decision: PostbackDecision?                       |
| - googleInstallReferrer: GoogleInstallReferrerData? |
+-----------------------------------------------------+
        |
        |------------------> +-------------------------+
                             |   AttributionOffer      |
                             +-------------------------+
                             | - id: String?           |
                             | - name: String?         |
                             | - lpId: String?         |
                             | - campaignId: String?   |
                             | - campaignName: String? |
                             | - adGroupId: String?    |
                             | - adGroupName: String?  |
                             | - adId: String?         |
                             | - adName: String?       |
                             +-------------------------+

        |------------------> +-----------------------+
                             |  AttributionPublisher |
                             +-----------------------+
                             | - id: String?         |
                             | - name: String?       |
                             | - subId: String?      |
                             | - subSubId: String?   |
                             | - site: String?       |
                             | - placement: String?  |
                             | - creative: String?   |
                             | - app: String?        |
                             | - appId: String?      |
                             | - unique1: String?    |
                             | - unique2: String?    |
                             | - unique3: String?    |
                             | - groupId: String?    |
                             +-----------------------+

        |------------------> +----------------------+
                             |       Ids            |
                             +----------------------+
                             | - installId: String? |
                             | - clickId: String?   |
                             | - userId: String?    |
                             +----------------------+

        |------------------> +-----------------------+
                             |   PostbackDecision    |
                             +-----------------------+
                             | - PASSED              |
                             | - FAILED              |
                             +-----------------------+

        |------------------> +----------------------------------+
                             | GoogleInstallReferrerData        |
                             +----------------------------------+
                             | - gclid: String?                 |
                             | - gbraid: String?                |
                             | - gadSource: String?             |
                             | - wbraid: String?                |
                             +----------------------------------+

Reliability

Event queue persistence

Queued events are persisted to AsyncStorage under __SWAARM_EVENT_QUEUE after every enqueue and every successful flush. If the app is killed or crashes before a flush completes, the queue is restored on the next launch and re-sent. The queue is capped at maxQueueSize (default 500); when full, the oldest event is dropped to make room.

A batch is only dropped from the queue when the server returns a 2xx response. Network errors and non-2xx responses leave the batch in place so the next flush cycle retries it.

App lifecycle

The SDK subscribes to AppState and behaves as follows:

  • On background: the flush and attribution timers are cleared and one final best-effort flush is fired.
  • On foreground: the flush interval is restarted and attribution polling resumes.

Clock-drift correction (always UTC)

The device clock can be skewed (user-set wrong time, timezone tricks, etc.). The SDK measures the offset between the device and the server on every SDK response using the HTTP Date header, compensates for round-trip latency, and persists the offset under __SWAARM_CLOCK_SKEW_MS. Every event's clientTime is then rendered as UTC via new Date(capturedAt + skew).toISOString() before being sent, so the server always receives UTC timestamps. No server changes or additional endpoints are required.

Stopping the SDK

Call SwaarmClient.stop() to stop the periodic event flush, the attribution polling, and the AppState listener (for example when the user opts out of tracking).