Skip to content

Standard web crypto

@symbiote-native/standard-web-crypto wraps expo-standard-web-crypto — a partial W3C Web Crypto API polyfill exposing crypto.getRandomValues — usable from every SymbioteNative adapter, not just React. Unlike every other Expo port in this repo, it ships no native module of its own: upstream is a ~15-line pure-JS shim that delegates straight to expo-crypto’s own getRandomValues, and this port delegates to @symbiote-native/crypto’s getRandomValues instead, since this repo already ships that native random source as a sibling package. Like @symbiote-native/crypto, every export here is a plain function/object with no per-instance state or event stream, so there is no hook/composable/service to reach for — the React, Vue, Angular, and Svelte entry points are plain re-exports of the same core.

OS platform Support
iOS ✅ live
Android ✅ live
Framework adapter Support
React ✅ live
Vue ✅ live
Angular ✅ live
Svelte ✅ live
Terminal window
npm install @symbiote-native/standard-web-crypto @symbiote-native/crypto

@symbiote-native/crypto comes along as a regular dependency and does the actual native random-byte generation — see its docs page for expo-crypto’s own native autolinking requirements (already satisfied in any app that already wires up @symbiote-native/crypto or @symbiote-native/device).

No further native wiring is needed for this package itself — it has no native module of its own and ships no native-link.json, so symbiote-expo-link generates nothing for it beyond what @symbiote-native/crypto already contributes.

All four adapters — React, Vue, Angular, Svelte — re-export the exact same default export and named function; there is no per-adapter hook/composable/service to reach for, since nothing here holds live state or a subscription.

import { useEffect, useState } from 'react';
import { Text, View } from '@symbiote-native/react';
import webCrypto, { polyfillWebCrypto } from '@symbiote-native/standard-web-crypto/react';
polyfillWebCrypto(); // no-op if globalThis.crypto already exists
export default function RandomBytes() {
const [hex, setHex] = useState('');
useEffect(() => {
const bytes = new Uint8Array(16);
webCrypto.getRandomValues(bytes);
setHex(Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join(''));
}, []);
return (
<View>
<Text>{hex || 'generating…'}</Text>
</View>
);
}
Signature Description
webCrypto: IWebCrypto (default export) The resolved Web Crypto object — either the real globalThis.crypto if one already exists, or this package’s own polyfill instance backed by @symbiote-native/crypto
webCrypto.getRandomValues<TArray extends ArrayBufferView>(values: TArray): TArray Fills values with cryptographically random numbers in place and returns it. Throws a TypeError if values isn’t one of the integer TypedArrays @symbiote-native/crypto supports (Int8Array/Uint8Array/Int16Array/Uint16Array/Int32Array/Uint32Array)
polyfillWebCrypto(): void Installs webCrypto as globalThis.crypto via a getter, for any library that expects the Web Crypto API to already be present. A no-op if globalThis.crypto is already defined — it never overwrites an existing implementation
Field Type Description
getRandomValues <TArray extends ArrayBufferView>(values: TArray) => TArray The one method this partial polyfill implements, matching the shape of the real DOM Crypto interface

getRandomValues only accepts the integer TypedArrays @symbiote-native/crypto can hand to its native module — passing any other ArrayBufferView (a DataView, Uint8ClampedArray, a Float32Array, …) throws a TypeError, the same way upstream’s own getRandomValues rejects an unsupported view.

@symbiote-native/standard-web-crypto ships zero native code of its own — the only Expo package in this repo’s lineup that doesn’t. Upstream’s expo-standard-web-crypto is itself a thin JS shim over expo-crypto’s native random source; this port keeps that same shape but swaps the delegate:

packages/standard-web-crypto/src/
├── core/ # framework-agnostic: web-crypto.ts — the Crypto class + webCrypto singleton
│ # (default export) and polyfillWebCrypto(), delegating to
│ # @symbiote-native/crypto's getRandomValues. No native-module.ts here — there is
│ # no native module to resolve.
├── react/ # @symbiote-native/standard-web-crypto/react — export * from '../core'
├── vue/ # @symbiote-native/standard-web-crypto/vue — export * from '../core'
├── angular/ # @symbiote-native/standard-web-crypto/angular — export * from '../core'
└── svelte/ # @symbiote-native/standard-web-crypto/svelte — export * from '../core'

Because the package needs no native module, it also needs no Android/iOS autolinking registration step — unlike every other expo-modules-core wrapper in this repo (see how to: wire up an Expo native module), there is nothing here for expo-modules-autolinking to discover. The only native dependency in the chain is @symbiote-native/crypto’s own module, already covered by that package’s install step. Same re-export shape as device and local auth: single-file re-exports with no lifecycle code at all, since every export here is a stateless function/object — there is nothing for a hook, composable, or service to subscribe to or clean up.