Skip to content
useffect.sh
Book 30 min with a senior
Guide · Audit

React Native app audit: what to check, how long, which deliverables

An audit exists to support a decision: stabilize, upgrade, take over or rewrite. To do that, it has to read the code, measure the app on a real build and produce a document that ranks. Here is what it should cover, what you can check yourself, and what to require.

By Jérémy Magrin ·

Short answer

A serious audit of a React Native or Expo app covers versions and the upgrade path, the New Architecture, dependency health, native modules, build and CI, performance measured on a production build, crashes and observability, basic security, compliance with store requirements, code quality and tests. It relies on read access to the repo, the crash reports and the CI, and ends with a written document that ranks risks by impact and offers costed options, not with a list of a hundred remarks. Before paying anyone, you can check your dependencies yourself with a free stack audit, Expo Doctor and React Native Directory. At useffect.sh, the audit takes five days with one senior engineer and produces a diagnosis of three pages at most. Be wary of an audit without measurements on a production build, without access to the code, or one that concludes with a rewrite by default.

People ask for an audit when something worries them: a crash-free session rate going down, an upgrade that is stuck, an app inherited from a vendor, a funding round coming up. The audit has a single purpose: to let you decide. This guide describes what it should cover point by point, with the official references that set the requirements, what you can check yourself before paying anyone, the deliverables to require, and the red flags in an offer.

What an audit should cover

AreaWhat gets checkedReference
Versions and upgradeReact Native or Expo SDK version, gap with maintained versions, upgrade pathReact Native releases (opens in a new window)
New ArchitectureEnablement, compatibility of each library, in-house native modulesReact Native 0.82 (opens in a new window)
DependenciesKnown vulnerabilities, archived or unmaintained libraries, versions misaligned with the Expo SDK, patchesReact Native Directory (opens in a new window), Expo Doctor (opens in a new window)
Native modulesIn-house Swift, Objective-C, Kotlin or Java code, third-party SDKs, config pluginsCode reading
Build and CIReproducibility, Xcode and JDK versions, EAS or in-house CI, signing, build timeApple requirements (opens in a new window)
OTA updatesChannel, runtime version, rollback strategyExpo runtime versions (opens in a new window)
PerformanceCold start, navigation, lists, network, bundle size, on a production buildReact Native performance (opens in a new window)
Crashes and observabilityCrash reporter, symbolication, crash and ANR ratesAndroid vitals (opens in a new window)
Basic securitySecrets in the bundle, token storage, public variablesReact Native security (opens in a new window)
Store complianceTarget SDK, required reason APIs, account deletionGoogle Play target API (opens in a new window), App Review Guidelines (opens in a new window)
Code and testsStructure, module boundaries, tests on critical flowsCode reading

Versions and upgrade path

The React Native team commits to maintain (opens in a new window) "the latest 3 minor series", with a new minor version roughly every two months. An older version no longer gets fixes. The audit should say where you stand, which target to aim for, and through which steps. The Upgrade Helper (opens in a new window) shows the native file diff between two versions; on Expo, each SDK targets one React Native version.

New Architecture

Since React Native 0.82 (opens in a new window) (October 8, 2025), the New Architecture is the only one: newArchEnabled=false and RCT_NEW_ARCH_ENABLED=0 are ignored. The team recommends going through React Native 0.81 or Expo SDK 54 first, "the last versions that allow you to use the Legacy Architecture". For an app still on the old architecture, this is often the main workstream, and the audit should list the libraries and native modules that block it.

Dependency health

This is the most mechanical part, and the one you can do yourself (see below). The audit goes further: it looks at patches applied with patch-package, internal forks, and transitive native dependencies. At the end of October 2026, React Native Directory (opens in a new window) listed about 2,800 packages, 71% of which support the New Architecture: about three libraries in ten either don't or haven't declared it.

Native modules, build and CI

In-house native code is often what costs the most during an upgrade. The audit inventories it, checks that it runs on the New Architecture, and looks at whether it could become a config plugin or an Expo Module. On the build side, the question is simple: can a new developer produce a release build from a fresh machine, and does the CI do it without manual steps? Tool versions matter: since April 28, 2026, Apple requires (opens in a new window) apps to be "built with Xcode 26 or later using an SDK for iOS 26". From April 2027 it will be the iOS 27 SDK, with a mandatory move to the UIScene life cycle: see our Xcode 27 guide.

If the app uses OTA updates, the audit checks the runtime version. Expo describes it as the property that "guarantees compatibility between a build's native code and an update"; a runtime version that doesn't follow native changes ships JavaScript to a build that cannot run it.

Performance

A measurement in development mode is worthless. The React Native documentation (opens in a new window) is clear: "JavaScript thread performance suffers greatly when running in dev mode", and "Always make sure to test performance in release builds". So the audit measures on a production build, on real phones, including low-end Android devices: cold start, navigation, long lists, network requests, bundle size. The same page notes that console.log calls left in a production bundle "can cause a big bottleneck in the JavaScript thread".

Crashes and observability

A crash reporter should be in place, with symbolicated traces on both platforms. On Android, Google publishes thresholds: in Android vitals (opens in a new window) (page updated October 19, 2026), the user-perceived crash rate should stay below 1.09% overall and 8% per phone model, the ANR rate below 0.47% and 8%. Beyond that, "Play may reduce the visibility of your title". The audit reports these numbers and ties them to their causes.

Basic security

