Skip to content

Releases: Preeternal/react-native-file-hash

v2.0.5 - Zig C ABI v3, streaming files, and cancellation

14 Jun 17:36

Choose a tag to compare

This release updates the Zig core to zig-files-hash v0.0.5, moves file
hashing fully onto streaming paths, and adds AbortController-style cancellation
for both the native and zig engines.

Existing positional JavaScript calls still work, but the new object-style
request API is now the recommended API shape because it can carry
algorithm, hashOptions, and signal without placeholder arguments.

Why cancellation matters

Hashing a large video, archive, or offline map can take long enough for the
user to change their mind. With AbortController, apps can stop native hashing
when the user leaves the screen, picks another file, closes a modal, retries an
upload, or cancels a verification step.

That means less wasted CPU and battery, fewer stale promises updating old UI
state, and a cleaner integration with the same cancellation pattern developers
already use for fetch.

Added

  • Added object-style request overloads for both public hash functions:
    • fileHash(filePath, { algorithm, hashOptions, signal })
    • stringHash(text, { algorithm, encoding, hashOptions, signal })
  • Added HashRequest, StringHashRequest, HashAbortSignal, and
    HashAbortError TypeScript types.
  • Added optional AbortSignal support for cancelling work the app no longer
    needs. Aborting rejects with E_CANCELLED and normalizes the JS error name
    to AbortError.
  • Added native cancelOperation(operationId) plumbing behind the JS API.
    Operation ids are internal; users should cancel with AbortController.
  • Added cancellation coverage for file hashing and string hashing in both
    engines:
    • Android native engine checks cancellation between stream chunks and closes
      the active InputStream on cancel.
    • Android Zig engine forwards cancellation into the Zig operation state.
    • iOS native engine tracks Operation instances and rejects cancelled work
      with E_CANCELLED.
    • iOS Zig engine tracks operations and forwards cancellation into the Zig
      operation state.
  • Added benchmark controls to the example app, including generated local test
    files, warmups, samples, per-algorithm results, and cancellation.

Changed

  • File hashing now uses streaming implementations throughout the runtime.
    The Zig file path no longer depends on the old one-shot file API:
    • Android Zig reads React Native file/content URIs through an InputStream
      and feeds zfh_hasher_*.
    • iOS Zig streams file URLs/paths through zfh_hasher_*.
    • Native engines continue to stream file data from disk.
  • Updated the bundled Zig core to zig-files-hash v0.0.5.
  • Updated the Zig integration to C ABI v3 (ZFH_API_VERSION = 3) and the new
    request/operation-state API.
  • Updated Zig error mapping for the v3 ABI, including
    ZFH_OUTPUT_BUFFER_TOO_SMALL, ZFH_OPERATION_CANCELED, and
    ZFH_INVALID_STATE.
  • fileHash(path) and fileHash(path, {}) both default to SHA-256.
  • stringHash(text) and stringHash(text, {}) both default to SHA-256 with
    utf8 input encoding.
  • The example app now uses the fresh object-style API and exposes cancel
    buttons for file hashing, string hashing, and benchmark runs.
  • scripts/check-packed-prebuilts.sh now uses an isolated npm cache while
    packing and verifies the generated Zig C ABI header in the package.

Deprecated

  • Deprecated positional overloads:
    • fileHash(filePath, algorithm, options)
    • stringHash(text, algorithm, encoding, options)
  • hashString(...) remains as a deprecated alias for stringHash(...).

Recommended replacement:

const digest = await fileHash(fileUri, {
  algorithm: 'SHA-256',
});

Cancelable flow:

const controller = new AbortController();

const promise = fileHash(fileUri, {
  algorithm: 'SHA-256',
  signal: controller.signal,
});

controller.abort();

await promise; // rejects with E_CANCELLED / AbortError

For keyed algorithms:

await fileHash(fileUri, {
  algorithm: 'HMAC-SHA-256',
  hashOptions: {
    key: 'secret',
    keyEncoding: 'utf8',
  },
});

