Increase Speed and Security With Native Crypto Libraries

Crypto libraries polyfilled from the browser or Node.js APIs open the door to security issues and are not performant

Web3 apps share similarities with the apps we've been accustomed to over the last decade. They also use native features like the Camera and Geolocation, and often also require a centralized server, besides interacting with the blockchain. The key distinction lies in occasional cryptographic requirements, such as hashing values, message signing with a private key, or generating secure random numbers cryptographically.

The web3 space as a whole is still new but can be considered mature on the web. There are plenty of web apps running stable for years and a good set of libraries and abstractions that allow a productive workflow. Therefore, it's only natural that when porting these applications to the React Native environment, developers will try going through the already known path, looking to use the same APIs.

The problem is that crypto utilities and functions are not provided by the JavaScript spec, but by the environment itself i.e. the browser, Node.js, Deno, Bun, etc., and the React Native environment lacks a native implementation.

There’s a GitHub discussion on adding a global crypto implementation to the React Native core (and even Hermes, the JavaScript engine created for React Native). However, following the React Native Lean Core efforts, the current understanding is that it's best to keep it as external packages by contributors committed to auditing and maintaining such critical packages.

Attempts were made to solve the issue

Over the past few years, several packages emerged to address this challenge by polyfilling the global crypto API with either the browser or Node.js implementation. However, this approach often comes with drawbacks, including an increased bundle size, non-standardization (as the browser crypto spec differs slightly from the Node.js spec), incomplete implementation for specific functions, and a potential security vulnerability.

Probably the most famous package, react-native-crypto (now deprecated) was a clone of crypto-browserify (a port of the Node.js implementation to the browser) and relied on traversing the node_modules directory and manually applying patches to the files inside. While this works, it opens the door to many security issues and is hard to maintain.

Solution

Use modern native implementations

Often, even web3 apps will only need a very specific subset of the available crypto functions. More specifically, most will need only getRandomValues(), a Cryptographically secure pseudorandom number generator (CSPRNG).

This is a function that can't be implemented relying on JavaScript's Math.random() because it can't guarantee that the result will contain enough entropy to be considered secure.

And that's where the native implementations come in. react-native-get-random-values by Linus Unnebäck is a native implementation of getRandomValues() committed to doing just that, and doing it well. It is battle-tested with more than 890.000 downloads weekly and uses SecureRandom on Android, and SecRandomCopyBytes on iOS, both APIs that are present and well-tested in the operating systems for many years.

The implementation is minimal and allows for easier auditing against security issues, within a very focused package.

This is the whole iOS implementation in Objective-C:

// Source: https://github.com/LinusU/react-native-get-random-values/blob/master/ios/RNGetRandomValues.m
#import "RNGetRandomValues.h"
@implementation RNGetRandomValues
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
RCT_EXPORT_MODULE()
RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSString*, getRandomBase64:(NSUInteger)byteLength) {
NSMutableData *data = [NSMutableData dataWithLength:byteLength];
int result = SecRandomCopyBytes(kSecRandomDefault, byteLength, data.mutableBytes);
if (result != errSecSuccess) {
@throw([NSException exceptionWithName:@"NO_RANDOM_BYTES" reason:@"Failed to aquire secure random bytes" userInfo:nil]);
}
return [data base64EncodedStringWithOptions:0];
}
@end

And the Android implementation in Java:

// Source: https://github.com/LinusU/react-native-get-random-values/blob/master/android/src/main/java/org/linusu/RNGetRandomValuesModule.java
package org.linusu;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import android.util.Base64;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
public class RNGetRandomValuesModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
public RNGetRandomValuesModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "RNGetRandomValues";
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String getRandomBase64(int byteLength) throws NoSuchAlgorithmException {
byte[] data = new byte[byteLength];
SecureRandom random = new SecureRandom();
random.nextBytes(data);
return Base64.encodeToString(data, Base64.NO_WRAP);
}
}

If you are using Expo, then you should consider the recently-revamped Expo Crypto, that contains a very similar implementation for getRandomValues in addition to other utilities like string digests and UUID generation. It will plug perfectly into your Expo app, and you can expect the same refined API and attention to detail as with all other Expo modules.

