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

@freshpaint/freshpaint-react-native

v0.4.0

Published

The Freshpaint react native integration.

Downloads

2,985

Readme

Freshpaint React Native SDK

Comprehensive analytics tracking SDK for React Native applications with advanced attribution, autotracking, and privacy features.

Documentation: Freshpaint React Native SDK Reference

Table of Contents

Installation

npm install @freshpaint/freshpaint-react-native
# or
yarn add @freshpaint/freshpaint-react-native

iOS Setup

cd ios && pod install

Add to your Info.plist if requesting ATT:

<key>NSUserTrackingUsageDescription</key>
<string>This app would like to track your activity for personalized ads and analytics.</string>

Android Setup

No additional setup required. The SDK automatically links native modules.

Quick Start

import Freshpaint from '@freshpaint/freshpaint-react-native';

// Initialize the SDK
Freshpaint.init('YOUR_API_KEY', {
  autoRequestATT: true, // Automatically request ATT on iOS (optional)
});

// Track an event
Freshpaint.track('Product Viewed', {
  product_id: '123',
  product_name: 'Premium Widget',
  price: 29.99,
});

// Identify a user
Freshpaint.identify('user_123', {
  email: '[email protected]',
  plan: 'premium',
});

Core Features

Event Tracking

Track custom events with optional properties:

Freshpaint.track('Button Clicked', {
  button_name: 'Sign Up',
  screen: 'Home',
});

Integration Options

Send events to specific destinations:

Freshpaint.track(
  'Purchase Completed',
  {
    total: 99.99,
    items: 3,
  },
  {
    integrations: {
      'Google Analytics': true,
      Mixpanel: false,
    },
  },
);

User Identification

Associate events with a specific user:

// Identify with user ID and properties
Freshpaint.identify('user_123', {
  email: '[email protected]',
  name: 'John Doe',
  plan: 'premium',
});

// Update user properties without changing ID
Freshpaint.identify({
  last_login: new Date().toISOString(),
});

Integration Options for Identify

Freshpaint.identify(
  'user_123',
  {
    email: '[email protected]',
  },
  {
    integrations: {
      Salesforce: true,
      Intercom: true,
    },
  },
);

Groups

Associate users with groups (teams, companies, etc.):

// Set group with properties
Freshpaint.group('company_456', {
  name: 'Acme Corp',
  plan: 'enterprise',
  employees: 500,
});

// Update group properties without changing ID
Freshpaint.group({
  subscription_status: 'active',
});

Integration Options for Group

Freshpaint.group(
  'company_456',
  {
    name: 'Acme Corp',
  },
  {
    integrations: {
      Salesforce: true,
    },
  },
);

Custom Properties

Add custom properties to all events:

// Add properties (merged with existing)
Freshpaint.addEventProperties({
  app_version: '2.1.0',
  environment: 'production',
});

// Add properties with lower priority (won't override existing)
Freshpaint.addInitialEventProperties({
  default_currency: 'USD',
});

// Remove a property
Freshpaint.removeEventProperty('environment');

Reset User State

Clear all user data (useful on logout):

Freshpaint.reset();

This clears:

  • User ID
  • User properties
  • Group ID and properties
  • Custom event properties
  • Generates new device ID

MMP Attribution

The SDK provides comprehensive Mobile Measurement Partner (MMP) attribution capabilities with automatic data collection and event tracking.

App First Open

Automatically fires an Application Installed event on the first app launch with complete attribution data.

What's Collected:

Common (iOS & Android):

  • install_timestamp - ISO 8601 timestamp of first open
  • device_id - Freshpaint device identifier
  • persistent_device_id - Survives app uninstall/reinstall
  • os_version - OS version string
  • version - App version from bundle
  • build - App build number
  • user_agent - User agent string
  • UTM parameters (utm_source, utm_medium, utm_campaign, utm_term, utm_content)
  • 35 ad click IDs (see Deep Link Tracking for full list)

iOS:

  • idfv - Identifier for Vendor (always available)
  • advertisingId - Advertising Identifier / IDFA (only if ATT authorized)
  • att_status - ATT authorization status (authorized, denied, restricted, notDetermined)
  • skan_registration_attempted - Boolean indicating SKAdNetwork registration
  • apple_ads_token - Apple Search Ads attribution token (iOS 14.3+, if available)

Android:

  • advertisingId - Google Advertising ID (GAID) - preferred identifier
  • android_id - Android ID (fallback when GAID unavailable)
  • limit_ad_tracking - Boolean indicating ad tracking preference
  • install_referrer - Play Store install referrer string
  • referrer_click_timestamp - Unix timestamp of ad click
  • install_begin_timestamp - Unix timestamp of install start

