Skip to content

Releases: react-native-quickjs/quickjs

v1.0.0-alpha.3

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 10 Sep 14:30

Alpha 3 is a major engine update focused on faster startup and better performance across real React Native workloads.

Highlights

  • QuickJS-NG has been updated to v0.16.2.
  • Faster React Native startup: unused functions in precompiled Metro bundles are now loaded on demand. On Android, the representative RN workload improved median bundle loading from 328 ms to 301 ms*.
  • Up to 8.8× faster isolated bytecode loading: a representative 3.3 MB Metro bundle improved from 5.9 ms to 0.67 ms in the host load-only benchmark.
  • RegExp performance more than doubled: the complete benchmark score increased from approximately 825 to over 1,800—about 2.2× faster overall. Matching, searching, splitting, captures, result creation, and common literal, prefix, character-class, and whitespace patterns all benefit.
  • Faster JSON: parsing and serialization now have specialized paths for integer arrays, ASCII strings and keys, dense arrays, ordinary objects, punctuation, and primitive values.
  • More than 4× faster lazy JSON parsing: the repeated-object benchmark improved from approximately 199 μs to 43 μs. Applications can enable lazy parsing for JSON documents of at least 4 KiB with react-native-quickjs.lazyJson.
  • Faster React-style object creation: reusable object shapes and optimized property initialization deliver consistent double-digit gains across representative object-literal workloads.
  • Faster property access: improved inline caches measured React fiber allocation at 1.92× faster, tree rendering at 1.29× faster, and constructor-heavy property stores at 1.36× faster.
  • Faster string search: representative String.prototype.indexOf and includes workloads improved by approximately 8–9%.
  • Faster bytecode verification: CRC-32C checksums now use hardware acceleration on supported ARM64 and x86-64 devices.
  • Safer precompiled bytecode: validation and failure handling have been strengthened for malformed bundles, function boundaries, nested functions, closures, async and generator functions, RegExp metadata, debugging information, and repeated failed loads.

v1.0.0-alpha.2

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 05 Sep 06:02

What's new

  • Fix: the engine's @react-native-quickjs/text-encoding dependency is now pinned exactly to 1.0.1. The previous 1.0.0 pin let npm nest a second copy of the module under the engine's own node_modules, which broke the folded Android build for consumers — the engine's CMake configured the same module twice and failed. An app on this engine dedupes to the single top-level text-encoding@1.0.1.
  • Release safety: scripts/release.js gained a module-dependency guard. It refuses a release if any @react-native-quickjs/* workspace module the engine depends on is pinned to a range (^/~), is out of sync with the module's current version, or points at a version that is not published — the three ways a consumer ends up with a nested, duplicate module copy.
  • Example app updated to React Native 0.85.3 (babel/metro/typescript configs matched).

v1.0.0-alpha.1

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 05 Sep 05:38

What's new

  • Android native modules are folded into the engine's single .so. react-native-quickjs-text-encoding and react-native-quickjs-intl no longer ship their own JNI libraries; the autolinker whole-archives their core and platform JNI into libquickjsinstancejni.so, so an app loads one .so instead of three. Same on the iOS side, which compiles the generated module registry into the app target.
  • New: @react-native-quickjs/intl. Full ECMA-402 Intl backed by the OS's own CLDR (Foundation on Apple, android.icu on Android) — no locale data ships in the bundle. Opt-in and lazy: an app that never touches Intl pays one property access. DateTimeFormat, NumberFormat, Collator, PluralRules, RelativeTimeFormat, ListFormat, DisplayNames, Segmenter, Locale, DurationFormat, plus the toLocale*/localeCompare ECMAScript methods.
  • CI workflows for the native modules (intl, text-encoding), running their host test suites only when the module's files change.
  • A release script (npm run release:module) that guards, tests, bumps and publishes any module under modules/.
  • Engine fix: a stripped-bytecode function now stringifies as [stripped source] instead of masquerading as native code.
  • Engine patch count is 8 (up from 6) — listed in engine/patches/README.md.

text-encoding v1.0.1

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 05 Sep 04:52

TextEncoder and TextDecoder for
@react-native-quickjs/quickjs,
per WHATWG Encoding.

npm install @react-native-quickjs/text-encoding@1.0.1

