Skip to content

fix!: require React Native 0.83 (Expo SDK 55) - #58

Merged
jkasprzyk17 merged 2 commits into
mainfrom
fix/minimum-react-native-0-83
Oct 18, 2026
Merged

jkasprzyk17 merged 2 commits into
mainfrom
fix/minimum-react-native-0-83

Conversation

@jkasprzyk17

@jkasprzyk17 jkasprzyk17 commented Oct 18, 2026 •

Copy link
Copy Markdown
Collaborator

What does this change?

Raises the minimum to React Native 0.83 / Expo SDK 55 and adds a CI job that builds the example there. Closes #26.

Before React Native 0.82, iOS drops a view that is not recycled without calling invalidate (RCTComponentViewRegistry.mm: 0.81-stable and 0.82-stable differ by exactly that call). For this view, invalidate is the only place Nitro's generated component calls onDropView from. On 0.81 / Expo SDK 54, which the README listed as supported, closed viewers were never torn down. Each kept its PDFView, document, callbacks (so #16 did not apply), search and form, and its loads and pins stayed.

Why 0.83 and not 0.82: no Expo SDK ships 0.82 (SDK 54 has 0.81, SDK 55 has 0.83.10). The example is an Expo app, so 0.83 is the oldest line CI can build.

  • peerDependencies: react-native >=0.83. The README, the migration guide (which still said 0.78+), the research notes and both issue templates now say the same.
  • native-build.yml takes an expo-sdk input. When it is set, the example moves to that SDK (expo install expo@^N --fix) before the unchanged prebuild, pod install, xcodebuild and Gradle steps, and package/node_modules is removed. package/ keeps react-native 0.86.3 as a devDependency, and the library's Android codegen fails on that nested copy with 0.83's parser; an app has no such copy. Without the input nothing changes, so native.yml and release.yml are untouched.
  • native-minimum.yml calls it with SDK 55 weekly, by hand, and on pull requests that edit either workflow, so this PR runs it.

Breaking: apps on React Native 0.81 (Expo SDK 54) or 0.82 fall outside the peer range. The first commit has a BREAKING CHANGE: footer. Keep the ! in the squash title so the release notes call it out.

Not done: gating release.yml on the minimum build. The issue suggests it, but it adds a second macOS job to every release and could block an urgent patch when something breaks on Expo's side.

How was it verified?

Locally on Expo SDK 55 / React Native 0.83.10 (macOS, Xcode 27.1), with the workflow's steps:

  • iOS: prebuild, pod install and xcodebuild of the NitroBetterPdf scheme for the simulator succeed. -[HybridBetterPdfViewComponent invalidate] is in the object file; Nitro compiles it only for React Native 0.82 and newer.
  • Android: :react-native-better-pdf:assembleDebug and testDebugUnitTest succeed, and the 273 JVM tests pass. With package/node_modules left in place, codegen fails with Unable to determine event arguments for "onModeChange".
  • Release build of the example app on an iOS 26.5 simulator (iPhone 17 Pro), with a temporary NSLog in onDropView:
    • 10 open/close cycles of the bundled sample (Maestro) logged onDropView 10 times.
    • Afterwards, heap showed no PDFView, PDFDocument or PDFPage objects.
    • 10 HybridBetterPdfView objects (about 1.3 KB each) remained, waiting for a Hermes GC that a Release build cannot force. The "after a GC" half of the acceptance criterion was therefore not measured here; fix: release closed viewers and their documents #16 measured it on 0.86.
  • The full example app on SDK 55 also needs IPHONEOS_DEPLOYMENT_TARGET=15.1 with Xcode 27.1, because react-native-blob-util's privacy bundle targets iOS 11.0. CI compiles only the library scheme, like the existing job, so it is not affected.
  • The new workflow step has not run on a GitHub runner yet. This PR's Native (minimum) checks are its first run.
  • bun run lint, bun run typecheck, bun run test and actionlint pass.

Not reproduced on 0.81 itself (there is no SDK 54 build). The 0.81 behaviour comes from React Native's source.

Scope

  • Platforms: both (the bug is iOS only; the new floor and the CI job cover both)
  • Android versions: not Android specific