Google Policy Compliance: The SDK follows Google Play policy by never sending both GAID and android_id in the same request. It prefers GAID and falls back to android_id only when GAID is unavailable.

Example Payload:

{
  event: 'Application Installed',
  properties: {
    custom_props: {
      install_timestamp: '2024-01-15T10:30:00.000Z',
      device_id: 'abc123...',
      persistent_device_id: 'xyz789...',
      os_version: '17.2',
      version: '1.0.0',
      build: '123',
      user_agent: 'MyApp/1.0.0 (iPhone; iOS 17.2)',

      // iOS-specific
      idfv: '12345678-1234-1234-1234-123456789012',
      advertisingId: '87654321-4321-4321-4321-210987654321', // if authorized
      att_status: 'authorized',
      skan_registration_attempted: true,

      // Attribution params (if opened via deep link)
      utm_source: 'facebook',
      utm_campaign: 'summer_sale',
      fbclid: 'abc123',
      gclid: 'xyz456',
    }
  }
}

Deep Link Tracking

Automatically tracks deep link opens with full attribution parsing.

Events:

  • Cold start (app not running): Fires deeplink event with URL and parameters
  • Warm open (app backgrounded): Fires deeplink event on foreground

Supported Attribution Parameters:

UTM Parameters (5):

  • utm_source, utm_medium, utm_campaign, utm_term, utm_content

Ad Network Click IDs (35):

| Network | Parameter(s) | | ------------- | -------------------------------------------------------------------------- | | Google | gclid, dclid, gclsrc, gbraid, wbraid, gacid (→ _campaign_id) | | Facebook | fbclid, fb_ad_id, fb_adset_id, fb_campaign_id | | TikTok | ttclid | | Microsoft | msclkid | | Twitter | twclid, clid_src | | LinkedIn | li_fat_id | | Pinterest | epik | | Reddit | rdt_cid | | Snapchat | ScCid, sccid | | Spotify | spclid | | Quora | qclid | | AppLovin | aleid | | Basis | cntr_auctionId | | Nextdoor | ndclid | | StackAdapt | sapid | | TheTradeDesk | ttdimp | | Viant | viant_clid | | Mailchimp | mc_cid | | Instagram | igshid | | Branch | _branch_match_id | | Adjust | adj_t | | Adobe/Kenshoo | s_kwcid | | Impact Radius | irclickid | | Affiliate | aff_id, affiliate_id |

Development URL Filtering:

The SDK automatically filters out development URLs to prevent false attribution:

  • localhost, 127.0.0.1
  • Private IP ranges: 192.168.*.*, 10.*.*.*, 172.16-31.*.*
  • Expo development client URLs
  • React Native debugger URLs

Example Deep Link Event:

{
  event: 'Deep Link Opened',
  properties: {
    custom_props: {
      url: 'myapp://product/123?utm_source=facebook&fbclid=abc123',
      utm_source: 'facebook',
      fbclid: 'abc123',

      // All current device info is included
      idfv: '...',
      advertisingId: '...',
      att_status: 'authorized',
      app_version: '1.0.0',
      user_agent: '...',
    }
  }
}

ATT (App Tracking Transparency)

Control and monitor iOS App Tracking Transparency permission.

Auto-Request ATT

Request ATT automatically on SDK initialization:

Freshpaint.init('YOUR_API_KEY', {
  autoRequestATT: true, // Show ATT prompt before first open event
});

Flow when autoRequestATT: true:

  1. SDK initializes
  2. ATT permission is requested
  3. User responds (or has previously responded)
  4. Application Installed event fires with current ATT status

When can timestamp be captured?

The SDK can capture the timestamp of when ATT permission was granted only for new requests when autoRequestATT: true.

Cannot capture timestamp when:

  • User already granted permission before SDK installation
  • Host app requests ATT (when autoRequestATT: false)
  • Permission was granted in a previous app version

Manual ATT Control

Request ATT permission programmatically:

// Check current status (doesn't show prompt)
const status = await Freshpaint.getTrackingAuthorizationStatus();
// Returns: 'authorized' | 'denied' | 'restricted' | 'notDetermined'

// Request permission (shows prompt if notDetermined)
const status = await Freshpaint.requestTrackingAuthorization();
// Returns same status values, safe to call multiple times

Getting Advertising Identifier

