Releases: react-native-quickjs/quickjs
Release list
v1.0.0-alpha.3
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.indexOfandincludesworkloads 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
What's new
- Fix: the engine's
@react-native-quickjs/text-encodingdependency is now pinned exactly to1.0.1. The previous1.0.0pin let npm nest a second copy of the module under the engine's ownnode_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-leveltext-encoding@1.0.1. - Release safety:
scripts/release.jsgained 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
What's new
- Android native modules are folded into the engine's single
.so.react-native-quickjs-text-encodingandreact-native-quickjs-intlno longer ship their own JNI libraries; the autolinker whole-archives their core and platform JNI intolibquickjsinstancejni.so, so an app loads one.soinstead of three. Same on the iOS side, which compiles the generated module registry into the app target. - New:
@react-native-quickjs/intl. Full ECMA-402Intlbacked by the OS's own CLDR (Foundation on Apple,android.icuon Android) — no locale data ships in the bundle. Opt-in and lazy: an app that never touchesIntlpays one property access.DateTimeFormat,NumberFormat,Collator,PluralRules,RelativeTimeFormat,ListFormat,DisplayNames,Segmenter,Locale,DurationFormat, plus thetoLocale*/localeCompareECMAScript 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 undermodules/. - 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
TextEncoder and TextDecoder for
@react-native-quickjs/quickjs,
per WHATWG Encoding.
npm install @react-native-quickjs/text-encoding@1.0.1What 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.soinstead of two. The Kotlin half now loads the engine library via
SoLoader, and the JNI layer captures theJavaVMfrom its attach call
rather than aJNI_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::jsion Android,jsion the host).
Intl v1.0.0
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/intlAn 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 injs/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; readingIntlmaterializes the implementation and redefines it as a data property. An app that never readsIntlpays one property access. - Bytecode.
js/intl.jsis 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,.prototypeand subclassing work.
v1.0.0-alpha.0
QuickJS as the JavaScript engine for React Native, on Android and iOS.
npm install @react-native-quickjs/quickjs@alpha
npx react-native-quickjs installReact Native 0.85+, New Architecture.
jsi::Runtimebacked by quickjs-ng,
plus theJSRuntimeFactoryReact 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. TextEncoderandTextDecodervia
@react-native-quickjs/text-encoding.
The engine carries six patches, listed in engine/patches/README.md.
text-encoding v1.0.0
TextEncoder and TextDecoder for
@react-native-quickjs/quickjs,
per WHATWG Encoding.
npm install @react-native-quickjs/text-encodingThe 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× |