Skip to content

JimmyDaddy/react-native-bs-diff-patch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

react-native-bs-diff-patch

Create a compact binary patch from two versions of a file, then reconstruct the new version from the old file and that patch. Android, iOS, and React Native Web all use the compatible ENDSLEY/BSDIFF43 wire format.

Documentation · Playground · 中文说明 · npm

Why use it?

  • One patch format: generate on one supported runtime and apply on another.
  • Both React Native architectures: legacy bridge and TurboModule/New Architecture.
  • Responsive by default: native work uses dedicated serial queues; Web work reuses a module Worker and cached WebAssembly instance off the page thread.
  • Bound untrusted Web work: built-in cancellation and input/output byte limits reject predictably with stable error codes.
  • No Web service required: the browser implementation is the same bundled C core compiled to WebAssembly.
Runtime Input model Create a patch Apply a patch
Android, iOS Absolute paths diff patch
Web In-memory binaries diffBytes patchBytes

Installation

npm install react-native-bs-diff-patch

After adding the package, install iOS pods and rebuild the native app:

npx pod-install

React Native autolinking handles native registration. A Metro reload alone is not enough after adding a native dependency.

Native quick start

The native API works with absolute file paths. Use the filesystem library already present in your app to select a writable cache directory.

import { diff, patch } from 'react-native-bs-diff-patch';

type NativeRoundTripOptions = {
  oldFilePath: string;
  newFilePath: string;
  cacheDirectory: string;
};

export async function nativeRoundTrip({
  oldFilePath,
  newFilePath,
  cacheDirectory,
}: NativeRoundTripOptions) {
  const runId = Date.now();
  const patchPath = `${cacheDirectory}/update-${runId}.patch`;
  const restoredPath = `${cacheDirectory}/restored-${runId}.bin`;

  await diff(oldFilePath, newFilePath, patchPath);
  await patch(oldFilePath, restoredPath, patchPath);

  return { patchPath, restoredPath };
}

Output paths must not exist, all paths in one call must be different, and the required input files must already exist. Both functions resolve to 0 on success.

React Native Web quick start

import { diffBytes, patchBytes } from 'react-native-bs-diff-patch';

export async function webRoundTrip(
  oldFile: File,
  newFile: File,
  signal?: AbortSignal
) {
  const oldData = await oldFile.arrayBuffer();
  const newData = await newFile.arrayBuffer();
  const options = {
    signal,
    maxInputBytes: 64 * 1024 * 1024,
    maxOutputBytes: 64 * 1024 * 1024,
  };
  const patchData = await diffBytes(oldData, newData, options);
  const restoredData = await patchBytes(oldData, patchData, options);

  return { patchData, restoredData };
}

diffBytes and patchBytes accept ArrayBuffer, any ArrayBufferView (including typed arrays and DataView), or Blob. They resolve to a new Uint8Array and leave the caller's buffers usable. Aborted operations reject with EABORTED; configured size limits reject with ERESOURCE.

Platform API matrix

API Android iOS Web
diff(oldPath, newPath, patchPath) Yes Yes No
patch(oldPath, outputPath, patchPath) Yes Yes No
diffBytes(oldData, newData, options?) No No Yes
patchBytes(oldData, patchData, options?) No No Yes
Legacy architecture Yes Yes N/A
New Architecture / TurboModule Yes Yes N/A

Calling an API family that is unavailable on the current platform rejects with EUNSUPPORTED instead of silently choosing different behavior.

Production checklist

  • Verify the restored output before replacing application data.
  • Authenticate patches from remote or otherwise untrusted sources.
  • Use unique native output paths and clean temporary files after success or failure.
  • Set product-specific input-size and time limits; binary diffing can use several times the input size in peak memory.
  • Generate and apply patches with this library. Generic BSDIFF40 patches are not interchangeable with ENDSLEY/BSDIFF43 patches.

See Production recipes for error handling, downloads, cross-runtime patch exchange, and integrity checks.

CI directly compiles the Android New Architecture sources against React Native 0.73.11, 0.74.7, and 0.86.0. Packed-consumer tests also verify that browser, ESM, CommonJS, and TypeScript resolution work without installing optional React Native peers for Web-only consumers.

Documentation

Contributing

See CONTRIBUTING.md for the local workflow and quality gates. Release history is in CHANGELOG.md; security reports follow SECURITY.md.

License

MIT

About

Binary diff and patch for React Native Android, iOS, and Web

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

6 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors