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

signin-mobile

v0.1.0

Published

Brokered social login for React Native — native system auth session (ASWebAuthenticationSession / Custom Tabs). Companion to HIKO Social Login Plus.

Readme

signin-mobile

Native sign-in for React Native, powered by HIKO Social Login Plus on the Shopify App Store.

signin-mobile is the official React Native companion to HIKO Social Login Plus — the Shopify app that adds social, passwordless, and passkey sign-in to a Shopify storefront. This package brings those exact sign-in methods, and the merchant's exact configuration, into a native iOS/Android app.

Your app renders native buttons; the actual OAuth/OTP step runs in the platform's system authentication session (ASWebAuthenticationSession on iOS, Chrome Custom Tabs on Android). There is no embedded WebView, no bundled Facebook/Google SDK, and no client secret in the app — the HIKO broker is an OIDC broker, so the app only ever handles an opaque session token.

  • ✅ Google, Facebook, Apple, LINE, and 20+ social providers
  • ✅ Email one-time-code, WhatsApp, and passkey (passwordless)
  • ✅ Buttons styled from the merchant's HIKO dashboard (theme, shape, brand icons)
  • ✅ Marketing/terms consent gate honored automatically
  • ✅ Opaque session persisted in the Keychain / Keystore (expo-secure-store)
  • ✅ Customer Account API GraphQL queries through the broker

Table of contents


How it works

HIKO Social Login Plus (the Shopify app, "the broker") already runs a per-shop OIDC login flow for the storefront. signin-mobile reuses that same broker and the same providers — it only changes the transport of the login step.

┌─────────────────────────┐
│  Your React Native app  │
│  ┌───────────────────┐  │   1. GET /headless/config?shop=…
│  │  <HikoSignin/>    │──┼──────────────────────────────────►  HIKO broker
│  │  native buttons,  │  │      providers, styles, passwordless, consent
│  │  styled from cfg  │◄─┼──────────────────────────────────
│  └─────────┬─────────┘  │
│            │ tap         │
│            ▼             │   2. openAuthSessionAsync(/headless/start?…)
│  ┌───────────────────┐  │──────────────────────────────────►  broker → Shopify
│  │ ASWebAuthSession /│  │      Customer Accounts → provider / OTP / passkey
│  │ Chrome Custom Tabs│◄─┼──────────────────────────────────
│  └─────────┬─────────┘  │   3. redirect → myapp://callback#hiko_session=…
│            ▼             │
│  ┌───────────────────┐  │   4. token stored in Keychain / Keystore
│  │  expo-secure-store│  │      (opaque; no secrets in the app)
│  └───────────────────┘  │
└─────────────────────────┘   5. query customer via POST /headless/customer
  1. Config — the widget fetches /headless/config for the shop and renders the enabled providers with the merchant's styling (brand icons, theme, shape, sizes) plus any passwordless methods and consent gate.
  2. Login — tapping a button opens the system auth session at /headless/start. The broker walks the user through Shopify Customer Accounts and the chosen method entirely in the trusted system browser.
  3. Return — on success the broker redirects to your app's custom scheme with an opaque hiko_session in the URL fragment. The system session hands that URL back to the app.
  4. Persist — the token is saved in expo-secure-store (iOS Keychain / Android Keystore) and restored on next launch.
  5. Query — authenticated Customer Account API GraphQL requests are proxied through the broker with the session as a bearer token.

Because the whole OAuth/OTP exchange happens in the system browser against the broker's origin, passkeys work with no native WebAuthn integration, and there is never a provider secret or access token inside your app.