// Returns Advertising ID (IDFA on iOS, GAID on Android) if authorized/available, null otherwise
const advertisingId = await Freshpaint.getAdvertisingIdentifier();

// Get IDFV (iOS only, always available)
const idfv = await Freshpaint.getIdentifierForVendor();

SKAdNetwork

iOS 11.3+ attribution framework for privacy-preserving ad attribution.

Automatic Registration

The SDK automatically registers with SKAdNetwork on first app launch (called once during Application Installed).

Version Support:

  • iOS 16.1+: Uses updatePostbackConversionValue with coarse conversion values
  • iOS 15.4-16.0: Uses updatePostbackConversionValue (fine-grained only)
  • iOS 11.3-15.3: Uses legacy registerAppForAdNetworkAttribution (deprecated)

Custom Conversion Values

Update conversion values to signal post-install events to ad networks:

// Simple update (iOS 15.4+)
await Freshpaint.updateSKANConversionValue(42);

// Full update with coarse value and lock (iOS 16.1+)
await Freshpaint.updateSKANConversionValue(
  42, // value: 0-63
  'high', // coarseValue: 'low' | 'medium' | 'high'
  true, // lockWindow: prevent further updates
);

Parameters:

  • value (0-63): Fine-grained conversion value
  • coarseValue: iOS 16.1+ only, ignored on older versions
  • lockWindow: iOS 16.1+ only, ignored on older versions

Returns: true if update attempted, false if not supported

Platform-Specific Attribution

iOS Attribution Data

const data = await Freshpaint.getAttributionData();

// Returns:
{
  idfv: '...',                 // Always available
  advertisingId: '...',        // Only if ATT authorized (IDFA)
  att_status: 'authorized',    // ATT status
  version: '1.0.0',
  build: '123',
  user_agent: '...',
  persistent_device_id: '...', // Survives uninstall (Keychain)
  device_id: '...',            // Freshpaint device ID
  is_first_launch: false,      // True only on first app launch

  // Attribution params from deep link (if any)
  utm_source: 'facebook',
  fbclid: '...',
}

Android Attribution Data

const data = await Freshpaint.getAttributionData();

// Returns (with GAID available):
{
  advertisingId: '...',           // Google Advertising ID (GAID) - preferred
  // android_id NOT included when GAID is available (Google policy)
  limit_ad_tracking: false,
  version: '1.0.0',
  build: '123',
  user_agent: '...',
  persistent_device_id: '...',    // Same as advertisingId when GAID available
  device_id: '...',               // Freshpaint device ID
  is_first_launch: false,

  // Play Install Referrer (if available)
  install_referrer: 'utm_source=google&utm_medium=cpc',
  referrer_click_timestamp: 1234567890,
  install_begin_timestamp: 1234567891,

  // Attribution params from deep link (if any)
  utm_source: 'google',
  gclid: '...',
}

// Returns (when GAID unavailable - fallback):
{
  // advertisingId NOT included when unavailable
  android_id: '...',              // Android ID used as fallback
  limit_ad_tracking: false,
  version: '1.0.0',
  build: '123',
  user_agent: '...',
  persistent_device_id: '...',    // Same as android_id when GAID unavailable
  device_id: '...',               // Freshpaint device ID
  is_first_launch: false,
  // ... other fields
}

Play Install Referrer (Android Only)

Get Play Store install referrer data separately:

const referrer = await Freshpaint.getPlayInstallReferrer();

// Returns:
{
  install_referrer: 'utm_source=google&utm_medium=cpc',
  referrer_click_timestamp: 1234567890, // seconds since epoch
  install_begin_timestamp: 1234567891,
}

Features:

  • Cached after first fetch (fast subsequent calls)
  • 5-second timeout if Play Store service doesn't respond
  • Returns empty object if unavailable or on iOS

Autotracking

The SDK provides comprehensive autotracking capabilities for common UI interactions. All autocaptured events are prefixed with $ (except screen_view).

React Navigation

Automatically track screen views:

import { NavigationContainer } from '@react-navigation/native';
import Freshpaint from '@freshpaint/freshpaint-react-native';

const navigationRef = React.createRef();

<NavigationContainer
  ref={navigationRef}
  onReady={() => {
    Freshpaint.withReactNavigationAutotrack(navigationRef);
  }}
>
  {/* Your navigation stack */}
</NavigationContainer>;

Fires screen_view events with screen name and route parameters.

Touchables & Pressables

Wrap components to track presses:

