Contact salesSign inSign up
AuthsignalAuthsignal
Product
Passwordless / multi-factor authentication (MFA)
Drop-in authentication
Risk-based authentication
Passkeys
Biometric authentication
WhatsApp OTP
Authenticator apps (TOTP)
Push authentication
SMS OTP
Email OTP
Magic links
See all authenticators
See less authenticators
Palm biometrics
Contactless payments & identity verification
Flexible integration modes
Pre-built UI
Low code
UI components
Customizable
Custom UI
Flexible
Digital credentials API Beta
Authenticate customers instantly using digital credentials
Session management
Keep users signed in across web and mobile after authentication
Fraud Controls
Rules and policies engine
Step-up authentication
No-code rule creation
Risk alerts
User observability
Audit trails
Dynamic linking
Why Authsignal?
Complete authentication infrastructure from enrollment to step-up auth, modular by design
Solutions
By USE CASE
View All
Account takeovers (ATO)
Go passwordless
Call center
SMS cost optimization
Existing apps
QR code payments
Step-up MFA
Palm biometrics payments
By INDUSTRY
View All
Financial services
Marketplace
e-Commerce
FinTech
Crypto
Healthcare
By Integration (identity provider)
Amazon Cognito
Azure AD B2C
Duende IdentityServer
Keycloak
Auth0
NextAuth.js
Custom identity provider
By ROLe
Engineers
Product
Passwordless / Multi-factor Authentication (MFA)
Flexible Integration Modes
Pre-built UI · Low code
UI Components · Customizable
Custom UI · Flexible
Digital credentials API Beta
Authenticate customers instantly using digital credentials
Session management
Issue JWT access and refresh tokens
Why Authsignal?
Plug in Authsignal to elevate your IDP — effortless integration with any architecture.
Drop-in Authentication
Risk-based authentication
Passkeys
Biometric authentication
WhatsApp OTP
SMS OTP
Email OTP
Magic links
Authenticator apps (TOTP)
Push notifications
Palm Biometrics
Contactless payments & identity verification
Fraud Controls
Rules and Policies Engine
Step-up Authentication
No Code Rule Creation
Risk Alerts
User Observability
Audit Trails
Use Cases
Financial services
Account takeovers (ATO)
Marketplace
Go passwordless
e-Commerce
Solutions
By Use Case
Account takeovers (ATO)
Go passwordless
Call center
SMS cost optimization
Existing apps
QR code payments
Step-up MFA
Palm Biometric Payments
View all Use Cases
By Industry
Financial services
Marketplace
e-Commerce
FinTech
Crypto
Healthcare
View all Industries
By Integration (identity provider)
Amazon Cognito
Azure AD B2C
Duende IdentityServer
Keycloak
Auth0
NextAuth.js
Custom identity provider
By Role
Engineers
PricingAboutDocsBlog
Schedule a call
Try Authsignal
AUS Flag

Authsignal secures millions of passkey transactions out of our hosted Sydney region.

AUS Flag

Authsignal secures millions of passkey transactions out of our hosted Sydney region.

Join us today!
Right icon
Blog
/
Current article
Passkeys
React native
Implementation

Implementing Passkeys In React Native: Why Expo Go Falls Short And How To Fix It

Ashutosh Bhadauriya
⬤
March 5, 2026
Share
Implementing Passkeys in React Native: Why Expo Go Falls Short and How to Fix It

Expo Go is a fantastic tool for React Native development, allowing you to quickly iterate on your app without the need for native builds. However, it comes with an important limitation:

‍

Expo Go does not natively support passkeys due to its limitations in handling native code dependencies. Passkey authentication requires native modules that are not compatible with Expo Go's managed environment.

‍

The core issue stems from the architecture of Expo Go:

  1. Sandboxed Environment: Expo Go runs your JavaScript code in a pre-built native container that has limited ability to incorporate custom native modules.
  2. Native Dependencies: Passkey implementation requires platform-specific native code to interact with the device's security features.
  3. Managed Workflow Limitations: In Expo's managed workflow, you can't directly modify the native code or add custom native modules without ejecting.

