react-native-securerandom

Generates cryptographically-secure random bytes in React Native apps using native iOS, Android, and Windows CSPRNGs.

Library
npm
v1.0.1
63stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
34/100Needs Attention
Development Activity0
Maintenance20
Community44
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
55/100Fair
Architecture58
Code Quality55
Innovation60
Learning Curve45

react-native-securerandom is a lightweight native module that exposes a single async function, generateSecureRandom(length), returning a Promise<Uint8Array> of cryptographically secure random bytes. Rather than reimplementing a PRNG in JavaScript, it delegates to each platform’s own vetted CSPRNG: SecRandomCopyBytes on iOS, SecureRandom (with Google’s PRNGFixes patch applied) on Android, and System.Security.Cryptography.RandomNumberGenerator on Windows via react-native-windows.

Because it forwards to native APIs instead of a JS-side polyfill, it avoids the well-documented pitfalls of Math.random() or naive JS PRNGs for security-sensitive code such as key generation, nonces, tokens, and salts. It ships with a TypeScript declaration and Flow types, and its native module and JS bridge are thin, auditable wrappers around a single native method.

What You Get

  • Single async API - generateSecureRandom(length) returns a Promise<Uint8Array> of secure random bytes.
  • True native CSPRNGs - Delegates to SecRandomCopyBytes (iOS), SecureRandom (Android), and RandomNumberGenerator (Windows) instead of a JS-side PRNG.
  • Android PRNG fix baked in - Applies Google’s PRNGFixes patch on module init to work around a known Android SecureRandom seeding vulnerability.
  • TypeScript and Flow types included - Ships index.d.ts and index.js.flow so consumers get type checking out of the box.
  • Tiny footprint - The entire JS surface is a few lines; the heavy lifting happens in native code you can read in an afternoon.

Common Use Cases

  • Generating cryptographic keys - Deriving symmetric keys or key material for local encryption in a mobile app.
  • Creating auth tokens and nonces - Generating unpredictable nonces, CSRF tokens, or session identifiers for API requests.
  • Password/salt generation - Producing random salts for client-side hashing before sending credentials to a server.
  • Building higher-level crypto libraries - Used as the randomness primitive underneath other React Native crypto packages that need a secure byte source.

Under The Hood

Architecture The JS surface is a single thin bridge: index.js pulls RNSecureRandom off NativeModules and calls generateSecureRandomAsBase64(length), decoding the returned base64 string to a Uint8Array with base64-js; there is no internal composition beyond this one call, so nothing structural would break if the abstraction changed since consumers only ever see generateSecureRandom. Each platform provides a minimal native counterpart — RNSecureRandomModule.java applies Android’s PRNGFixes patch on construction before delegating to java.security.SecureRandom, and RNSecureRandom.m wraps iOS’s SecRandomCopyBytes behind the standard RCT_REMAP_METHOD promise bridge — each doing exactly one platform crypto call and nothing else.

Tech Stack The JS package has a single runtime dependency, base64-js, and a peer dependency on react-native; native code is vanilla Java for Android (no Kotlin) built via Gradle, Objective-C for iOS built via an Xcode project and CocoaPods podspec, and C# for Windows via react-native-windows, calling System.Security.Cryptography.RandomNumberGenerator. JS-side tooling is Babel 7 for transpilation, Jest for tests, and Flow for static typing, with TypeScript declarations shipped separately for consumers on that toolchain.

Code Quality Two Jest test files (__tests__/happy.js, __tests__/notLinked.js) mock NativeModules to verify the correct byte length is forwarded to the native side, that base64 output is decoded correctly, and that an unlinked native module produces an explicit rejected promise rather than a silent failure — solid coverage of the small JS surface, though there is no automated test coverage of the native Android/iOS/Windows code and no CI configuration (no .github/workflows) was found in the repo. Naming is clear and consistent, and error handling is explicit throughout rather than swallowed.

API Design The public API is deliberately minimal — one function, one parameter, one return type — making it near-instant to learn and requiring no configuration beyond linking the native module for the target platform; a bundled example app (RNSecureRandomExample/) demonstrates usage end to end. The tradeoff is that it offers no configurable options (encodings, streaming, seeding) beyond the single byte-length argument, which is appropriate given its narrow, single-purpose scope.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search