chore(rn-run): pin rnrun 0.2.3 - #29
Open
sanketsahu wants to merge 7 commits into
Open
Conversation
0.2.3 (with browser-metro 1.3.0) fixes invisible text on native: NativeWind's remapProps components — KeyboardAvoidingView, FlatList, ImageBackground — pass an opaque placeholder style to their children, and resolving it needs the css-interop JSX wrapper active inside the package chunk. rnrun compiles those chunks against the real react/jsx-runtime, so every descendant Text lost its resolved style: default black at no font size, which on a dark theme renders as nothing and collapses the layout. 0.2.3 also versions native dep hashes, so a server-side change to native output mints new hashes and every cache layer misses instead of serving stale bytes. Co-Authored-By: Claude Fable 5 <[email protected]>
0.2.5 fixes a deterministic device crash: any screen using FlatList redboxed with "property is not configurable". esbuild lowered class fields with spec semantics (defineProperty) while the RN ecosystem is compiled with loose class fields (plain assignment), and VirtualizedList declares `state` where [[Define]] is rejected but [[Set]] succeeds. Diagnostic signature: __publicField or __defNormalProp frames in a device stack trace. It also folds the native-deps version into /pkg and /prelude URLs and the server's per-package cache keys, so a change to native bundling output is unreachable through any stale cache layer by construction — no more hand-wiping the on-box cache after a server fix. --prewarm ios moves the cold build off the critical path: a scale-to-zero container boots, idles, and today the first device to scan waits out the whole build. iOS only, because a cold build is CPU-bound at the package server and build time tracks concurrency more than dep count. Co-Authored-By: Claude Fable 5 <[email protected]>
0.3.0 caches the assembled bundle to disk, keyed by platform, tool versions, project sources, assets, inlined env and the bundler flags. Until now every container start rebuilt the bundle from scratch, and because containers scale to zero the QR scan was usually what started the container — so the phone waited out a 30-90s rebuild of bytes the same container had produced minutes earlier. Measurements that drove this (same project, warm package cache, 12.3MB bundle): gVisor/4cpu/1GB 31.6s bundling and 86s wall; gVisor/8cpu/2GB 31.0s and 75s; runc/8cpu/2GB 25.4s and 43s. Doubling CPU bought nothing, so the fix was to stop redoing the work rather than to buy more machine. 0.3.0 also makes --prewarm exclusive: startup previously built a web bundle unconditionally, so a container woken by a phone scan built web first and then iOS. Web is now deferred to the first browser request. The cache lives under HOME, which is the container's writable layer, and our suspend is `docker stop` on the same container — so it survives a normal scale-to-zero wake. Only container recreation loses it. Co-Authored-By: Claude Fable 5 <[email protected]>
0.3.0 (and 0.2.7, which introduced the lean fetch) resolves the reanimated
worklets babel plugin by symlinking into rnrun's own node_modules. This image
installs rnrun with `npm install -g`, whose flattened layout has no such path,
so the fetch fails, the full-install fallback fails too, and every bundle is
built with the plugin disabled:
[worklets] fetched plugin did not load; falling back to a full install
[worklets] plugin install failed (ENOENT: ... lstat
'/usr/local/lib/node_modules/rnrun/node_modules/react-native-worklets');
reanimated worklets will not run.
All 8 live containers reported it, meaning every project would ship animations
that cannot run — worse than the slow wakes 0.3.0 was meant to fix. 0.2.5 uses
the older full-install path, which works here.
The disk bundle cache in 0.3.0 is otherwise verified good: a warm start serves
in 0.19s versus a 30-90s rebuild, --prewarm does not bypass it, and the web
build is correctly deferred. Re-pin once the plugin resolves against a global
install (or once the plugin can be baked via RNRUN_TOOLS_DIR).
Co-Authored-By: Claude Fable 5 <[email protected]>
Two corrections to the 0.3.0 roll, both found by measuring real production wakes rather than fresh-container tests: 1. gVisor wipes the container writable layer on docker stop/start. rnrun's disk bundle cache lives under HOME=/cache in that layer, so it never survived a scale-to-zero wake — every wake rebuilt (measured: writable layer 114M before stop, 14M and 0 cache entries after start). Redirect the two expensive caches (RNRUN_BUNDLE_CACHE_DIR, RNRUN_TOOLS_DIR) to /data, the per-mobile-workload bind mount, which is real host storage. pkg-cache stays ephemeral: a bundle-cache hit serves instantly, only the background rebuild re-fetches. 2. Drop --prewarm. With a persistent cache, --prewarm is actively harmful: it rebuilds unconditionally on start, and a scan arriving mid-rebuild coalesces onto it (~32s) instead of reading the cache. Without it the serve path hits the cache directly. Result on a live project: cold first build 38s (once), then a real suspend/wake serves the iOS bundle in 0.67s (was 32-90s). Worklets enabled throughout. 0.3.1 also fixes the worklets plugin resolution under a global npm install that made 0.2.7/0.3.0 unusable here (reanimated silently disabled). Co-Authored-By: Claude Fable 5 <[email protected]>
0.3.2 makes the Fast-Refresh module-graph rebuild lazy (built on first edit) instead of firing on every cache hit, so --prewarm ios is now a true no-op on a warm cache — verified on a real stop/start wake: 0.19s serve, no rebuild. Restore it so a genuinely-cold project warms during idle rather than making its first-ever scan pay the ~38s build, without the per-wake penalty 0.3.1 had. Also add RNRUN_PKG_CACHE_DIR=/data/.rnrun/pkg (new in 0.3.2): the package cache was still under HOME in the ephemeral layer and re-fetched every wake. All three rnrun caches now co-locate on the persistent /data mount. Co-Authored-By: Claude Fable 5 <[email protected]>
0.3.3 adds the expo-web SPA deep-path fallback (reactnative-run #70): a browser navigation (Accept: text/html) to a deep route with no file extension and not a dev-server/manifest/asset path now serves the same index.html as /, so expo-router resolves the route client-side instead of 404ing. Fixes /login etc. on a primary rnrun web host rendering "Not found: /login". Native/Expo-Go behavior unchanged; bare (non-navigation) requests to unknown paths still 404 by design so real misses aren't masked. Also carries the bun-install fail-fast, pre-warm, tailwindcss stub, chunk cache, and lazy graph merged since 0.3.2. Verified live on rapidnative-app-8zenm.rapidnative.app: /login and /some/deep/route (Accept: text/html) -> 200 byte-identical to /; /login no-Accept -> 404; /index.bundle -> 200 js. Worklets enabled, real builds unaffected (a project with a syntax error in theme.ts errors identically on 0.3.2 and 0.3.3). Co-Authored-By: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps the preset image's rnrun pin to 0.2.3 (ships browser-metro 1.3.0).
Why: 0.2.1 rendered every
<Text>invisible on native in NativeWind apps. NativeWind styles components two ways —cssInterop()swaps the component (works, because app-level JSX resolves it), whileremapProps()components (KeyboardAvoidingView,FlatList,ImageBackground) pass an opaque placeholder style down to their children. Resolving that placeholder needs the css-interop JSX wrapper active for the JSX inside the package chunk. Metro gets this free by aliasingreact/jsx-runtimeglobally; rnrun's per-package chunks compile against the real runtime, so package-internal JSX bypassed the wrapper and every descendantTextlost its style — default black at no font size, invisible on a dark theme with zero layout height.0.2.3 also adds a native-deps version to bundle hashes, which structurally prevents stale native bytes being served from any cache layer.
Verified on the box: rebuilt image reports
[email protected]/browser-metro 1.3.0; served iOS bundles now containjsx-runtime__original(the wrapper marker) and 437–507__workletHashentries (correctly workletized reanimated, versus 8 in the poisoned bundles). Fleet migrated: suspended mobile containers removed so their next wake creates fresh, and the running ones restarted.🤖 Generated with Claude Code