Compatibility

  • Hash output remains lowercase hex.
  • Key rules are unchanged:
    • HMAC-* algorithms require hashOptions.key.
    • BLAKE3 uses keyed mode only when hashOptions.key is provided.
    • Other algorithms reject hashOptions.key.
  • HashOptions.mode remains removed and still rejects with
    E_INVALID_ARGUMENT.
  • XXH3-128 remains native-only.
  • Consumers using the published package do not need Zig installed. Custom
    source/prebuilt builds must use the zig-files-hash C ABI v3 core.
  • Cancellation is cooperative. Long file hashes stop at chunk boundaries; small
    stringHash calls can finish before an abort is observed.

Performance

  • Refreshed physical-device Release benchmarks for the current native and
    zig engines. Full current tables live in BENCHMARKS.md.
  • The refreshed benchmark tables compare the current zig engine with the
    current native engine. They should be read separately from the
    release-to-release Zig speedups below.
  • Compared with the previous benchmark set, Zig BLAKE3 is much faster:
    • iOS 200 MiB: 728 ms -> ~302 ms
    • Android 200 MiB: 551 ms -> ~391 ms
  • Zig XXH3-64 improved on iOS: 81 ms -> ~66 ms for 200 MiB.
  • Zig SHA-224 / SHA-256 and matching HMAC variants remain competitive on
    iOS and stay near native on Android through the existing native fallback.
  • Native remains the faster choice for iOS SHA-1 and the iOS
    SHA-384 / SHA-512 family.
  • On Android, Zig remains the faster choice for SHA-512/224 and
    SHA-512/256; native remains faster for SHA-1, SHA-384, SHA-512,
    BLAKE3, and XXH3-64 in the current device run.

Testing

  • Expanded Jest coverage for the object request API, default values, abort
    handling, native cancellation calls, and AbortError normalization.
  • Updated runtime diagnostics tests for Zig C ABI v3 and zig-files-hash
    v0.0.5.

v2.0.3 - iOS Zig engine fix and React Native 0.85 template refresh

10 May 19:07

Choose a tag to compare

This release fixes iOS Zig engine prebuilts for Xcode 26 and refreshes the
project scaffold/example app to the latest create-react-native-library
template.

The public FileHash JavaScript API and hash output behavior are unchanged. The
default native engine remains unchanged; the iOS fix matters when opting into
the zig engine.

Fixed

  • Fixed iOS zig engine builds on Xcode 26 by repacking Zig-produced static
    archives with Apple's libtool, avoiding linker rejection of archives with
    not 8-byte aligned Mach-O members.
  • macOS CI now uses Homebrew zig@0.15 for Zig 0.15.2, which includes the
    Xcode 26.4 .tbd / Dylib.zig backport needed to rebuild iOS prebuilts.

Compatibility

  • JavaScript API remains compatible with previous 2.x releases.
  • Android minimum SDK remains 24 (Android 7.0).
  • React Native development and example app baseline updated to 0.85.0.
  • React development baseline updated to 19.2.3.
  • Old Architecture compatibility remains available for older React Native
    versions that still support it.
  • Old Architecture support is deprecated and will be removed in a future major
    release.
  • Both native and zig engine selection paths remain supported.

Android

  • Updated the example Android project to the current React Native 0.85
    template.
  • Updated example Gradle wrapper to 9.3.1.
  • Updated library Android defaults to compileSdkVersion 36 and
    targetSdkVersion 36.
  • Kept Android minimum SDK at 24.
  • Kept Android NDK pinned to 27.1.12297006 for reproducible CMake/JNI builds.
  • Moved library Android default versions into android/build.gradle and removed
    the separate library android/gradle.properties.
  • Migrated Android lint configuration from lintOptions to lint.
  • Kept check:16kb coverage for the final Android libfilehash-native.so.
  • Kept native and Zig Android hashing behavior unchanged.

iOS

  • Updated the example iOS project and pods for React Native 0.85.
  • Updated iOS CI jobs to Xcode 26.
  • Enabled React Native prebuilt dependencies in CI for faster iOS builds.
  • Included repacked Zig iOS prebuilts compatible with Xcode 26.
  • Preserved the existing Objective-C++ FileHash implementation and bridge
    exports.

Zig

  • iOS Zig prebuilts are rebuilt with archive repacking for Apple's stricter
    Xcode 26 linker checks.
  • Android Zig prebuilt generation remains based on Zig cross-compilation and is
    unchanged.

Tooling and CI

  • Updated create-react-native-library metadata from 0.55.1 to 0.62.0.
  • Updated Node tooling to Node 24.13.0 in .nvmrc.
  • Updated Jest to 30.x with @react-native/jest-preset and @jest/globals.
  • Updated TypeScript, ESLint, Prettier, Turbo, Bob, Commitlint, Lefthook, and
    Release It dependencies to match the refreshed template.
  • Excluded generated Gradle/CMake output directories from Turbo Android inputs.
  • Added cpp to packaged files for future native shared-code layout.

v2.0.2 - Packaging cleanup

19 Mar 19:53

Choose a tag to compare

Fixed

  • Removed unnecessary runtime dependency on buffer.
  • Package no longer pulls buffer into consumer installs; no API/runtime behavior changes.

v2.0.1 - Switchable engines (native / zig) and API update

15 Mar 14:54

Choose a tag to compare

Breaking changes

  • HashOptions.mode removed from public API. Passing mode now returns E_INVALID_ARGUMENT.
  • HMAC moved to dedicated algorithms: HMAC-SHA-224, HMAC-SHA-256,
    HMAC-SHA-384, HMAC-SHA-512, HMAC-MD5, HMAC-SHA-1.
  • Keyed/plain selection for BLAKE3 is now inferred from presence of key.
  • key is now valid only for HMAC algorithms and BLAKE3; for other
    algorithms it returns E_INVALID_ARGUMENT.
  • hashString(...) was replaced by stringHash(...) as the primary API.
    hashString(...) remains as a deprecated alias for migration.
  • Output contract is fixed: both fileHash and stringHash return lowercase
    hex digest strings.

Added

  • New optional zig engine with stable Zig C ABI integration.
  • Build-time engine selection (native by default, optional zig) for Android
    and iOS.
  • Runtime diagnostics APIs:
    • getRuntimeInfo()
    • getRuntimeDiagnostics()
  • Expo config plugin support (app.plugin.js) to set engine in prebuild/EAS.
  • New benchmark document and size/perf helper scripts:
    • BENCHMARKS.md
    • scripts/compare-size-android.sh
    • scripts/compare-size-ios.sh