import { TouchableOpacity, Pressable } from 'react-native';
import Freshpaint from '@freshpaint/freshpaint-react-native';

// Higher-Order Components
const FreshpaintTouchable = Freshpaint.withFreshpaintTouchableAutocapture(TouchableOpacity);
const FreshpaintPressable = Freshpaint.withFreshpaintPressableAutocapture(Pressable);

// Usage
<FreshpaintTouchable onPress={handlePress}>
  <Text>Track This Press</Text>
</FreshpaintTouchable>;

Fires $element_clicked events with component metadata.

Text Input

Track text input changes:

const FreshpaintTextInput = Freshpaint.withFreshpaintTextInputAutocapture(TextInput);

<FreshpaintTextInput placeholder="Email" onChangeText={handleChange} />;

Fires $text_input_changed events.

Switches

Track switch toggles:

<Switch
  value={enabled}
  onValueChange={(value) => {
    Freshpaint.autotrackSwitchChange(value, { switch_id: 'notifications' });
    setEnabled(value);
  }}
/>

Scroll Views

Track scrolling:

<ScrollView
  onScroll={(event) => {
    Freshpaint.autocaptureScrollView(event.nativeEvent);
  }}
  scrollEventThrottle={400}
>
  {/* Content */}
</ScrollView>

Ignoring Elements

Prevent specific elements from being tracked:

import { FreshpaintIgnore } from '@freshpaint/freshpaint-react-native';

<FreshpaintIgnore>
  <SensitiveComponent />
</FreshpaintIgnore>;

Advanced Configuration

Initialization Options

Freshpaint.init('YOUR_API_KEY', {
  autoRequestATT: true, // Request ATT on iOS (default: false)
  apiEndpoint: 'custom-endpoint', // Custom API endpoint
  batchEvents: true, // Batch events (default: false)
  eventUploadPeriodMillis: 30000, // Upload interval (default: 30s)
  // ... see full documentation for all options
});

Opt Out

Disable tracking for privacy-conscious users:

// Opt out of tracking
Freshpaint.setOptOut(true);

// Re-enable tracking
Freshpaint.setOptOut(false);

API Reference

Initialization

| Method | Parameters | Description | | -------- | --------------------------------- | ------------------ | | init() | apiKey: string, config?: object | Initialize the SDK |

Event Tracking

| Method | Parameters | Description | | --------- | ------------------------------------------------------ | -------------------- | | track() | event: string, properties?: object, options?: object | Track a custom event |

User Management

| Method | Parameters | Description | | ------------ | --------------------------------------------------------- | ---------------------- | | identify() | userId?: string, properties?: object, options?: object | Identify a user | | group() | groupId?: string, properties?: object, options?: object | Associate with a group | | reset() | - | Clear all user state |

Custom Properties

| Method | Parameters | Description | | ----------------------------- | -------------------- | ---------------------------------- | | addEventProperties() | properties: object | Add properties to all events | | addInitialEventProperties() | properties: object | Add properties with lower priority | | removeEventProperty() | key: string | Remove a custom property |

Attribution

| Method | Returns | Description | | -------------------------- | ----------------- | ----------------------------------- | | getAttributionData() | Promise<object> | Get all attribution data | | getPlayInstallReferrer() | Promise<object> | Get Play Install Referrer (Android) |

ATT (iOS)

| Method | Returns | Description | | ---------------------------------- | ------------------------- | --------------------------------- | | getTrackingAuthorizationStatus() | Promise<string> | Get current ATT status | | requestTrackingAuthorization() | Promise<string> | Request ATT permission | | getAdvertisingIdentifier() | Promise<string \| null> | Get Advertising ID (IDFA on iOS, GAID on Android) | | getIdentifierForVendor() | Promise<string \| null> | Get IDFV (iOS only) |

SKAdNetwork (iOS)

| Method | Parameters | Returns | Description | | ----------------------------- | ----------------------------------------------------------- | ------------------ | ----------------------- | | updateSKANConversionValue() | value: number, coarseValue?: string, lockWindow?: boolean | Promise<boolean> | Update conversion value |

Privacy

| Method | Parameters | Description | | ------------- | ------------------ | ----------------------- | | setOptOut() | enabled: boolean | Enable/disable tracking |

Platform Support

  • iOS: 13.0+
  • Android: API 21+ (Android 5.0+)
  • React Native: 0.70.0+

License

MIT

Support

  • Documentation: https://documentation.freshpaint.io
  • Issues: https://github.com/freshpaint-io/freshpaint-react-native/issues
  • Email: [email protected]