skip to content

Three React Native apps need an in-app PDF viewer; how do you decide between adopting a community native library and building and publishing an in-house one?

level: principalimportance: should knowfreq 25%

answer

  1. New Architecture support first
  2. who upgrades it every release
  3. Expo and bare apps both covered
  4. requirements the library cannot meet
  5. fork or wrap as the middle path

basics

~20 s

Adopt a community library if it supports the New Architecture, meets your requirements, fits Expo and bare apps and is maintained; build in-house only when requirements or risk justify owning two native codebases through every upgrade.

solid answer

~50 s

I start from requirements and total cost of ownership, not from code. A community library is the default if it implements the New Architecture natively (the only architecture since 0.82, with legacy modules running only through the interop layer), covers the features the three apps need, keeps its `react-native` peer range current with each release, works in Expo apps, and has a licence and security posture we accept. Building in-house is justified when requirements are unmet (annotations, rendering fidelity, a security review of document parsing), when no candidate is maintained, or when the viewer is core to the product. Then the cost is real: iOS and Android expertise, a library scaffolded with `create-react-native-library`, a private registry, an example app in CI, and upgrades to track React Native's new minor roughly every two months. Forking or wrapping a community library is often the cheaper middle path.

go deeper

for a junior

Recall that adopting a native library means checking it supports the New Architecture and your React Native version before installing it.

for a middle

Explain the evaluation criteria for a native library: architecture support, peer range, Expo compatibility, maintenance activity and licence.

for a senior

Assess a concrete candidate, estimate the upgrade and staffing cost of owning native code, and propose fork or wrap options with their risks.

for a principal

Own the decision for several apps: total cost of ownership, a named owning team, a support window and the trigger that makes you revisit the choice.

## Frame the decision A native module is not a one-off: once three apps depend on it, whoever owns it owns **two native codebases** (Android and iOS) through every React Native upgrade. So the question is less "can we build a PDF viewer?" and more "who carries it for the next three years?" ## What to check in a community library | Criterion | What good looks like | Why it matters | |---|---|---| | Architecture | Native Turbo Module or Fabric component | The New Architecture is the only one since 0.82; legacy-only code runs through the interop layer, which the React Native team keeps "for the foreseeable future" while promising updates on its eventual removal | | Version support | Peer range tracks current React Native | 2026 minors shipped about every two months (0.84 in February to 0.87 in August) | | Expo compatibility | Works in development builds, config plugin if setup is needed | Some of the three apps may be Expo projects on SDK 57, which runs React Native 0.86 | | Feature fit | Rendering, zoom, search, password-protected files, annotations | A missing core feature means forking anyway | | Maintenance | Recent releases, answered issues, more than one maintainer | Abandonment becomes your problem at the next upgrade | | Licence and security | Licence compatible with your apps; parsing of untrusted files reviewed | PDFs from users are untrusted input | | Cost to the binary | Acceptable size and native dependencies | Three apps pay it | ## When building in-house is justified - **Unmet, stable requirements** that are central to the product, such as signing workflows or strict rendering fidelity. - **Risk** you cannot accept from a third party: an unmaintained dependency, a licence problem, or native parsing code you must audit. - **Reuse across several apps** that makes a well-owned package cheaper than three sets of workarounds. ## What building really costs 1. **Scaffold** with `npx create-react-native-library@latest`: a Fabric view for page rendering, perhaps a Turbo Module for search, and an example app. 2. **Staffing**: Kotlin and Swift or Objective-C skills, or a shared C++ core for platform-independent parts. 3. **Packaging**: `react-native` and `react` as peer dependencies with a tested range, autolinking-friendly layout, a podspec, published to a private registry with semantic versioning. 4. **Verification**: CI that builds the example app on both platforms for every supported React Native version. 5. **Upgrades**: each React Native release can change native APIs; the library must move before the three apps can. ## The middle paths - **Fork** a good community library, fix what you need, and upstream the fixes. - **Wrap** a library behind your own thin JavaScript API, so the three apps do not depend on its surface and you can swap it later. - **Sponsor or contribute** to the maintainer, which is often cheaper than ownership. - **Expo Modules API**: for Expo-first teams, writing the module with Expo's own module API is another option; the React Native Turbo Module route is not the only one. ## Signals to revisit the decision 1. The adopted library misses a React Native release and blocks an app upgrade. 2. A security issue in its document parsing goes unanswered. 3. The apps need a feature it will not accept upstream. 4. The in-house library's owning team shrinks or moves on. 5. Expo or React Native ships a built-in capability that makes either option unnecessary. Writing these triggers down turns a one-time choice into a decision with a review date. ## A defensible recommendation For most teams: adopt the best-maintained New Architecture library, wrap it behind an internal API, and schedule a review at each React Native upgrade. Build in-house only with a named owning team, a support window written down, and an explicit budget for upgrades. Whatever you choose, record the decision and its trigger for revisiting it, such as the library missing a React Native release.

  • The best community library is legacy-architecture only. Can you still use it on 0.87?
    Possibly, through the New Architecture's interop layer, which the React Native team keeps for the foreseeable future. But you inherit the risk of its eventual removal and of subtle behaviour differences, so treat it as a stopgap: plan a migration, contribute one upstream, or replace it.
  • How do you stop three apps from being blocked by the library at every upgrade?
    Give the library a written support window as a peer range, run CI against the next React Native release candidate, and release library updates ahead of app upgrades. Wrapping it behind an internal API keeps app code stable when the library changes underneath.

saying these in an interview costs you the question

  • Building in-house is always cheaper because there is no dependency risk
  • Any library that installs cleanly is compatible with the New Architecture
  • Once written, a native module needs no work across React Native upgrades
  • Popularity alone proves a library is maintained and secure
  • An Expo app can use any native library in Expo Go without a new build