react-native-ultra-base64 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alex Shumihin
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,378 @@
1
+ # ⚡ react-native-ultra-base64
2
+
3
+ **The fastest base64 encoding/decoding library for React Native**
4
+
5
+ Ultra-fast base64 operations powered by optimized C++ with JSI bindings. Built for performance-critical applications that need blazing-fast base64 encoding and decoding.
6
+
7
+ [![npm version](https://img.shields.io/npm/v/react-native-ultra-base64.svg)](https://www.npmjs.com/package/react-native-ultra-base64)
8
+ [![license](https://img.shields.io/npm/l/react-native-ultra-base64.svg)](https://github.com/pioner92/react-native-ultra-base64/blob/main/LICENSE)
9
+ [![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20Android-lightgrey.svg)](https://github.com/pioner92/react-native-ultra-base64)
10
+
11
+ ---
12
+
13
+ ## 🚀 Why Choose This Library?
14
+
15
+ - **🏎️ Blazing Fast** - Up to **2x faster** than react-native-quick-base64 v3
16
+ - **⚡ Zero Bridge Overhead** - Direct JSI bindings eliminate React Native bridge bottleneck
17
+ - **🌐 URL-Safe Support** - Native support for URL-safe base64 encoding/decoding
18
+ - **📦 Small Bundle** - Minimal JavaScript footprint, heavy lifting done in native code
19
+ - **🔒 Type Safe** - Full TypeScript support with comprehensive type definitions
20
+ - **✅ Battle Tested** - Extensive test suite covering edge cases and compatibility
21
+
22
+ ---
23
+
24
+ ## 📊 Performance
25
+
26
+ Benchmark against **react-native-quick-base64 v3**
27
+
28
+ | iPhone | Android |
29
+ | ------ | ------- |
30
+ | <img src="./assets/iphone.png" height="600"> | <img src="./assets/android.png" height="600"> |
31
+
32
+
33
+ > 💡 **Performance scales with data size** - the larger your data, the more dramatic the improvement!
34
+
35
+ ---
36
+
37
+ ## 📦 Installation
38
+
39
+ ```sh
40
+ npm install react-native-ultra-base64
41
+ ```
42
+
43
+ or
44
+
45
+ ```sh
46
+ yarn add react-native-ultra-base64
47
+ ```
48
+
49
+ ### iOS Setup
50
+
51
+ ```sh
52
+ cd ios && pod install
53
+ ```
54
+
55
+ ### Android Setup
56
+
57
+ No additional steps required! The library will automatically link.
58
+
59
+ ---
60
+
61
+ ## 🎯 Quick Start
62
+
63
+ ```typescript
64
+ import {
65
+ fromByteArray,
66
+ toByteArray,
67
+ byteLength,
68
+ trimBase64Padding
69
+ } from 'react-native-ultra-base64';
70
+
71
+ // 🔵 Encode to base64
72
+ const data = new Uint8Array([72, 101, 108, 108, 111]);
73
+ const encoded = fromByteArray(data);
74
+ console.log(encoded); // "SGVsbG8="
75
+
76
+ // 🔵 Decode from base64
77
+ const decoded = toByteArray('SGVsbG8=');
78
+ console.log(decoded); // Uint8Array [72, 101, 108, 108, 111]
79
+
80
+ // 🔵 Get byte length without decoding
81
+ const length = byteLength('SGVsbG8=');
82
+ console.log(length); // 5
83
+
84
+ // 🔵 URL-safe base64
85
+ const urlSafeEncoded = fromByteArray(data, true);
86
+ console.log(urlSafeEncoded); // Uses '-' and '_' instead of '+' and '/'
87
+ ```
88
+
89
+ ---
90
+
91
+ ## 📖 API Reference
92
+
93
+ ### `fromByteArray(uint8: Uint8Array, urlSafe?: boolean): string`
94
+
95
+ Encodes a `Uint8Array` to a base64 string.
96
+
97
+ **Parameters:**
98
+ - `uint8` - The byte array to encode
99
+ - `urlSafe` (optional) - Use URL-safe encoding (replaces `+/` with `-_` and omits padding)
100
+
101
+ **Returns:** Base64 encoded string
102
+
103
+ **Example:**
104
+ ```typescript
105
+ const bytes = new Uint8Array([255, 254, 253]);
106
+ const standard = fromByteArray(bytes); // "//79"
107
+ const urlSafe = fromByteArray(bytes, true); // "__79"
108
+ ```
109
+
110
+ ---
111
+
112
+ ### `toByteArray(input: string, removeLinebreaks?: boolean): Uint8Array`
113
+
114
+ Decodes a base64 string to a `Uint8Array`.
115
+
116
+ **Parameters:**
117
+ - `input` - The base64 string to decode
118
+ - `removeLinebreaks` (optional) - Remove `\n` and `\r` before decoding
119
+
120
+ **Returns:** Decoded byte array
121
+
122
+ **Example:**
123
+ ```typescript
124
+ const decoded = toByteArray('SGVsbG8=');
125
+ console.log(decoded); // Uint8Array [72, 101, 108, 108, 111]
126
+
127
+ // Handle base64 with linebreaks
128
+ const withLinebreaks = 'SGVs\nbG8=';
129
+ const cleaned = toByteArray(withLinebreaks, true);
130
+ ```
131
+
132
+ **Throws:** `Error` if input is not valid base64
133
+
134
+ ---
135
+
136
+ ### `byteLength(b64: string): number`
137
+
138
+ Calculates the byte length of a base64 string **without decoding**.
139
+
140
+ **Parameters:**
141
+ - `b64` - The base64 string
142
+
143
+ **Returns:** Number of bytes the decoded data would be
144
+
145
+ **Example:**
146
+ ```typescript
147
+ const length = byteLength('SGVsbG8=');
148
+ console.log(length); // 5 (much faster than decoding)
149
+ ```
150
+
151
+ ---
152
+
153
+ ### `trimBase64Padding(str: string): string`
154
+
155
+ Removes trailing padding characters (`=`) from a base64 string.
156
+
157
+ **Parameters:**
158
+ - `str` - The base64 string
159
+
160
+ **Returns:** String without padding
161
+
162
+ **Example:**
163
+ ```typescript
164
+ const padded = 'SGVsbG8=';
165
+ const trimmed = trimBase64Padding(padded);
166
+ console.log(trimmed); // "SGVsbG8"
167
+ ```
168
+
169
+ ## 🎨 Advanced Examples
170
+
171
+ ### Working with Images
172
+
173
+ ```typescript
174
+ import { toByteArray, fromByteArray } from 'react-native-ultra-base64';
175
+ import RNFS from 'react-native-fs';
176
+
177
+ // Load and decode base64 image
178
+ async function loadImage(base64Data: string) {
179
+ const imageBytes = toByteArray(base64Data);
180
+ const path = `${RNFS.CachesDirectoryPath}/image.jpg`;
181
+ await RNFS.writeFile(path, imageBytes, 'base64');
182
+ return path;
183
+ }
184
+
185
+ // Encode image to base64
186
+ async function encodeImage(filePath: string) {
187
+ const fileData = await RNFS.readFile(filePath, 'base64');
188
+ const bytes = toByteArray(fileData);
189
+ return fromByteArray(bytes);
190
+ }
191
+ ```
192
+
193
+ ### Processing Large Files
194
+
195
+ ```typescript
196
+ import { toByteArray, fromByteArray } from 'react-native-ultra-base64';
197
+
198
+ // Efficiently process large base64 data
199
+ function processLargeFile(base64String: string) {
200
+ // Decode (fast!)
201
+ const bytes = toByteArray(base64String);
202
+
203
+ // Process bytes...
204
+ const processed = bytes.map(byte => byte ^ 0xFF); // Example: invert bits
205
+
206
+ // Encode back (still fast!)
207
+ return fromByteArray(new Uint8Array(processed));
208
+ }
209
+ ```
210
+
211
+ ### API Requests with Base64 Bodies
212
+
213
+ ```typescript
214
+ import { fromByteArray, toByteArray } from 'react-native-ultra-base64';
215
+
216
+ // Send binary data as base64
217
+ async function uploadBinaryData(data: Uint8Array) {
218
+ const base64 = fromByteArray(data);
219
+
220
+ const response = await fetch('https://api.example.com/upload', {
221
+ method: 'POST',
222
+ headers: { 'Content-Type': 'application/json' },
223
+ body: JSON.stringify({ data: base64 })
224
+ });
225
+
226
+ return response.json();
227
+ }
228
+
229
+ // Receive binary data as base64
230
+ async function downloadBinaryData() {
231
+ const response = await fetch('https://api.example.com/download');
232
+ const { data } = await response.json();
233
+
234
+ return toByteArray(data); // Returns Uint8Array
235
+ }
236
+ ```
237
+
238
+ ### Crypto Integration
239
+
240
+ ```typescript
241
+ import { toByteArray, fromByteArray } from 'react-native-ultra-base64';
242
+ import * as Crypto from 'expo-crypto';
243
+
244
+ async function encryptAndEncode(plaintext: string) {
245
+ // Encrypt
246
+ const encrypted = await Crypto.digestStringAsync(
247
+ Crypto.CryptoDigestAlgorithm.SHA256,
248
+ plaintext,
249
+ { encoding: Crypto.CryptoEncoding.HEX }
250
+ );
251
+
252
+ // Convert hex to bytes
253
+ const bytes = new Uint8Array(
254
+ encrypted.match(/.{1,2}/g)!.map(byte => parseInt(byte, 16))
255
+ );
256
+
257
+ // Encode to base64 for transmission
258
+ return fromByteArray(bytes);
259
+ }
260
+ ```
261
+
262
+ ---
263
+
264
+ ## 🔥 Features
265
+
266
+ - ✅ **Standard & URL-safe base64** - Full RFC 4648 compliance
267
+ - ✅ **Linebreak handling** - Automatically remove `\n` and `\r` during decode
268
+ - ✅ **Padding tolerance** - Handles missing or misplaced padding gracefully
269
+ - ✅ **TypeScript first** - Complete type definitions included
270
+ - ✅ **Zero dependencies** - No runtime dependencies except React Native
271
+ - ✅ **JSI direct bindings** - Bypass the bridge entirely
272
+ - ✅ **Memory efficient** - Optimized memory usage for large data
273
+ - ✅ **Works with Expo** - Compatible with Expo dev builds
274
+
275
+ ---
276
+
277
+ ## 🆚 Comparison with react-native-quick-base64
278
+
279
+ | Feature | react-native-ultra-base64 | react-native-quick-base64 |
280
+ |---------|--------------------------|---------------------------|
281
+ | **Speed** | ⚡⚡⚡⚡⚡ ~2x faster | ⚡⚡⚡ Fast |
282
+ | **JSI Bindings** | ✅ | ✅ |
283
+ | **URL-safe Support** | ✅ | ✅ |
284
+ | **TypeScript** | ✅ | ✅ |
285
+ | **Bundle Size** | 🟢 Small | 🟢 Small |
286
+ | **Native Code** | C++ (highly optimized) | C++ |
287
+
288
+ ---
289
+
290
+ ## 🏗️ How It Works
291
+
292
+ This library uses several optimization techniques:
293
+
294
+ 1. **JSI Direct Bindings** - Functions are installed directly on the JavaScript global object, eliminating bridge serialization overhead
295
+ 2. **Cache-Aligned Tables** - Lookup tables are aligned to 64-byte boundaries for L1 cache efficiency
296
+ 3. **Branch Prediction Hints** - Uses `[[likely]]`/`[[unlikely]]` attributes for optimal branch prediction
297
+ 4. **Zero-Copy Operations** - Direct memory access to ArrayBuffers without copying when possible
298
+ 5. **Optimized Hot Paths** - Fast path for common cases (99.9%), slow path only for edge cases
299
+
300
+ ---
301
+
302
+ ## 🐛 Troubleshooting
303
+
304
+ ### "encodeBase64FromArrayBuffer is not a function"
305
+
306
+ Make sure the native module is properly installed and linked:
307
+
308
+ ```sh
309
+ # iOS
310
+ cd ios && pod install
311
+
312
+ # Clean build
313
+ cd .. && yarn example ios --simulator="iPhone 15"
314
+ ```
315
+
316
+ ### TypeScript errors
317
+
318
+ Ensure you have the latest version installed and TypeScript can find the types:
319
+
320
+ ```json
321
+ // tsconfig.json
322
+ {
323
+ "compilerOptions": {
324
+ "moduleResolution": "node"
325
+ }
326
+ }
327
+ ```
328
+
329
+ ### Performance not as expected?
330
+
331
+ - Ensure you're running a **release build** (debug builds have overhead)
332
+ - Check you're testing with realistic data sizes (>1KB)
333
+ - Verify no other libraries are intercepting base64 operations
334
+
335
+ ---
336
+
337
+ ## 🤝 Contributing
338
+
339
+ Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.
340
+
341
+ ### Development Setup
342
+
343
+ ```sh
344
+ # Clone the repo
345
+ git clone https://github.com/pioner92/react-native-ultra-base64.git
346
+ cd react-native-ultra-base64
347
+
348
+ # Install dependencies
349
+ yarn
350
+
351
+ # Run example app
352
+ yarn example ios
353
+ # or
354
+ yarn example android
355
+ ```
356
+
357
+ ---
358
+
359
+ ## 📄 License
360
+
361
+ MIT © [Alex Shumihin](https://github.com/pioner92)
362
+
363
+ ---
364
+
365
+ ## 🙏 Acknowledgments
366
+
367
+ - Inspired by [base64-js](https://github.com/beatgammit/base64-js) and [react-native-quick-base64](https://github.com/craftzdog/react-native-quick-base64)
368
+ - Built with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
369
+
370
+ ---
371
+
372
+ ## ⭐ Show Your Support
373
+
374
+ If this library helps your project, please give it a ⭐ on [GitHub](https://github.com/pioner92/react-native-ultra-base64)!
375
+
376
+ ---
377
+
378
+ **Made with ❤️ for the React Native community**
@@ -0,0 +1,34 @@
1
+ cmake_minimum_required(VERSION 3.4.1)
2
+ project(react-native-ultra-base64)
3
+
4
+ set (CMAKE_VERBOSE_MAKEFILE ON)
5
+ set (CMAKE_CXX_STANDARD 17)
6
+
7
+
8
+ add_library(react-native-ultra-base64 SHARED
9
+ ../cpp/react-native-ultra-base64.cpp
10
+ ../cpp/simdutf.cpp
11
+ ../cpp/simdutf.h
12
+ cpp-adapter.cpp
13
+ )
14
+
15
+ include_directories(
16
+ ../cpp
17
+ )
18
+
19
+ find_package(ReactAndroid REQUIRED CONFIG)
20
+
21
+
22
+ if (ReactAndroid_VERSION_MINOR GREATER_EQUAL 76)
23
+ target_link_libraries(
24
+ react-native-ultra-base64
25
+ ReactAndroid::jsi
26
+ ReactAndroid::reactnative
27
+ )
28
+ else()
29
+ target_link_libraries(
30
+ react-native-ultra-base64
31
+ ReactAndroid::jsi
32
+ ReactAndroid::reactnativejni
33
+ )
34
+ endif()
@@ -0,0 +1,107 @@
1
+ buildscript {
2
+ def kotlin_version = rootProject.ext.has("kotlinVersion") ? rootProject.ext.get("kotlinVersion") : project.properties["RNUltraBase64_kotlinVersion"]
3
+
4
+ repositories {
5
+ google()
6
+ mavenCentral()
7
+ }
8
+
9
+ dependencies {
10
+ classpath "com.android.tools.build:gradle:7.2.1"
11
+ // noinspection DifferentKotlinGradleVersion
12
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13
+ }
14
+ }
15
+
16
+
17
+ def reactNativeArchitectures() {
18
+ def value = rootProject.getProperties().get("reactNativeArchitectures")
19
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
20
+ }
21
+
22
+ def isNewArchitectureEnabled() {
23
+ return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
24
+ }
25
+
26
+ def getExtOrDefault(name) {
27
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["RNUlid_" + name]
28
+ }
29
+
30
+ def getExtOrIntegerDefault(name) {
31
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["RNUlid_" + name]).toInteger()
32
+ }
33
+
34
+
35
+ apply plugin: "com.android.library"
36
+ apply plugin: "kotlin-android"
37
+
38
+
39
+ if (isNewArchitectureEnabled()) {
40
+ apply plugin: "com.facebook.react"
41
+ }
42
+
43
+ android {
44
+ namespace "com.ultrabase64"
45
+
46
+ compileSdkVersion getExtOrDefault("compileSdkVersion")
47
+
48
+ defaultConfig {
49
+ minSdkVersion getExtOrDefault("minSdkVersion")
50
+ targetSdkVersion getExtOrDefault("targetSdkVersion")
51
+
52
+ externalNativeBuild {
53
+ cmake {
54
+ cppFlags "-O3 -Wall -ffunction-sections -fdata-sections -fstack-protector-strong"
55
+ abiFilters (*reactNativeArchitectures())
56
+ arguments "-DANDROID_STL=c++_shared",
57
+ "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
58
+ }
59
+ }
60
+ }
61
+
62
+ externalNativeBuild {
63
+ cmake {
64
+ path "CMakeLists.txt"
65
+ }
66
+ }
67
+
68
+ buildFeatures {
69
+ buildConfig true
70
+ prefab true
71
+ }
72
+
73
+ buildTypes {
74
+ release {
75
+ minifyEnabled false
76
+ }
77
+ }
78
+
79
+ packagingOptions {
80
+ excludes = [
81
+ "**/libc++_shared.so",
82
+ "**/libjsi.so",
83
+ "**/libreactnativejni.so",
84
+ "**/libreact_nativemodule_core.so",
85
+ "**/libturbomodulejsijni.so",
86
+ "**/libc++_shared.so",
87
+ "**/libfbjni.so",
88
+ "**/libreactnative.so",
89
+ ]
90
+ }
91
+
92
+ lint {
93
+ disable "GradleCompatible"
94
+ }
95
+
96
+ compileOptions {
97
+ sourceCompatibility JavaVersion.VERSION_1_8
98
+ targetCompatibility JavaVersion.VERSION_1_8
99
+ }
100
+ }
101
+
102
+ def kotlin_version = getExtOrDefault("kotlinVersion")
103
+
104
+ dependencies {
105
+ implementation "com.facebook.react:react-native:+"
106
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
107
+ }
@@ -0,0 +1,12 @@
1
+ #include <jni.h>
2
+ #include "jsi/jsi.h"
3
+ #include "react-native-ultra-base64.h"
4
+
5
+
6
+ extern "C"
7
+ JNIEXPORT void JNICALL
8
+ Java_com_ultrabase64_UltraBase64Module_nativeInstall (JNIEnv* /*env*/, jobject /*thiz*/, jlong runtimePtr) {
9
+ auto* rt = reinterpret_cast<facebook::jsi::Runtime*>(runtimePtr);
10
+ if (!rt) return;
11
+ rnub_base64::install(rt);
12
+ }
@@ -0,0 +1,5 @@
1
+ RNTurboBase64_kotlinVersion=1.7.0
2
+ RNTurboBase64_minSdkVersion=21
3
+ RNTurboBase64_targetSdkVersion=31
4
+ RNTurboBase64_compileSdkVersion=31
5
+ RNTurboBase64_ndkversion=21.4.7075529
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,38 @@
1
+ package com.ultrabase64
2
+
3
+ import android.util.Log
4
+ import com.facebook.react.bridge.ReactApplicationContext
5
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
6
+ import com.facebook.react.bridge.ReactMethod
7
+ import com.facebook.react.common.annotations.FrameworkAPI
8
+
9
+ class UltraBase64Module(private val reactContext: ReactApplicationContext) :
10
+ ReactContextBaseJavaModule(reactContext) {
11
+
12
+ override fun getName(): String {
13
+ return NAME
14
+ }
15
+
16
+ companion object {
17
+ const val NAME = "RNUltraBase64"
18
+ init {
19
+ System.loadLibrary("react-native-ultra-base64")
20
+ }
21
+
22
+ @OptIn(FrameworkAPI::class)
23
+ @JvmStatic
24
+ private external fun nativeInstall(jsiRuntimePtr: Long)
25
+ }
26
+
27
+ @OptIn(FrameworkAPI::class)
28
+ @ReactMethod(isBlockingSynchronousMethod = true)
29
+ fun install(): Boolean {
30
+ Log.d("react-native-ultra-base64", "install() called")
31
+ nativeInstall(
32
+ reactContext.javaScriptContextHolder!!.get(),
33
+ )
34
+ return true
35
+ }
36
+
37
+
38
+ }
@@ -0,0 +1,16 @@
1
+ package com.ultrabase64
2
+
3
+ import com.facebook.react.ReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.uimanager.ViewManager
7
+
8
+ class UltraBase64Package : ReactPackage {
9
+ override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
10
+ return listOf(UltraBase64Module(reactContext))
11
+ }
12
+
13
+ override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
14
+ return emptyList()
15
+ }
16
+ }