Finally, if you need a more complete crypto package, you should go for Margelo’s react-native-quick-crypto. It aims to be a drop-in replacement for the old react-native-crypto with a bigger set of crypto functions and provides great performance by taking advantage of directly invoking methods through C/C++ JSI.

Benefits

Less security attack vectors, faster performance, and a smaller bundle size

Security should always be a top priority, and even more when talking about web3 apps, which usually deal with financial and/or other unrecoverable assets from your users.

By using the options suggested above, you take another step towards a more secure and performant app, with an overall smaller bundle size without relying on clunky polyfills. It's a win-win situation, both for DX as well as UX.

Insights

Learn more about Web3

Event Cover

Apr 5Talk

Build Universal Web3 Apps With React Native

Learn how to use React Native to build true cross-platform experiences (iOS, Android and Web) for your decentralized apps, from a single codebase.

cover

Mar 13Article

The Mini Guide to React Native Optimization for Web3

Explore the essential strategies for optimizing React Native apps in the web3 landscape with this insightful mini-guide. Enhance stability, security, and UX.

cover

Jan 12Article

How to Build Universal Lens Protocol Social Apps With React Native

Unlock the potential of web3 social apps with Lens Protocol on the Polygon blockchain. Learn how to build a universal social network app using React Native.

cover

Dec 28Article

Cross-Platform Web3 dApps With React Native

Discover the power of cross-platform development with React Native and Expo in this guide. Learn to build Web3 dApps for web, iOS, and Android.

cover

Nov 14Podcast

Building the Future of Mobile Web3

Do Web3 and React Native go together? Tune in to our discussion about the possibilities & challenges of building cross-platform mobile apps with blockchain.

cover

Nov 13Article

Best DX for React Native Web3 dApps With Web3Modal and Wagmi

Unsatisfied with developer experience of developing for Ethereum? Learn how to build a React Native dApp using Wagmi and Web3Modal.

cover

Oct 25Article

Build Modern Web3 dApps on Ethereum With React Native and Viem

Learn to build modern web3 dApps on Ethereum using React Native and viem. Discover how viem outperforms traditional libraries.

cover

Mar 19Tutorial

The Hard Way vs. The React Native AI SDK Way: Stop Writing Custom Modules for Every Model

Learn how React Native AI uses a unified provider model to switch between cloud and on-device LLMs without rewriting application logic, enabling reliable AI experiences online and offline.

cover

Mar 12Tutorial

Build Smarter Apps: Tool Calling & AI Orchestration Explained

Learn how on-device models in React Native can call tools, interact with external APIs, and return structured outputs you can use directly in application logic.

cover

Mar 5Tutorial

MLC LLM + React Native: On-Device AI Without the Pain

Learn how to run third-party on-device LLMs in React Native using MLC LLM. Choose your models, run them efficiently across platforms, and keep a unified JavaScript API with React Native AI.

cover

Feb 24Tutorial

Intelligent Fallbacks with Apple Intelligence in React Native

Learn how to use Apple’s built-in Foundation Models in React Native apps, reduce memory usage, and enable fast, fully on-device AI with React Native AI Apple.

cover

Feb 10Tutorial

What Is the React Native AI SDK? A Complete Intro & Quickstart

Learn why on-device AI matters for React Native apps, how local LLMs behave offline, and what problems React Native AI is designed to solve from day one.

cover

Jan 29Tutorial

Implementing an Android TurboModule with Kotlin

Learn how to implement a React Native TurboModule on Android, from the TypeScript spec and Codegen to the Kotlin implementation and package registration.

cover

Jan 19Tutorial

Working with Different Threads in Swift TurboModules

Learn how JavaScript, native module, background, and main threads interact in React Native TurboModules, and how to use GCD queues to run async work safely in Swift.

cover

Jan 9Tutorial

How to Add Type-Safe Constants to Swift TurboModules

Learn how to expose typed, immutable constants from a Swift TurboModule using Codegen, and get full end-to-end type safety between native and JavaScript.

cover

Dec 30Tutorial

Adding Event Emitters to Your TurboModule in Swift

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

cover

Dec 22Tutorial

Writing Your First TurboModule in Swift

Learn how to build a fully working TurboModule in Swift, integrate it with Codegen, and bridge it through Objective‑C inside an Expo app.