An app audit is not a penetration test, but it must check the basics. The React Native documentation (opens in a new window) is explicit: "Never store sensitive API keys in your app code", because anything in the bundle can be read in plain text. Async Storage is "unencrypted" and must not hold tokens; use secure storage such as expo-secure-store, which relies on the iOS Keychain and on keys protected by the Android Keystore. On Expo, EXPO_PUBLIC_ variables are visible (opens in a new window) "in plain-text in your compiled application". These are the mistakes we find most often in apps generated too fast.

Store compliance

Requirements move every year, and an old React Native version eventually stops passing. Since August 31, 2026, Google Play requires (opens in a new window) new apps and updates to target Android 16 (API level 36). Since May 1, 2024, Apple requires (opens in a new window) approved reasons for certain APIs, "including from third-party SDKs". And guideline 5.1.1(v) of the App Review Guidelines (opens in a new window) requires that an app supporting account creation also offer account deletion within the app.

Code quality and tests

This is what sets the cost of every future change. The audit looks at module boundaries, state management, duplication, and above all whether critical flows are tested: sign-in, payment, data. An app without tests is not necessarily bad, but every fix in it is a bet.

Self-checking before you pay

Part of the audit can be automated, and you can do it before calling anyone.

  1. Run our free stack audit. Paste your package.json, add your lockfile for exact versions: in 30 seconds it flags known vulnerabilities, overdue major updates, archived or unmaintained libraries, New Architecture compatibility according to React Native Directory, a subset of Expo Doctor checks, and the age of your dependencies in libyears. Nothing is stored.
  2. On an Expo project, run npx expo-doctor. The tool is used "to diagnose issues in your Expo project" and can check your packages (opens in a new window) against React Native Directory. npx expo install --fix realigns versions with your SDK.
  3. Compare your version with the maintained ones on the releases page (opens in a new window).
  4. Open Android vitals and your crash reports for the last thirty days, and note the three most frequent crashes.
  5. Search the code for secrets: API keys, tokens, admin URLs, sensitive EXPO_PUBLIC_ variables.
  6. Produce a release build from a fresh machine, following only the repo's documentation.

If everything is green, you start from a solid base; performance on real devices, architecture and prioritization remain, and this list does not cover them. If several points are red, at least you will know what to ask for.

How long to plan for

Duration depends on the size of the app, the number of platforms and repos, and the state of the CI: you need to be able to produce a production build to measure. There is no public norm; here is how to reason about it.

An audit needs time for three distinct things. Reading the code and its history, to understand how the app was built and where the fragile areas are. Measuring, on a release build and on real devices, what users actually experience. And writing a document that ranks and costs, then presenting it to the team. An audit that skips one of these steps gives an opinion, not a diagnosis.

At useffect.sh, the format is fixed: five days with one senior. Day one covers access and reading the history, days two to four profiling on a production build and reviewing the architecture, dependencies, security and release pipeline, and day five the written diagnosis and the walkthrough. The scope covered (platforms, repos) is agreed in a 30-minute call, before starting.

The deliverables to require

A useful audit ends with a short document, not a linter export. Require:

  • A written diagnosis, readable by a founder as well as a developer.
  • Ranked risks, by impact and effort, not a flat list.
  • Performance measurements on a production build, with the devices used.
  • A dependency review and the upgrade path.
  • Costed options, from a targeted fix to a full takeover.
  • A walkthrough with your team, questions included.

That is exactly the format of our React Native app audit: five days, one senior in your repo with read-only access, a diagnosis of three pages at most, ranked risks, costed options and a walkthrough. The document is yours, whatever comes next.

Red flags in an audit offer

  • No access to the code. An audit based on interviews and screenshots is an opinion, not a diagnosis.
  • No measurement on a production build. Performance measured in development mode says nothing about what your users experience.
  • A fifty-page report. Nobody will read it. The value is in the ranking, not in exhaustiveness.
  • A conclusion known in advance. If the offer already announces a rewrite before anyone has read the code, the conclusion is not a diagnosis.
  • No name. You should know which engineer will read your code, and what their React Native and native experience is.
  • No confidentiality commitment. An NDA before any access, and clear rules on using AI tools with your code.
  • A document useless without the auditor. A good diagnosis can be handed to your team or to another vendor.

Sources

Common questions

How long does a React Native app audit take?

It depends on the size of the app and the number of platforms and repos. At useffect.sh, the format is fixed: five days, one senior, a written diagnosis of three pages at most and a walkthrough. An audit that is too short leaves no time to profile a production build; one that is too long delays the decision it was meant to inform.

What access should you give an auditor?

Read access to the repo, the crash reports and the CI, plus a production build or the means to make one. Read access to App Store Connect and the Play Console helps with vitals and review feedback. Sign an NDA before any access, and make sure nothing in your repo is modified during the audit.

Can you audit your own React Native app?

Partly. Dependencies can be checked in minutes: a free stack audit on your package.json, npx expo-doctor on an Expo project, and React Native Directory for New Architecture compatibility. Performance on real devices, architecture, security and prioritization need an outside view and time.

Should an audit conclude with a rewrite?

Rarely. A full rewrite is justified when the data model is wrong at the root, or the product has changed so much that the app no longer fits it. An audit that recommends a rewrite has to prove it by comparing the cost of both options, with numbers.

What should you do with the audit report?

Hand it to your team, to a vendor, or to the same auditor for what comes next. A good diagnosis is yours and usable by anyone: ranked risks, fixes to make first, costed options. If only its author can act on it, it is a quote in disguise.

Want to know where your app stands?

30 minutes with a senior to scope an audit of your React Native or Expo app. Free.