‍

Options for Implementing Passkeys in React Native with Expo

Option 1: Use Development Builds (Recommended)

The most effective approach is to use Expo's development builds while staying within the Expo ecosystem:

# Install the necessary packages
npx expo install expo-dev-client

# Create a development build
eas build --profile development --platform all

‍

With development builds, you can:

  • Add custom native modules via config plugins
  • Use Expo's managed workflow for most features
  • Test native functionality on real devices

Option 2: Use Config Plugins with EAS Build

Expo's config plugins system allows you to modify native code without ejecting:

  1. Create a config plugin for passkey implementation:
// plugins/withPasskeys.js
const withPasskeys = config => {
  // iOS modifications
  if (config.ios) {
    config.ios = {
      ...config.ios,
      // Add entitlements for passkeys
      entitlements: {
        ...(config.ios.entitlements || {}),
        'com.apple.developer.associated-domains': ['webcredentials:yourdomain.com'],
        'com.apple.developer.authentication-services.autofill-credential-provider': true
      }
    };
  }
  
  // Android modifications
  if (config.android) {
    // Add necessary Android configurations
  }
  
  return config;
};

module.exports = withPasskeys;

‍

  1. Register the plugin in your app.json:
{
  "expo": {
    "plugins": [
      "./plugins/withPasskeys"
    ]
  }
}

‍

Option 3: Use Expo's Prebuild to Generate a Native Project

expo prebuild

This command generates the necessary native code for your project, allowing you to directly modify native modules while still using Expo tools.

‍

How to implement Passkeys in React Native using AuthSignal

We’ll be using Authsignal’s React Native SDK to add passkeys

Step 1: Install the SDK

# Install using yarn
yarn add react-native-authsignal

# Link native iOS dependencies
npx pod-install ios

‍

Step 2: Configure Native Requirements

After you have configured your Relying Party on Authsignal Portal, you should follow the steps below.

For iOS:

  1. Host an apple-app-site-association file on your domain that matches your relying party:
GET https://<yourrelyingparty>/.well-known/apple-app-site-association

‍

The response should contain:

{
   "applinks": {},
   "webcredentials": {
      "apps": ["ABCDE12345.com.example.app"]
   },
   "appclips": {}
}

Where ABCDE12345 is your team ID and com.example.app is your bundle identifier.

  1. In XCode under “Signing & Capabilities” add a webcredentials entry for your domain / relying party e.g. example.com:

‍

For Android:

  1. Host an assetlinks.json file on your domain that matches your relying party:

‍

The response JSON should look something like this:

[{
    "relation": [
        "delegate_permission/common.handle_all_urls",
        "delegate_permission/common.get_login_creds"
    ],
    "target": {
        "namespace": "android_app",
        "package_name": "com.example",
        "sha256_cert_fingerprints": [
            "FA:C6:17:45:DC:09:03:78:6F:B9:ED:E6:2A:96:2B:39:9F:73:48:F0:BB:6F:89:9B:83:32:66:75:91:03:3B:9C"
        ]
    }
}]

‍

  1. Finally, you will need to add an expected origin value for your APK hash when configuring passkeys in the Authsignal Portal.

‍

Step 3: Initialize the Authsignal Client

You can find your tenant ID in the Authsignal Portal.

import { Authsignal } from "react-native-authsignal";

const authsignal = new Authsignal({
  tenantID: "YOUR_TENANT_ID",
  baseURL: "YOUR_REGION_BASE_URL", // e.g., "https://api.authsignal.com/v1"
});

‍

Step 4: Implement Passkey Registration

const handleCreatePasskey = async () => {
  try {
    // Get token from your backend (after user is authenticated)
    const { token } = await fetchTokenFromBackend();
    
    // Register passkey
    const response = await authsignal.passkey.signUp({
      token: token,
      username: "user@example.com",
      displayName: "User Name",
    });
    
    if (response.success) {
      console.log("Passkey created successfully");
    }
  } catch (error) {
    console.error("Error creating passkey:", error);
  }
};

