Skip to content

fix(ios): vendor RaTeX as a prebuilt static XCFramework (drop spm_dependency) - #652

Merged
eszlamczyk merged 2 commits into
mainfrom
fix/ios-ratex-vendored-xcframework
Aug 11, 2026
Merged

fix(ios): vendor RaTeX as a prebuilt static XCFramework (drop spm_dependency)#652
eszlamczyk merged 2 commits into
mainfrom
fix/ios-ratex-vendored-xcframework

Conversation

@eszlamczyk

@eszlamczyk eszlamczyk commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

What / Why?

iOS LaTeX math (RaTeX) was integrated via React Native's spm_dependency, i.e. RaTeX was consumed as a Swift Package inside a CocoaPods target. That interop is the root cause of a cluster of iOS build failures - several of which persist despite earlier workarounds:

This PR replaces spm_dependency with a vendored, prebuilt, already-signed static RaTeX XCFramework, removing the mechanism behind all of the above. It mirrors the existing tree-sitter vendoring pattern (pinned + sha256-verified, gitignored, restored on prepare/prepack).

Root cause and fix

Failure Why (SPM) Why vendoring removes it
#491 signature collision SPM product target and pod target both sign-collect the same XCFramework one target, one XCFramework → one signature
#527 x86_64 per-arch swiftmodule built at app-build time prebuilt XCFramework already contains the ios-arm64_x86_64-simulator slice
redefinition of module 'RaTeXFFI' spm_dependency generates a duplicate modulemap XCFramework ships its own modulemap
signing / Rust clone SPM builds + signs RaTeX at archive time prebuilt binary, fetched once, pinned by sha256
forced dynamic frameworks SPM interop static XCFramework links under CocoaPods default static linkage

Changes

  • vendor/ratex-version.json + vendor/vendor-ratex.mjs - pin RaTeX v0.1.14 and restore (sha256-verified) the XCFramework + RaTeX core Swift + KaTeX fonts into gitignored packages/react-native-enriched-markdown/ios/vendor/. Wired into the package prepare and prepack hooks.
  • ReactNativeEnrichedMarkdown.podspec - adds vendored_frameworks + the RaTeXCoreFonts resource bundle; deletes the EXCLUDED_ARCHS, the Fix RaTeXFFI Module Redefinition (sed), and the Dedupe RaTeX XCFramework Signature (rm) workarounds, and the spm_dependency call.
  • ENRMRaTeXBridge.swift - drops import RaTeX (RaTeX core is now same-module).
  • EnrichedMarkdownCore.podspec - DEFINES_MODULE = YES so the Swift-containing pod links under default static linkage with no consumer Podfile changes.
  • Example Podfile - removes the forced dynamic frameworks. Docs updated (docs/LATEX_MATH.md).

Testing

Reproduced the failure on main, then verified the fix (Apple Silicon, Xcode 26.6):

  • iOS archive fails on Xcode 26: “RaTeX.xcframework-ios.signature” (0.7.x, math enabled) #491 (baseline red): simulator archive fails rc=70 on RaTeX.xcframework-ios-simulator.signature. After - archive assembles, no collision.
  • iOS RaTeX math dependency breaks x86_64 simulator builds in react-native-enriched-markdown >= 0.7 #527 (verified without an Intel Mac): lipo shows x86_64 arm64 in the vendored simulator slice, and the example app links for x86_64 (-target x86_64-apple-ios-simulator … -lratex_ffi).
  • Default static linkage: pod install succeeds with no use_frameworks! and no use_modular_headers!; the app links libReactNativeEnrichedMarkdown.a (static) instead of Pods_EnrichedMarkdownExample.framework (dynamic).
  • Cold clean build (run-ios path, fresh DerivedData) succeeds.
  • Math off (ENRICHED_MARKDOWN_ENABLE_MATH=0): RaTeX fully excluded, installs clean.
  • Runtime: formulas render correctly on the simulator (KaTeX fonts load from the RaTeXCoreFonts bundle under static linkage).

