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

@akin-travel/sdk-react-native

v0.1.0

Published

React Native binding for the Akin partner SDK — auth (passkey/magic-link) + loyalty, wrapping @akin-travel/sdk-core with native AsyncStorage, @react-native-firebase/auth, and react-native-passkey adapters

Readme

@akin-travel/sdk-react-native

React Native binding for the Akin partner SDK — passkey/magic-link auth and loyalty (tiers, points, history) for partner mobile apps on iOS and Android from one codebase.

It wraps the framework-agnostic @akin-travel/sdk-core with React Native adapters:

| Concern | sdk-core interface | React Native implementation | |---|---|---| | Persistence | StorageAdapter | @react-native-async-storage/async-storage | | Identity provider | FirebaseAuthClient | @react-native-firebase/auth | | Passkey ceremony | Authenticator | react-native-passkey (iOS ASAuthorization · Android Credential Manager) |

It exposes the same provider + hook API as the web binding (@akin-travel/partner-sdk) — AkinProvider, useAkinAuth, useAkinLoyalty, useSDK — so code is portable between platforms. Parity is enforced at compile time (src/conformance.ts).

Status: pre-1.0 (0.1.0). Part of epic akin-travel/issues#2042. The cross-platform conformance/parity suite and example-app QA matrix are owned by #2049.


Install

npm install @akin-travel/sdk-react-native
# peer dependencies (install the ones your app doesn't already have)
npm install @react-native-firebase/app @react-native-firebase/auth \
            @react-native-async-storage/async-storage \
            react-native-passkey

react-native-passkey is an optional peer — magic-link and Google sign-in work without it; it is only required for the native passkey ceremony.

This is a New-Architecture-compatible library with native dependencies, so it needs a custom dev client / bare workflow (it does not run in Expo Go). With Expo, use a development build (expo prebuild + expo run:ios|android).


Native setup

Firebase (GIP)

@react-native-firebase/auth auto-initialises from the native config files — drop them in and no JS Firebase config is required:

  • iOS: add GoogleService-Info.plist to the Xcode project.
  • Android: add google-services.json to android/app/.

The SDK sets the GIP tenant at runtime from config.gipTenantId.

Passkeys — iOS (ASAuthorization)

  1. Enable the Associated Domains capability in Xcode and add webcredentials:<your-rp-id> (e.g. webcredentials:akintravel.com).
  2. Host the Apple App Site Association file at https://<rp-id>/.well-known/apple-app-site-association with your app's webcredentials entry. Requires iOS 16+.

Passkeys — Android (Credential Manager)

  1. Host a Digital Asset Links file at https://<rp-id>/.well-known/assetlinks.json including your app's signing SHA-256 fingerprint.
  2. Credential Manager passkeys require Android 9+ (API 28+), with the best experience on Android 14+.

The relying-party ID and challenge come from the Akin API (passkeyAuthenticationOptions); the SDK passes them straight to the native ceremony. You do not configure WebAuthn options in app code.


Quickstart

Wrap your app once:

import { AkinProvider } from '@akin-travel/sdk-react-native';

export default function App() {
  return (
    <AkinProvider
      config={{
        partnerId: 'YOUR_PARTNER_ID',
        apiKey: 'YOUR_PARTNER_API_KEY',
        environment: 'staging', // 'production' | 'staging' | 'development'
        gipTenantId: 'YOUR_GIP_TENANT_ID',
        verifyCallbackUrl: 'https://yourapp.com/auth/verify',
      }}
    >
      <RootNavigator />
    </AkinProvider>
  );
}

Use the hooks anywhere beneath it:

import { View, Text, Button } from 'react-native';
import { useAkinAuth, useAkinLoyalty } from '@akin-travel/sdk-react-native';

function MemberScreen() {
  const { member, isAuthenticated, signInWithPasskey, requestMagicLink, signOut } =
    useAkinAuth();
  const { tier, points, tierProgress } = useAkinLoyalty();

  if (!isAuthenticated) {
    return (
      <View>
        <Button title="Sign in with passkey" onPress={signInWithPasskey} />
        <Button title="Email me a magic link" onPress={() => requestMagicLink('[email protected]')} />
      </View>
    );
  }

  return (
    <View>
      <Text>Welcome, {member?.firstName}</Text>
      <Text>{points} points · Tier {tier}</Text>
      {tierProgress && <Text>{Math.round(tierProgress.progressPercentage)}% to next tier</Text>}
      <Button title="Sign out" onPress={signOut} />
    </View>
  );
}

Magic-link verification

The magic-link email opens your verifyCallbackUrl. Capture the token from the deep link and complete sign-in:

const { verifyMagicLink } = useAkinAuth();
const { success, isNewUser } = await verifyMagicLink(tokenFromDeepLink);

API

useAkinAuth()

State: user, member, isAuthenticated, isLoading, error. Actions: signIn, signUp, signUpPasswordless, requestMagicLink, verifyMagicLink, signInWithPasskey, signOut, resetPassword, refreshMemberData, clearError.

useAkinLoyalty()

State: points, akinPoints, tier, tierConfigs, tierConfig, tierProgress, transactions, tierHistory, upcomingStays, previousStays, membershipYearStats, lifetimeStats, tierBenefits, isLoading, error. Actions: refreshData, getTransactionHistory, getTierHistory.

useSDK()

config, plus the live adapters (storage, authenticator, firebaseAuthClient) for advanced use.

Custom adapters

The provider builds the default native adapters automatically. To inject your own (e.g. a Keychain/Keystore-backed StorageAdapter, or for testing):

import {
  AkinProvider,
  createAsyncStorageAdapter,
  createReactNativeFirebaseAuthClient,
} from '@akin-travel/sdk-react-native';

<AkinProvider config={config} adapters={{ storage: myKeychainAdapter }}>
  {children}
</AkinProvider>

Localise auth error copy with the errorMessages prop (keyed by the stable AkinAuthErrorCode from sdk-core).


Example app

A runnable Expo example lives in example/ — a single screen that signs in (passkey or magic-link) and renders the member's tier and points.


Development

npm run build   # tsc → dist (also runs the compile-time parity conformance)
npm test        # vitest — adapters, passkey flow, tier-progress, member mapper, exports

The RN peer modules are not installed in the akin-online monorepo; the adapters are dependency-injected and unit-tested with fakes, and the native imports are isolated to src/native/defaults.ts (typed via src/native-modules.d.ts).