‍

Step 5: Implement Passkey Authentication

const handleSignInWithPasskey = async () => {
  try {
    const response = await authsignal.passkey.signIn({ 
      action: "signInWithPasskey" 
    });
    
    if (response.data?.token) {
      // Send token to your server to validate
      const validationResult = await validateTokenWithBackend(response.data.token);
      
      if (validationResult.success) {
        // User is authenticated
        console.log("Successfully authenticated with passkey");
      }
    }
  } catch (error) {
    console.error("Error signing in with passkey:", error);
  }
};

‍

Note: On your backend, you'll need to validate the Authsignal token using the Authsignal Server SDK. This verifies that the passkey authentication was successful and hasn't been tampered with. For implementation details, see Authsignal's backend validation documentation.

‍

That’s it, you’ve successfully added passkeys to your React Native Application.

‍

Conclusion

By using development builds with Authsignal's SDK, you can implement secure passkey authentication while staying in the Expo ecosystem.

The initial setup requires more effort than using Expo Go, but the security and UX benefits for your users make it worthwhile. Passkeys eliminate password-related vulnerabilities while providing a seamless authentication experience. If passkeys are important for your app, the transition from Expo Go is a necessary and valuable investment.

Question icon
Have a question?
Talk to an expert
NewsletterDemo PasskeysView docs
Passkeys
React native
Implementation

You might also like

BSP Circular 1213: Philippine banks must replace SMS OTPs by June 2026
BSP Circular 1213
Philippine banking
SMS OTP
Risk based authentication

BSP Circular 1213: Philippine banks must replace SMS OTPs by June 2026

March 18, 2026
How to add adaptive MFA and passkeys to any web app with Authsignal and Lambda@Edge
AWS
Authentication
Security

How to add adaptive MFA and passkeys to any web app with Authsignal and Lambda@Edge

March 10, 2026
The real cost of building authentication in-house
Build vs. Buy
Authentication

The real cost of building authentication in-house

March 10, 2026

Secure your customers’ accounts today with Authsignal

Passkey demoCreate free account

Authsignal delivers passwordless and multi-factor authentication as a service. Focused on powering mid-market and enterprise businesses to rapidly deploy optimized good customer flows that enable a flexible and risk-based approach to authentication.

AICPA SOCFido Certified
LinkedInTwitter
Passwordless / multi-factor authentication (MFA)
Pre-built UI (low code)UI components (customizable)Custom UI (flexible)
Why Authsignal?
Drop-in authentication
Risk-based authentication PasskeysBiometric authenticationWhatsApp OTPSMS OTPEmail OTPMagic linksAuthenticator apps (TOTP)Push authenticationPalm biometricsDigital Credential Verification API
Rules and policies engine
User observability
Industries
Financial services
Marketplace
e-Commerce
FinTech
Crypto
View all industries
Teams
Engineers
Use cases
Account takeovers (ATO)
Go passwordless
Call center
SMS cost optimization
Existing apps
View all use cases
Identity providers (IDPs)
Amazon Cognito
Auth0
Azure AD B2C
Custom identity provider
Duende IdentityServer
Keycloak
NextAuth.js
Integrations
ASP.NET
C#
Java
Node.js
Open ID Connect (OIDC)
PHP
Python
React
Ruby
Ruby on Rails
Compare
Twilio Verify vs AuthsignalAuth0 vs AuthsignalAWS Cognito vs Authsignal + AWS Cognito
Resources
BlogDeveloper docsFree Figma mobile passkeys templateFree Figma desktop passkeys templateFree Figma webapp passkeys template
Company
About usWhy AuthsignalCareersPress releasesPartnersContact us
What is
SMS OTP
Risk Based Authentication
IP Spoofing
Passwordless authentication
Multi-Factor Authentication (MFA)
United States
+1 214 974-4877
Ireland
+353 12 676529
Australia
+61 387 715 810
New Zealand
+64 275 491 983
© 2026 Authsignal - All Rights Reserved
Terms of servicePrivacy policySecuritySystem statusCookies