Note

Upgrading from a version that used use_frameworks! :linkage => :dynamic for
math requires a one-time clean build
(Product → Clean Build Folder / delete
DerivedData). Switching the pod from a dynamic framework to a static library
leaves stale module artifacts; a stale build otherwise fails with
ReactNativeEnrichedMarkdown.framework/Modules/module.modulemap not found.
Fresh installs are unaffected. This is documented in docs/LATEX_MATH.md.

PR Checklist

  • Code compiles and runs on iOS
  • Code compiles and runs on Android (unaffected by this change)
  • Updated documentation/README if applicable
  • Ran example app to verify changes
  • E2E tests are passing
  • Required E2E tests have been added (if applicable)

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR switches the iOS LaTeX math integration (RaTeX) from React Native’s spm_dependency-based build-time SPM wiring to a vendored, prebuilt static RaTeX.xcframework plus the minimal required RaTeX Swift sources and KaTeX fonts, restored on demand and bundled into the published npm tarball.

Changes:

  • Add a vendor restore script + pin file to fetch/verify/extract the prebuilt RaTeX XCFramework and required assets into ios/vendor/.
  • Update the iOS CocoaPods integration to link the vendored XCFramework/resources under default static linkage (no use_frameworks!, no spm_dependency).
  • Update docs and example apps to reflect the new static-linking workflow and remove the old SPM pin.

Reviewed changes

Copilot reviewed 10 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
vendor/vendor-ratex.mjs New restore script to fetch/verify and populate the gitignored RaTeX vendor tree.
vendor/ratex-version.json New pin manifest for the RaTeX tag plus sha256s and required source/font paths.
scripts/prepare-npm-publish.sh Runs the RaTeX vendor restore during prepack so the npm tarball includes iOS math assets.
packages/react-native-enriched-markdown/ReactNativeEnrichedMarkdown.podspec Replaces spm_dependency integration with vendored_frameworks + resource bundle and updated exclusions.
packages/react-native-enriched-markdown/package.json Adds vendor-ratex script and runs it as part of prepare.
packages/react-native-enriched-markdown/ios/math/ENRMRaTeXBridge.swift Removes import RaTeX and documents that vendored sources now compile into the pod’s module.
packages/core/EnrichedMarkdownCore.podspec Defines a module (DEFINES_MODULE=YES) to support Swift dependency under static linkage in the monorepo.
docs/LATEX_MATH.md Updates setup/upgrade guidance to reflect the new static XCFramework approach.
apps/react-native-macos-example/macos/Podfile Updates comment explaining macOS math remains disabled despite the old use_frameworks! blocker being removed.
apps/react-native-example/ios/Podfile.lock Updates lockfile after Pod configuration changes.
apps/react-native-example/ios/Podfile Removes dynamic frameworks env wiring; notes static vendored RaTeX approach.
apps/react-native-example/ios/EnrichedMarkdownExample.xcworkspace/xcshareddata/swiftpm/Package.resolved Removes the RaTeX SPM resolution file now that SPM is no longer used.
apps/react-native-example/ios/EnrichedMarkdownExample.xcodeproj/project.pbxproj Updates example project linkage from Pods framework to static Pods archive.
.gitignore Ignores the generated packages/react-native-enriched-markdown/ios/vendor/ directory.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@eszlamczyk
eszlamczyk force-pushed the fix/ios-ratex-vendored-xcframework branch from efacbe0 to 13c38dc Compare August 11, 2026 13:46
@eszlamczyk
eszlamczyk marked this pull request as ready for review August 11, 2026 19:31
@eszlamczyk
eszlamczyk merged commit 94ea7e0 into main Aug 11, 2026
9 checks passed
@eszlamczyk
eszlamczyk deleted the fix/ios-ratex-vendored-xcframework branch August 11, 2026 19:31
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.

3 participants