Skip to content

Crypto

@symbiote-native/crypto wraps expo-crypto — cryptographically secure random bytes, randomUUID, and string/buffer digest hashing — so every SymbioteNative adapter can reach it. Like local auth, every function here is a plain sync/async call with no per-instance state or event stream — no hook/composable/service to reach for. The AES-encryption surface from upstream’s expo-crypto (its aes/ subfolder) is out of scope for this pass.

OS platform Support
iOS ✅ live
Android ✅ live
Framework adapter Support
React ✅ live
Vue ✅ live
Angular ✅ live
Svelte ✅ live
Terminal window
pnpm add @symbiote-native/crypto

expo-crypto and expo-modules-core come along as regular dependencies, pinned to exact versions — never install either yourself, and never add the expo meta-package to your project (it bundles its own Metro/Babel pipeline, which conflicts with this project’s own).

No platform permission strings are needed for this package — random-byte generation and digest hashing touch no protected device capability.

All four adapters — React, Vue, Angular, Svelte — re-export the exact same free functions; 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 { Pressable, Text, View } from '@symbiote-native/react';
import {
CryptoDigestAlgorithm,
digestStringAsync,
randomUUID,
} from '@symbiote-native/crypto/react';
export default function CryptoDemo() {
const [uuid, setUuid] = useState('');
const [hash, setHash] = useState('');
useEffect(() => {
setUuid(randomUUID());
}, []);
const handleHash = () => {
digestStringAsync(CryptoDigestAlgorithm.SHA256, 'Confirm it is you').then(setHash);
};
return (
<View>
<Text>UUID: {uuid}</Text>
<Pressable onPress={handleHash}>
<Text>Hash a string</Text>
</Pressable>
{hash && <Text>SHA-256: {hash}</Text>}
</View>
);
}
Signature Description
getRandomBytes(byteCount: number): Uint8Array Synchronously generates byteCount cryptographically secure random bytes. byteCount must be 0-1024
getRandomBytesAsync(byteCount: number): Promise<Uint8Array> Same as getRandomBytes, asynchronously
getRandomValues<T extends ITypedArray>(typedArray: T): T Fills a provided integer-based TypedArray with cryptographically secure random values, in place
randomUUID(): string A V4 UUID (RFC4122), generated using cryptographically secure random values
digestStringAsync(algorithm: CryptoDigestAlgorithm, data: string, options?: ICryptoDigestOptions): Promise<IDigest> Generates a digest of a string, formatted per options.encoding (defaults to CryptoEncoding.HEX)
digest(algorithm: CryptoDigestAlgorithm, data: BufferSource): Promise<ArrayBuffer> Generates a digest of raw bytes, returned as an ArrayBuffer
Field Value Description
SHA1 'SHA-1' 160 bits
SHA256 'SHA-256' 256 bits, collision-resistant
SHA384 'SHA-384' 384 bits, collision-resistant
SHA512 'SHA-512' 512 bits, collision-resistant
MD2 'MD2' 128 bits. @platform ios
MD4 'MD4' 128 bits. @platform ios
MD5 'MD5' 128 bits
Field Value Description
HEX 'hex' Hexadecimal string output
BASE64 'base64' Base64 string output, with trailing padding, no line wraps
Field Type Default Description
encoding CryptoEncoding CryptoEncoding.HEX Format the digest string is returned in

@symbiote-native/crypto ships zero React/Vue/Angular logic in expo-crypto itself — its functions, enums, and the CryptoError validation class are hand-ported, verbatim, into this package’s own core/, resolving the native module through expo-modules-core’s requireNativeModule rather than the expo meta-package this project never installs:

packages/crypto/src/
├── core/ # framework-agnostic: every function above, CryptoDigestAlgorithm, CryptoEncoding,
│ # the option/result types, and CryptoError; native-module.ts resolves the native
│ # module via expo-modules-core's requireNativeModule
├── react/ # @symbiote-native/crypto/react — export * from '../core'
├── vue/ # @symbiote-native/crypto/vue — export * from '../core'
├── svelte/ # @symbiote-native/crypto/svelte — export * from '../core'
└── angular/ # @symbiote-native/crypto/angular — export * from '../core'

Same shape as local auth’s three adapter entries: single-file re-exports with no lifecycle code at all, since every function here is stateless and one-shot — there is nothing for a hook, composable, or service to subscribe to or clean up. The native code itself is never vendored or copied — expo-modules-autolinking resolves it straight out of node_modules (see the native setup guide).