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

@ai-oauth-sdk/react-native

v1.3.0

Published

React Native / Expo adapter for ai-oauth-sdk: deep-link and auth-session receivers plus secure token storage.

Readme

@ai-oauth-sdk/react-native

React Native / Expo adapter for ai-oauth-sdk.

Documentation

npm i @ai-oauth-sdk/react-native

No peer dependencies. The RN and Expo modules are passed in rather than imported, so this package installs and typechecks whether or not you use Expo.

Expo

import * as WebBrowser from 'expo-web-browser'
import * as SecureStore from 'expo-secure-store'
import { createAuthClient, authSessionReceiver, secureStoreAdapter } from '@ai-oauth-sdk/react-native'

const client = createAuthClient({
  provider: 'openai',
  clientId,
  storage: secureStoreAdapter(SecureStore),
})

const tokens = await client.login({
  receiver: authSessionReceiver({ webBrowser: WebBrowser, redirectUri: 'myapp://auth/callback' }),
})

authSessionReceiver uses SFAuthenticationSession / Custom Tabs, so the user keeps their provider cookies and the OS closes the sheet on redirect.

Bare React Native

import { Linking } from 'react-native'
import { deepLinkReceiver } from '@ai-oauth-sdk/react-native'

const tokens = await client.login({
  receiver: deepLinkReceiver({ linking: Linking, redirectUri: 'myapp://auth/callback' }),
})

A custom URL scheme is open to every app on the device, so the receiver matches the callback to the attempt it presented, by state. A deep link whose state disagrees — or that carries none where one was presented — is dropped instead of settling the login. That includes ?error=..., which RFC 6749 requires a provider to echo state on; a provider that does not leaves the login pending rather than failing it, so pass timeoutMs (or a signal) to login().

Cold start

If the OS killed your app while the user was on the consent screen, the redirect arrives as the launch URL rather than a url event, and login() cannot pick it up: the relaunched app starts a fresh authorization with a fresh state, which the old URL can never match. Finish it yourself instead — the pending record is stored under its state, so with a persistent storage adapter, and inside the authorization TTL (10 minutes by default), this completes the flow the killed process started:

const callbackUrl = await Linking.getInitialURL()

if (callbackUrl?.startsWith('myapp://auth/callback')) {
  await client.completeAuthorization({ callbackUrl })
}

Crypto

No polyfill needed. Hermes ships without crypto.subtle, so PKCE challenges use a bundled pure-JS SHA-256, verified against WebCrypto and the FIPS 180-4 vectors.

Randomness is different: if crypto.getRandomValues is missing, the library throws rather than weakening your state and verifier. On bare RN add react-native-get-random-values and import it once at the top of your entry file; on Expo use expo-standard-web-crypto.

URLs

No react-native-url-polyfill either. React Native's built-in URL shim throws from its searchParams getter, and its URLSearchParams has historically accepted only an object, which is enough to break an authorization URL before the browser even opens. So the OAuth path never touches either global: query strings are built and parsed internally, byte-for-byte identically to what URLSearchParams would emit, which the test suite asserts against the real implementation across the whole ASCII range.

Install the polyfill if your own code wants a spec-compliant URL. Nothing here needs it.

Storage

secureStoreAdapter(SecureStore) uses the Keychain on iOS and EncryptedSharedPreferences on Android. Use it for refresh tokens. asyncStorageAdapter(AsyncStorage) is available too, but it is not encrypted at rest.

License

MIT


An independent, unofficial project. Not affiliated with or endorsed by OpenAI, Anthropic, Google, GitHub, Microsoft, xAI, Alibaba or OpenRouter; all trademarks belong to their owners. No provider officially supports these OAuth flows, and any of them may change without notice. Please read the disclaimer.