Requirements

  • React Native 0.7x+ (Expo SDK 50+ recommended; built and tested on Expo SDK 56).
  • The shop must have HIKO Social Login Plus installed and configured (providers enabled, and your app's redirect allowlisted — see Configuration).
  • Peer dependencies (installed alongside this package):

The package uses Expo modules but does not require an Expo-managed app — it runs in bare React Native too via install-expo-modules (see below).


Installation

npm install signin-mobile

Then install the peer dependencies. In an Expo project:

npx expo install expo-web-browser expo-secure-store react-native-svg

In a bare React Native project:

npm install expo-web-browser expo-secure-store react-native-svg
# one-time: enable Expo modules in a non-Expo RN app
npx install-expo-modules@latest
npx pod-install        # iOS

Deep-link (URL scheme) setup

Login returns to your app via a custom URL scheme (e.g. myapp://callback). The scheme you pass as appRedirect must be registered by the app and allowlisted on the broker for the shop.

Expo (managed / dev client)

In app.json / app.config.js, set the app scheme and add the Expo module config plugins:

{
  "expo": {
    "scheme": "myapp",
    "plugins": ["expo-web-browser", "expo-secure-store"]
  }
}

Build a dev client or standalone build (npx expo run:ios / npx expo run:android). The custom-scheme redirect does not work in Expo Go, which owns the exp:// scheme.

Bare React Native — iOS

Register the scheme in ios/<App>/Info.plist:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>myapp</string>
    </array>
  </dict>
</array>

ASWebAuthenticationSession captures the callback scheme for the auth session, so no extra AppDelegate wiring is required for login itself. Run npx pod-install after installing the peers.

Bare React Native — Android

Add an intent-filter for the scheme to your main activity in android/app/src/main/AndroidManifest.xml:

<activity android:name=".MainActivity" android:launchMode="singleTask" ...>
  <intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="myapp" />
  </intent-filter>
</activity>

Chrome Custom Tabs returns to the app through this filter.


Quick start

import { HikoSignin } from "signin-mobile";

export default function SignInScreen() {
  return (
    <HikoSignin
      shop="your-shop.myshopify.com"
      configServer="https://signin.hiko.software"
      appRedirect="myapp://callback"
      onLogin={(customer) => console.log("Signed in as", customer?.firstName)}
      onLogout={() => console.log("Signed out")}
    />
  );
}

HikoSignin handles the whole lifecycle: it loads the shop config, renders the styled provider buttons + passwordless entries, runs the auth session, persists the session, restores it on next launch, and exposes signed-in / signed-out callbacks.


Configuration

| Prop | Type | Description | | -------------- | -------------------- | ---------------------------------------------------------------------- | | shop | string (required) | The *.myshopify.com domain with HIKO Social Login Plus installed. | | configServer | string | Broker base URL. Defaults to https://signin.hiko.software. | | appRedirect | string (required) | Your app's custom-scheme return URL, e.g. myapp://callback. | | onLogin | (customer) => void | Fires once when a customer is signed in (with fetched customer data). | | onLogout | () => void | Fires on every signed-in → signed-out transition. |

Allowlist your redirect. appRedirect must be added to the shop's headless Allowed origins in the HIKO Social Login Plus admin. If it isn't, the broker rejects the login with invalid_return (scheme not accepted) or return_not_allowed (not in the allowlist).


Server-driven appearance & methods

Everything the widget shows comes from /headless/config, so merchants control it from the HIKO dashboard with no app release:

  • styles — theme (color/dark/light), shape (pill/rounded/square), format (icontext/center/right/text/icon), sizes, colors, and per-button overrides. Brand icons are rendered from vendored SVG marks via react-native-svg.
  • providers — the ordered list of enabled social providers.
  • passwordless{ otp, whatsapp, passkey }. When otp is on the widget shows an email field; whatsapp adds a WhatsApp button; passkey is offered on the broker's passwordless page during the email flow.
  • consent{ enabled, defaultChecked }. When enabled, a terms-consent checkbox is shown and sign-in is blocked until it's ticked.

Custom UI with useHikoAuth

Prefer to build your own UI? Use the hook and skip <HikoSignin> entirely.

import { useHikoAuth } from "signin-mobile";
import { Button, Text, View } from "react-native";

export function MySignIn() {
  const {
    isLoggedIn,
    customer,
    login,             // (provider) => Promise<boolean>
    loginWithEmail,    // (email)    => Promise<boolean>
    loginWithWhatsapp,
    logout,
    query,
  } = useHikoAuth({
    shop: "your-shop.myshopify.com",
    configServer: "https://signin.hiko.software",
    appRedirect: "myapp://callback",
  });

  if (isLoggedIn) {
    return (
      <View>
        <Text>Hi {customer?.firstName ?? "there"}</Text>
        <Button title="Log out" onPress={logout} />
      </View>
    );
  }

  return (
    <View>
      <Button title="Continue with Google" onPress={() => login("google")} />
      <Button title="Email me a code" onPress={() => loginWithEmail("[email protected]")} />
      <Button title="WhatsApp" onPress={loginWithWhatsapp} />
    </View>
  );
}

Querying customer data

Once signed in, run Customer Account API GraphQL through the broker:

const { auth } = useHikoAuth({ /* … */ });

const data = await auth.query(`
  {
    customer {
      firstName
      lastName
      emailAddress { emailAddress }
      orders(first: 5) { edges { node { name } } }
    }
  }
`);

auth.query attaches the persisted session as a bearer token and calls /headless/customer. A 401 clears the session and signs the user out.


API reference

Exports

import {
  HikoSignin,          // <HikoSignin /> drop-in component
  useHikoAuth,         // hook: state + login/logout for custom UIs
  createMobileAuth,    // low-level auth client (no React)
  loadConfig,          // fetch /headless/config
  createAuthSession,   // wrap expo-web-browser (preferEphemeralSession by default)
  parseSessionFromUrl, // extract hiko_session from a return URL
  createStorage,       // expo-secure-store token storage
} from "signin-mobile";

useHikoAuth({ shop, configServer, appRedirect })

Returns { auth, isLoggedIn, customer, login, loginWithEmail, loginWithWhatsapp, logout, query, getToken }.

createMobileAuth({ shop, configServer?, appRedirect, fetchImpl?, authSession?, storage? })

The headless client behind the hook. Methods:

| Method | Description | | -------------------------- | --------------------------------------------------------------- | | loadConfig() | Fetch the per-shop widget config. | | restore() | Rehydrate a persisted session on app launch. | | login(provider) | Social sign-in via the system auth session. Resolves boolean.| | loginWithEmail(email) | Email one-time-code (and passkey) sign-in. | | loginWithWhatsapp() | WhatsApp one-time-code sign-in. | | query(query, variables?) | Customer Account API GraphQL through the broker. | | getToken() | The current Customer Account API token info. | | session() | Current session info from the broker. | | logout() | Revoke on the broker and clear local storage. | | isLoggedIn() | Boolean, in-memory. | | getLastCustomer() | The last customer object fetched, if any. | | onChange(cb) | Subscribe to auth-state changes. Returns an unsubscribe fn. | | onLoginPhase(cb) | Observe start / cancel login phases. |

Config shape (/headless/config)

{
  entitled: boolean,
  providers: string[],
  styles: { theme, shape, format, buttonSize, iconSize, divider, /* + overrides */ },
  passwordless: { otp: boolean, whatsapp: boolean, passkey: boolean },
  consent: { enabled: boolean, defaultChecked: boolean },
  widgetText: Record<string, unknown>,
  storefront: Record<string, unknown>
}

Troubleshooting

| Symptom | Cause & fix | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------ | | invalid_return | The broker doesn't accept your redirect scheme. Ensure the broker supports custom-scheme returns and your appRedirect is allowlisted. | | return_not_allowed | appRedirect is a valid format but not in the shop's headless Allowed origins. Add it in the HIKO admin. | | Login opens then returns to a blank app | The custom scheme isn't registered (Info.plist / AndroidManifest / Expo scheme), or you're running in Expo Go. Use a dev/standalone build. | | "…Wants to Use … to Sign In" iOS prompt | The auth session is non-ephemeral. createAuthSession defaults to preferEphemeralSession: true; pass false to opt back into shared-Safari SSO. | | No buttons render | The shop isn't entitled or has no providers enabled in HIKO Social Login Plus. |


License

MIT