What changed in 1.0.1

  • Android: the module no longer ships its own JNI library. The native
    core and platform JNI are folded into the engine's single
    libquickjsinstancejni.so (whole-archived at build time), so an app loads
    one .so instead of two. The Kotlin half now loads the engine library via
    SoLoader, and the JNI layer captures the JavaVM from its attach call
    rather than a JNI_OnLoad (one per .so).
  • iOS: module headers are private to the pod, keeping jsi.h/quickjs.h
    out of the generated Swift module map.
  • Host/build: the module links whichever JSI target the build defines
    (ReactAndroid::jsi on Android, jsi on the host).

Intl v1.0.0

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 05 Sep 05:15

ECMA-402 Intl for @react-native-quickjs/quickjs,
backed by the operating system's own CLDR database the way Hermes does — no locale data ships in your bundle and none ships in this package.

npm install @react-native-quickjs/intl

An app that installs it needs no other Intl polyfill.

What it provides

Intl.DateTimeFormat · Intl.NumberFormat · Intl.Collator ·
Intl.PluralRules · Intl.RelativeTimeFormat · Intl.ListFormat ·
Intl.DisplayNames · Intl.Segmenter · Intl.Locale ·
Intl.DurationFormat · Intl.getCanonicalLocales · Intl.supportedValuesOf

plus the ECMAScript-side methods that must route to the same backend:
Number.prototype.toLocaleString, BigInt.prototype.toLocaleString,
Array.prototype.toLocaleString, %TypedArray%.prototype.toLocaleString,
String.prototype.localeCompare and its toLocaleUpperCase/toLocaleLowerCase,
and Date.prototype.toLocaleString/toLocaleDateString/toLocaleTimeString.

How it works

  • Algorithm in JS, data in the OS. BCP-47 parsing, option resolution and its getter order, locale negotiation, resolvedOptions, and the class shapes are written once in js/intl.js, byte-identical on every platform. The CLDR data is reached through a narrow platform seam (cpp/IntlPlatform.h) into what iOS and Android already carry.
  • Lazy. Installing defines one accessor on globalThis; reading Intl materializes the implementation and redefines it as a data property. An app that never reads Intl pays one property access.
  • Bytecode. js/intl.js is compiled to QuickJS bytecode at build time against the same engine revision, so materialization costs no parse.
  • Real classes. Ordinary JavaScript classes, so new, instanceof, .prototype and subclassing work.

v1.0.0-alpha.0

v1.0.0-alpha.0 Pre-release
Pre-release

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 03 Sep 08:56

QuickJS as the JavaScript engine for React Native, on Android and iOS.

npm install @react-native-quickjs/quickjs@alpha
npx react-native-quickjs install

React Native 0.85+, New Architecture.

  • jsi::Runtime backed by quickjs-ng,
    plus the JSRuntimeFactory React Native uses to select it. Neither Hermes nor
    JavaScriptCore is linked into the result.
  • Engine compiled from source in the app build. Nothing prebuilt is downloaded.
  • Release bundles compiled to QuickJS bytecode on both platforms.
  • Chrome DevTools debugging over React Native's inspector: breakpoints,
    stepping, call stacks, variable inspection, evaluation.
  • Expo support through a config plugin for npx expo prebuild.
  • Hermes compatibility shim, so libraries linking against Hermes run unmodified:
    worklets, reanimated, gesture-handler, mmkv, nitro-modules, nitro-sqlite,
    unistyles, op-sqlite, quick-crypto, safe-area-context.
  • TextEncoder and TextDecoder via
    @react-native-quickjs/text-encoding.

The engine carries six patches, listed in engine/patches/README.md.

text-encoding v1.0.0

Choose a tag to compare

@ammarahm-ed ammarahm-ed released this 03 Sep 08:54

TextEncoder and TextDecoder for
@react-native-quickjs/quickjs,
per WHATWG Encoding.

npm install @react-native-quickjs/text-encoding

The runtime depends on this package, so an app on QuickJS has both globals
already.

Against the JavaScript polyfill, same runtime, same inputs:

case native polyfill speedup
encode 15 B ascii 127 ns 1472 ns 11.6×
encode 4 KB ascii 4578 ns 294922 ns 64.4×
encode 1.2 KB mixed 782 ns 77148 ns 98.7×
decode 15 B ascii 46 ns 1045 ns 22.7×
decode 4 KB ascii 1190 ns 433594 ns 364.3×
decode 1.2 KB mixed 1976 ns 93750 ns 47.4×