Changed

  • Android engine internals split into explicit executors (NativeHashEngine,
    ZigHashEngine) with shared module routing.
  • Android Zig path now uses native fallback for SHA-224 / SHA-256 and
    matching HMAC variants in shipped generic Zig setup to avoid SHA-2 latency
    cliffs on devices without ARM64 sha2 acceleration in prebuilt config.
  • iOS bridge refactored into dedicated internal helpers for native and Zig
    paths (FileHashBridgeNative, FileHashBridgeZig, FileHashZigHelpers).
  • fileHash support for provider-backed paths was hardened on both platforms
    (content:// on Android, security-scoped/provider URLs on iOS).

CI / Tooling

  • Added reusable Zig setup action (.github/actions/setup-zig).
  • Expanded CI coverage for native and Zig paths (including Android unit tests
    and runtime smoke flows).

v1.1.3 - 16KB page alignment for Play Store

25 Jan 11:19

Choose a tag to compare

  • What's new

    • Android: enable 16KB page alignment for native library to satisfy Play Store requirements.
    • Guard the linker flag when unsupported; builds continue without 16KB alignment.
    • README: document 16KB alignment and tested NDK (27.1.x).
  • Tooling

    • Bump Yarn to 4.12.0 and refresh example locks.

v1.1.2 – bundle native sources in npm package

09 Jan 18:31

Choose a tag to compare

Fix

  • Include vendored native sources (xxhash/blake3) in the npm tarball so iOS builds from npm no longer fail with xxhash.h file not found.

Notes

  • After clone from git: git submodule update --init --recursive.

v1.1.1 – bundle native sources (XXH3/BLAKE3, HMAC/keyed)

14 Dec 18:38

Choose a tag to compare

Fix

  • Bundled native sources (xxhash/blake3) in the npm package so iOS builds no longer fail with xxhash.h file not found and the TurboModule registers correctly.

Reminder (from 1.1.0)

  • Native XXH3-64/XXH3-128 and BLAKE3 on iOS/Android.
  • hashString(text, algorithm, encoding?, options?) for small payloads (utf8/base64); for real files use fileHash (streams from disk).
  • Modes in fileHash/hashString: hash / hmac (SHA-224/256/384/512) / keyed (BLAKE3, 32-byte key utf8/hex/base64).
  • XXH3-128 output matches official xxHash order (low64 → high64).
  • Example app: hash file/string, switch modes, test utf8/hex/base64 keys. Migrated to create-react-native-library template (TurboModule, new/old arch).
  • README: algorithm table, output lengths, thread-safety note, submodule reminder.

Notes

  • After clone: git submodule update --init --recursive.
  • Tests: yarn test.

v1.1.0 – XXH3 & BLAKE3, hashString, HMAC/keyed modes

13 Dec 18:47

Choose a tag to compare

  • What’s new

    • Added native XXH3-64/XXH3-128 and BLAKE3 on iOS/Android.
    • New hashString(text, algorithm, encoding?, options?) for small payloads. Supports utf8 and base64 input. For real files always prefer fileHash, which streams data from disk.
    • Modes supported in fileHash and hashString: hash / hmac / keyed
      • HMAC — SHA-224/256/384/512 only.
      • Keyed — BLAKE3 only, 32-byte key (utf8 / hex / base64).
    • XXH3-128 output matches the official xxHash order (low64 → high64) on both platforms.
  • Example & scaffolding

    • New example app: hash files or small strings, switch modes (hash / hmac / keyed), and try utf8 / hex / base64 keys.
    • Project migrated to the create-react-native-library template (TurboModule, supports new/old architecture).
    • README: algorithm table and output lengths, thread-safety note, reminder about submodules.
  • Notes

    • After clone: git submodule update --init --recursive.
    • Tests: yarn test.

v1.0.5 — Full hash suite, Android coroutines, iOS performance

14 Sep 13:50

Choose a tag to compare

  • Highlights

    • Adds MD5, SHA‑1, SHA‑224, SHA‑256, SHA‑384, SHA‑512 across Android and iOS.
    • Faster async: Android coroutines; iOS OperationQueue + 64 KiB chunks.
    • README updated; CI now publishes only to npmjs.com.
  • Android

    • Migrated to Kotlin coroutines with lifecycle-aware cancel in invalidate().
    • Supports file://, content://, and plain paths; 64 KiB buffer for large files.
    • Explicit mapping to JCA names; unsupported → E_UNSUPPORTED_ALGORITHM.
  • iOS

    • Uses OperationQueue (maxConcurrentOperationCount = 2) and 64 KiB chunked reads.
    • SHA‑224 via CommonCrypto (CryptoKit doesn’t provide SHA‑224).
    • Thin Obj‑C extern (RCT_EXTERN_MODULE) kept for Old/New Arch robustness.
  • JS/Types

    • THashAlgorithm: 'MD5' | 'SHA-1' | 'SHA-224' | 'SHA-256' | 'SHA-384' | 'SHA-512' (default 'SHA-256').
  • Docs/CI

    • README documents all algorithms and examples.
    • Publishing to GitHub Packages removed to avoid registry conflicts.
  • Breaking changes

    • None expected. Public API unchanged; types widened to include more algorithms.
  • Upgrade notes

    • If .npmrc points @preeternal to GitHub Packages, switch to npmjs.com.
    • iOS: run pod install after upgrading.
    • Android: ensure kotlinx-coroutines-android is available in your build.

v1.0.4

20 Jul 13:45

Choose a tag to compare

  • Fixed compatibility with React Native New Architecture (TurboModules) on Android.
  • Now the library works seamlessly with both legacy and new architectures.
  • Improved module registration and codegen integration for Android.
  • Minor internal refactoring.
    Full Changelog: v1.0.2...v1.0.4