React Native

React Native

We also published a React Native version of this library that you can find at (opens in a new tab).


  • Supports Expo using expo-dev-client
  • Supports React Native Web


npm install react-native-opaque

The API is identical to the web version, except that you need to import from react-native-opaque instead of @serenity-kit/opaque.

One difference is that the ready Promise is already resolved when the react-native-opaque module is imported.

If you are using react-native-web you still need to wait for ready to resolve before you can use any function from react-native-opaque.

Usage with React Native Web

Since on web the package uses Web Assembly under the hood, it needs to be loaded asynchronously. To offer the same API the module is loaded internally, but in addition the API offers a ready Promise that will resolve once the module is loaded and ready to be used.

import * as opaque from 'react-native-opaque';
const password = 'sup-krah.42-UOI'; // user password
opaque.ready.then(() => {
  const { clientRegistrationState, registrationRequest } =
    opaque.client.startRegistration({ password });
  // ...

The most convenient way to use this is to have loading page that waits for the ready Promise to resolve before rendering the actual app.

For example:

export default function LoadingApp() {
  const [opaqueModuleStatus, setOpaqueModuleStatus] = React.useState<
    'loading' | 'failed' | 'loaded'
  React.useEffect(() => {
    async function waitForOpaque() {
      try {
        await opaque.ready;
      } catch (e) {
  }, []);
  if (opaqueModuleStatus === 'loading') return null;
  if (opaqueModuleStatus === 'failed')
    return <Text>Failed to load resources. Please reload the app.</Text>;
  return <App />;

Note: The ready Promise resolves right away on the native side.

Expo support

Since the package contains binaries it can't be used in combination with Expo Go. However, it can be used in combination with the Expo development client out of the box. No further configuration is needed.

Expo Example Instructions

  1. Setup an Expo project
  2. Setup EAS:
eas build:configure
  1. Add a simulator build to eas.json
  "build": {
    "development-simulator": {
      "developmentClient": true,
      "distribution": "internal",
      "ios": {
        "simulator": true
  1. Add expo-dev-client to package.json
npx expo install expo-dev-client

Add this to the top of App.js

import "expo-dev-client";

Replace in package.json:

"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"


"start": "expo start --dev-client",
"android": "expo start --android --dev-client",
"ios": "expo start --ios --dev-client",
"web": "expo start --web --dev-client"
  1. Commit your changes

  2. Add react-native-opaque

npx expo install react-native-opaque
  1. Run a build
eas build --profile development-simulator --platform ios
  1. Add the your code

You can get inspired by the example project here (opens in a new tab).

P256 Support

There also exists a version using the P256 curve for React Native. You can find it at