Skip to content

Commit 886236b

Browse files
committed
docs: address additional PR feedback
1 parent 536d9a3 commit 886236b

9 files changed

Lines changed: 90 additions & 18 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,3 +190,6 @@ tsconfig.tsbuildinfo
190190
# agents
191191
.claude/settings.local.json
192192
.agent/
193+
194+
# exclude docs lib
195+
!docs/lib

docs/app/api/releases/route.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ const getContributorDetails = unstable_cache(
3636

3737
if (!res.ok) {
3838
if (res.status === 404) return null;
39+
if (res.status === 403) {
40+
console.warn(`[API] Rate limit hit for user ${login}. Using fallback.`);
41+
return {
42+
login,
43+
avatar_url: `https://github.com/${login}.png`,
44+
html_url: `https://github.com/${login}`
45+
};
46+
}
3947
throw new Error(`GitHub User API Error: ${res.status}`);
4048
}
4149

docs/components/CoverageTable.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ export function CoverageTable() {
194194
) : (
195195
filteredCategories.map((category) => (
196196
<div key={category.title} className="bg-fd-card rounded-xl border border-fd-border overflow-hidden">
197-
<div className="px-6 py-4 bg-fd-secondary/30 border-b border-fd-border">
197+
<div className="px-6 py-4 bg-fd-card border-b border-fd-border sticky top-[var(--fd-nav-height)] z-10">
198198
<h3 className="font-semibold text-lg">{category.title}</h3>
199199
{category.description && (
200200
<p className="text-sm text-fd-muted-foreground mt-1">{category.description}</p>

docs/content/docs/guides/migration.mdx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Step, Steps } from 'fumadocs-ui/components/steps';
99
If you are coming from `react-native-crypto` (the slow, standard shim) or `expo-crypto`, here is how to upgrade.
1010

1111
## Why Upgrade?
12-
* **Performance**: 10x-60x faster depending on the operation.
12+
* **Performance**: **Hundreds of times faster** (via C++/JSI).
1313
* **Compatibility**: Supports modern Node.js 16+ crypto APIs.
1414
* **Correctness**: Passes the official Node.js test suite.
1515

@@ -76,6 +76,8 @@ If you only need simple hashing (SHA-256), `expo-crypto` is fine. If you need **
7676

7777
**Expo Crypto (digest):**
7878
```ts
79+
import * as Crypto from 'expo-crypto';
80+
7981
const digest = await Crypto.digestStringAsync(
8082
Crypto.CryptoDigestAlgorithm.SHA256,
8183
'Hello world'

docs/content/docs/introduction/comparison.mdx

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ RNQC is designed to be the faster, more complete alternative to existing solutio
1212

1313
| Feature | RNQC | react-native-crypto | react-native-fast-crypto |
1414
| :--- | :---: | :---: | :---: |
15-
| **Performance** | **JSI** (Native C++) | 🐢 Bridge (JS-shim) | ⚡️ JSI (Partial) |
15+
| **Performance** | **Nitro** (Native C++) | 🐢 Bridge (JS-shim) | ⚡️ JSI (Partial) |
1616
| **Node.js API** | **1:1 Compatible** | Compatible | Custom API |
1717
| **Sync Methods** | Fully Supported | Async Only | Supported |
1818
| **Thread Safety** | **Off-Main-Thread** | Blocks JS Thread | Off-Main-Thread |
@@ -29,7 +29,7 @@ sequenceDiagram
2929
participant JS as Javascript Code
3030
participant B as Bridge (JSON)
3131
participant N as Native Module
32-
participant JSI as RNQC (JSI)
32+
participant Nitro as RNQC (Nitro)
3333
3434
note over JS, B: Standard Module (Slow)
3535
JS->>B: Serialize JSON (Base64)
@@ -38,10 +38,10 @@ sequenceDiagram
3838
N->>B: Send Result JSON
3939
B->>JS: Deserialize JSON
4040
41-
note over JS, JSI: RNQC (Fast)
42-
JS->>JSI: Direct C++ Call (ArrayBuffer Ref)
43-
JSI->>JSI: Hash Memory Directly
44-
JSI->>JS: Return Result
41+
note over JS, Nitro: RNQC (Fast)
42+
JS->>Nitro: Direct C++ Call (ArrayBuffer Ref)
43+
Nitro->>Nitro: Hash Memory Directly
44+
Nitro->>JS: Return Result
4545
```
4646

4747
---
@@ -57,7 +57,7 @@ Standard React Native modules (like `react-native-crypto`) communicate via the B
5757
3. **Native**: Deserializes JSON, decodes Base64 to bytes.
5858
4. **Native**: Hashes bytes.
5959

60-
**RNQC (JSI)**:
60+
**RNQC (Nitro)**:
6161
1. **JS**: Holds a reference to an `ArrayBuffer`.
6262
2. **C++**: Reads that memory address directly. **Hash.**
6363
3. **Done.**
@@ -72,14 +72,16 @@ JSI allows us to define "Hybrid Objects" that can spawn their own C++ threads. W
7272
Proof is in the numbers. We benchmarked RNQC against standard JS implementations (`browserify`) and other native libraries.
7373

7474
<Callout type="info">
75-
**Benchmark Philosophy**: These comparisons are not meant to disparage pure JavaScript libraries. Libraries like `@noble/hashes` and `@noble/curves` perform exceptionally well in browser and Node.js environments. However, React Native lacks Node.js crypto APIs, so these benchmarks demonstrate the performance advantage of native implementations when pure JS is the only alternative on mobile.
75+
**Benchmark Philosophy**: This is not meant to disparage the other libraries. On the contrary, they perform amazingly well when used in a server-side Node environment or browser. This library exists because React Native does not have that environment nor the Node Crypto API implementation at hand. So the benchmark suite is there to show you the speedup vs. the alternative of using a pure JS library on React Native.
7676
</Callout>
7777

7878
**Environment**: iPhone 15 Pro, iOS 17.
7979

8080
## 1. Hashing (BLAKE3)
8181

82-
BLAKE3 is optimized for speed. RNQC (via JSI) processes large inputs **90x faster** than JS implementations.
82+
![Blake3 Benchmark](/img/benchmarks/blake3.png)
83+
84+
BLAKE3 is optimized for speed. RNQC (via Nitro) processes large inputs **90x faster** than JS implementations.
8385

8486
| Operation | RNQC | @noble/hashes | Speedup |
8587
| :--- | :--- | :--- | :--- |
@@ -89,15 +91,20 @@ BLAKE3 is optimized for speed. RNQC (via JSI) processes large inputs **90x faste
8991

9092
## 2. Encryption (AES-GCM / Salsa20)
9193

94+
![Cipher Benchmark](/img/benchmarks/cipher.png)
95+
9296
Native encryption prevents frame drops. `AES-256-GCM` is over **100x faster** for large buffers.
9397

9498
| Operation | RNQC | JS / Browserify | Speedup |
9599
| :--- | :--- | :--- | :--- |
96100
| **XSalsa20 (64KB)** | **852 ops/s** | 7.39 ops/s | **115x** 🚀 |
97-
| **AES-256-GCM (1MB)** | **177 ops/s** | 0.18 ops/s | **962x** 🚀 |
101+
| **AES-256-GCM (1MB)** | **177 ops/s** | 0.18 ops/s (browserify) | **962x** 🚀 |
102+
| **AES-256-GCM (1MB)** | **177 ops/s** | 1.32 ops/s (@noble) | **134x** 🚀 |
98103

99104
## 3. Key Derivation (PBKDF2)
100105

106+
![PBKDF2 Benchmark](/img/benchmarks/pbkdf2.png)
107+
101108
Password hashing is computationally expensive. Running this on the JS thread freezes the UI.
102109

103110
| Operation | RNQC | @noble/hashes | Speedup |
@@ -107,6 +114,8 @@ Password hashing is computationally expensive. Running this on the JS thread fre
107114

108115
## 4. Signatures (Ed25519)
109116

117+
![Ed25519 Benchmark](/img/benchmarks/ed25519.png)
118+
110119
Essential for crypto wallets. Verify signatures instantly without lag.
111120

112121
| Operation | RNQC | @noble/curves | Speedup |
@@ -116,6 +125,8 @@ Essential for crypto wallets. Verify signatures instantly without lag.
116125

117126
## 5. HKDF
118127

128+
![HKDF Benchmark](/img/benchmarks/hkdf.png)
129+
119130
Standard key derivation is **over 100x faster**.
120131

121132
| Operation | RNQC | @noble/hashes | Speedup |

docs/content/docs/introduction/complete-setup.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,12 +203,12 @@ yarn start --reset-cache
203203
If you need to use the `xsalsa20` cipher algorithm, you must enable libsodium support by setting an environment variable **before building your native code**:
204204

205205
```bash
206-
export RN_QUICK_CRYPTO_LIBSODIUM=1
206+
export SODIUM_ENABLED=1
207207
```
208208

209209
This can be done:
210-
- **iOS**: Set in your Xcode build settings or in a pre-build script
211-
- **Android**: Add to your `gradle.properties` or as a build environment variable
210+
- **iOS**: Export the variable `export SODIUM_ENABLED=1` before running `pod install`.
211+
- **Android**: Add `sodiumEnabled=true` to your project's `gradle.properties` file.
212212

213213
<Callout type="warn">
214214
Without this flag, attempting to use `xsalsa20` will throw a runtime error: `"libsodium must be enabled to use this cipher"`

docs/data/coverage.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export const COVERAGE_DATA: CoverageCategory[] = [
101101
{ name: 'asymmetricKeyDetails', status: 'missing' },
102102
{ name: 'equals', status: 'missing' },
103103
{ name: 'symmetricKeySize', status: 'missing' },
104+
{ name: 'toCryptoKey', status: 'missing' },
104105
{ name: 'from', status: 'missing', note: 'static' }
105106
]
106107
},
@@ -118,8 +119,8 @@ export const COVERAGE_DATA: CoverageCategory[] = [
118119
{ name: 'constants', status: 'implemented' },
119120
{ name: 'createCipheriv', status: 'implemented' },
120121
{ name: 'createDecipheriv', status: 'implemented' },
121-
{ name: 'createDiffieHellman', status: 'implemented' },
122-
{ name: 'createDiffieHellmanGroup', status: 'implemented' },
122+
{ name: 'createDiffieHellman', status: 'missing' },
123+
{ name: 'createDiffieHellmanGroup', status: 'missing' },
123124
{ name: 'createECDH', status: 'missing' },
124125
{ name: 'createHash', status: 'implemented' },
125126
{ name: 'createHmac', status: 'implemented' },
@@ -186,7 +187,7 @@ export const COVERAGE_DATA: CoverageCategory[] = [
186187
{ name: 'getCipherInfo', status: 'missing' },
187188
{ name: 'getCiphers', status: 'implemented' },
188189
{ name: 'getCurves', status: 'missing' },
189-
{ name: 'getDiffieHellman', status: 'implemented' },
190+
{ name: 'getDiffieHellman', status: 'missing' },
190191
{ name: 'getFips', status: 'missing' },
191192
{ name: 'getHashes', status: 'implemented' },
192193
{ name: 'getRandomValues', status: 'implemented' },
@@ -231,6 +232,17 @@ export const COVERAGE_DATA: CoverageCategory[] = [
231232
{
232233
title: 'WebCrypto (Subtle)',
233234
items: [
235+
{
236+
name: 'crypto.subtle',
237+
subItems: [
238+
{ name: 'decapsulateBits', status: 'missing' },
239+
{ name: 'decapsulateKey', status: 'missing' },
240+
{ name: 'encapsulateBits', status: 'missing' },
241+
{ name: 'encapsulateKey', status: 'missing' },
242+
{ name: 'getPublicKey', status: 'missing' },
243+
{ name: 'supports', status: 'missing' }
244+
]
245+
},
234246
{
235247
name: 'crypto.subtle.decrypt',
236248
subItems: [

docs/lib/layout.shared.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
2+
3+
export function baseOptions(): BaseLayoutProps {
4+
return {
5+
nav: {
6+
title: 'React Native Quick Crypto',
7+
},
8+
};
9+
}

docs/lib/source.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { docs } from 'fumadocs-mdx:collections/server';
2+
import { type InferPageType, loader } from 'fumadocs-core/source';
3+
import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons';
4+
5+
// See https://fumadocs.dev/docs/headless/source-api for more info
6+
export const source = loader({
7+
baseUrl: '/docs',
8+
source: docs.toFumadocsSource(),
9+
plugins: [lucideIconsPlugin()],
10+
});
11+
12+
export function getPageImage(page: InferPageType<typeof source>) {
13+
const segments = [...page.slugs, 'image.png'];
14+
15+
return {
16+
segments,
17+
url: `/og/docs/${segments.join('/')}`,
18+
};
19+
}
20+
21+
export async function getLLMText(page: InferPageType<typeof source>) {
22+
const processed = await page.data.getText('processed');
23+
24+
return `# ${page.data.title}
25+
26+
${processed}`;
27+
}

0 commit comments

Comments
 (0)