Checklist

  • bun run lint, bun run typecheck and bun run test pass
  • New behavior is covered by a test (JS, Kotlin JVM or an end-to-end flow): covered by the new CI job instead
  • Nitro specs changed? cd package && bun run specs was re-run and package/nitrogen/ is committed with it: not changed
  • Public API changed? docs/api.md, the feature's guide in docs/guides/, the README's capability matrix and docs/api-design.md are updated: not changed
  • Native change? Validated on both iOS and Android (no native code changed; compiled on both at the new floor)
  • Performance claim? A benchmark run on a release build is attached: none
  • Commits follow Conventional Commits
  • Behavior changed without a type change? Say so explicitly above: the peer range narrows, see Breaking

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

Before React Native 0.82, iOS drops a view that is not recycled without
calling invalidate, and invalidate is the only place Nitro's generated
component calls onDropView from for this view. On 0.81 every closed
viewer kept its PDFView, document, callbacks, search and form, its load
kept running and its pin in Caches/BetterPdf/open stayed (#26).

No Expo SDK ships 0.82 (SDK 54 has 0.81, SDK 55 has 0.83.10), so the
floor is 0.83, the oldest line the Expo example builds on. There, in a
Release build of the example on the iOS simulator, 10 open/close cycles
called onDropView 10 times and left no PDFView, PDFDocument or PDFPage;
the 10 HybridBetterPdfView objects left wait for a Hermes GC, which a
Release build cannot force. The library also compiles on Android at
SDK 55, and its JVM tests pass.

The README, the migration guide, the research notes and the issue
templates now state the same minimum.

BREAKING CHANGE: react-native >= 0.83 (Expo SDK 55) is required. React
Native 0.81 (Expo SDK 54) and 0.82 are no longer supported; on 0.81 iOS
never released closed viewers.
native-build.yml takes an expo-sdk input. When set, the example moves to
that SDK with expo install --fix before the unchanged prebuild, pod
install, xcodebuild and Gradle steps, and package/node_modules is
removed. package/ keeps react-native 0.86.3 as a devDependency, and the
library's Android codegen fails on that nested copy with the older
parser. Apps have no such copy.

native-minimum.yml calls it with SDK 55 weekly, by hand, and on pull
requests that edit either workflow. Run locally at SDK 55, the same
steps compile the library for iOS and Android.

Closes #26
@coderabbitai

coderabbitai Bot commented Oct 18, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 457e2981-b559-4fc3-8042-e3289a441722
📥 Commits

Reviewing files that changed from the base of the PR and between b1581d4 and 36a8229.

📒 Files selected for processing: 9
  • .github/ISSUE_TEMPLATE/BUG_REPORT.yml
  • .github/ISSUE_TEMPLATE/BUILD_ERROR.yml
  • .github/workflows/native-build.yml
  • .github/workflows/native-minimum.yml
  • CONTRIBUTING.md
  • README.md
  • docs/architecture/research.md
  • docs/migrating-from-react-native-pdf.md
  • package/package.json

Included review availability: This review used your included allowance. 2 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

📝 Summary

Summary by CodeRabbit

  • Compatibility
    • The minimum supported React Native version is now 0.83, and the minimum Expo SDK version is 55. Expo Go is not supported; use a development build.
  • Build Validation
    • Native builds now include a weekly check against the minimum supported Expo SDK, with an option to select an Expo SDK for builds.
  • Documentation
    • Updated setup, migration, and contribution guidance to reflect the revised version requirements and build checks.

The pull request raises the minimum supported React Native version to 0.83 and Expo SDK version to 55. It adds optional Expo SDK selection to the reusable native build workflow and a workflow that builds the example with SDK 55.

Changes: Minimum native support

Layer / File(s) Summary
Minimum version requirements
package/package.json, README.md, docs/architecture/research.md, docs/migrating-from-react-native-pdf.md, .github/ISSUE_TEMPLATE/BUG_REPORT.yml, .github/ISSUE_TEMPLATE/BUILD_ERROR.yml
The peer dependency and documentation set React Native 0.83 and Expo SDK 55 as minimums. The issue templates now state the React Native 0.83 minimum.
Expo SDK selection in native builds
.github/workflows/native-build.yml
The reusable workflow accepts an optional Expo SDK value. When provided, the iOS and Android jobs install that SDK in example, remove package/node_modules, and print the installed React Native version.
Scheduled minimum-SDK build
.github/workflows/native-minimum.yml, CONTRIBUTING.md
A new workflow runs the native build with Expo SDK 55 on a weekly schedule, manual dispatch, and qualifying pull requests. The contributor guide documents the weekly minimum-SDK example build.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 36a82

This change raises the minimum supported React Native version to 0.83 (Expo SDK 55) and adds a CI build for that minimum. It is an intentional breaking change, and the PR asks to keep the ! in the squash title. No concrete merge-blocking risk was found.

Pre-merge checks: Passed 5 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Linked Issues check Inconclusive Issue #26 requires a consistent minimum, iOS teardown at that minimum, and a CI build. The package peer range, README, migration guide, research notes, and issue templates state React Native 0.83 and … Provide reviewable evidence for React Native 0.83 / Expo SDK 55 that 10 open/close cycles followed by GC leave no HybridBetterPdfView objects, or provide an automated equivalent. Confirm the minimum workflow run if that result is required…
Passed Passed checks: 5 passed
Check name Status Explanation
Title check Passed The title is concise, uses the required type prefix, and accurately describes the main change: raising the minimum React Native and Expo SDK versions.
Description check Passed The description directly explains the dependency changes, CI workflow additions, breaking impact, verification steps, and known limitations.
Out of Scope Changes check Passed The changed files support issue #26. The workflow input and minimum workflow build the example's native library through the Expo SDK 55 environment. The documentation and issue-template updates synchr…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Security Check Passed No medium, high, or critical vulnerability is introduced. The only executable change adds an Expo SDK input to the reusable native-build workflow, but the sole caller supplies the fixed value 55; th…
Full details: Out of Scope Changes check

Explanation

The changed files support issue #26. The workflow input and minimum workflow build the example's native library through the Expo SDK 55 environment. The documentation and issue-template updates synchronize the new support floor. The contributing-guide update documents the new minimum-build check. No unrelated product behavior, API, or release workflow change is demonstrated.

Full details: Docstring Coverage

Explanation

No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0 files. (9 skipped: 9 unsupported.)

Full details: Security Check

Explanation

No medium, high, or critical vulnerability is introduced. The only executable change adds an Expo SDK input to the reusable native-build workflow, but the sole caller supplies the fixed value 55; the value is passed through an environment variable and quoted in the shell command. Both jobs use contents: read, checkout disables persisted credentials, and no secrets or write-capable tokens are exposed. The remaining changes only update documentation, issue templates, and a peer dependency. No prior security threads or current findings require re-reporting.

Full details: Linked Issues check

Explanation

Issue #26 requires a consistent minimum, iOS teardown at that minimum, and a CI build. The package peer range, README, migration guide, research notes, and issue templates state React Native 0.83 and Expo SDK 55. native-minimum.yml invokes the reusable build with SDK 55 on a schedule, manually, and for workflow changes. The existing generated invalidate path applies from React Native 0.82, so it covers the selected floor. The PR reports 10 successful onDropView calls and no remaining PDF objects, but it did not measure the required post-GC HybridBetterPdfView count. The new CI workflow had also not run at review time.

Resolution

Provide reviewable evidence for React Native 0.83 / Expo SDK 55 that 10 open/close cycles followed by GC leave no HybridBetterPdfView objects, or provide an automated equivalent. Confirm the minimum workflow run if that result is required for the conclusion.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@jkasprzyk17
jkasprzyk17 merged commit a86aa16 into main Oct 18, 2026
7 checks passed
@jkasprzyk17 jkasprzyk17 mentioned this pull request Oct 19, 2026
@jkasprzyk17
jkasprzyk17 deleted the fix/minimum-react-native-0-83 branch October 19, 2026 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

React Native 0.81, the documented minimum: iOS never calls onDropView, so closed viewers are never torn down

1 participant