Free resource · 40-point checklist

The React Native App Audit Checklist

This is the exact checklist I run at the start of every React Native audit and rescue engagement — 40 checks across architecture, performance, security, releases, testing, and observability. Run it against your own app: every unchecked box is a risk you now know about, which already puts you ahead of most teams.

Download the PDF version to share with your team or work through offline.

1. Architecture & Code Health

01Feature-based folder structure, not type-based

Screens, hooks, and API calls for one feature living together is what keeps a codebase navigable past 50 screens. A giant components/ folder is the first smell of a project that grew without an owner.

02TypeScript strict mode is on — and respected

strict: false or a codebase full of `any` means the type system is decoration. Most 'random' production crashes in audits trace to a shape mismatch TypeScript would have caught.

03State management fits the app, not the trend

One giant context re-rendering the whole tree, or Redux boilerplate wrapping two values — both are drag. Server state belongs in a query library; UI state in something small.

04Business logic lives outside components

Pricing rules and data transforms buried in JSX can't be tested and get duplicated. Components render; logic lives in plain functions that have unit tests.

05Dependency audit: unmaintained and duplicate libraries

Two date libraries, three icon sets, and a navigation lib abandoned in 2022 — each one is future migration debt. Every dependency should earn its place.

2. Performance

06Long lists are virtualized properly

Feeds beyond a few hundred items need FlashList or a well-configured FlatList. Blank cells while scrolling is the #1 user-visible performance complaint in rescues.

07No re-render storms on core screens

A keystroke that re-renders 40 components is why the app 'feels laggy'. Profile first: most RN performance problems are React problems, not native ones.

08Images are sized, cached, and compressed

Shipping 4000px images into 120px avatars burns memory and scroll performance. Resize on the server, cache on the client, use modern formats.

09Hermes enabled and startup time measured

Cold start over ~3 seconds loses users before the first screen. Measure TTI on a mid-range Android device, not your simulator.

10JS bundle audited for weight

Moment with all locales, lodash imported wholesale, dev-only tooling in production — bundle bloat slows startup on every single launch.

3. Reliability & Error Handling

11Crash reporting wired with readable stack traces

Sentry (or equivalent) with sourcemaps uploaded per release. A crash report pointing at minified line 1 is not observability.

12Error boundaries around risky surfaces

One thrown error in a deeply nested component should not white-screen the entire app. Boundaries plus a friendly retry screen contain the blast radius.

13Network failures are handled, not assumed away

Every API call needs a loading, error, and retry story. Apps tested only on office Wi-Fi fall apart on train Wi-Fi.

14Offline behavior is defined

Even 'this app requires a connection' is a decision — show it deliberately. Cached reads and queued writes are the difference between 4 and 5 stars in reviews.

15Slow frames and ANRs monitored in production

Crashes get reported; jank silently churns users. Production performance monitoring shows what your test devices never will.

4. Security

16Tokens in SecureStore/Keychain — never AsyncStorage

AsyncStorage is plaintext and readable from device backups. Auth tokens belong in the platform keychain, full stop.

17No secrets inside the JS bundle

API keys shipped in the app can be extracted in minutes. Anything secret stays server-side behind endpoints you control.

18Transport security: HTTPS everywhere, pinning where it matters

Fintech and health apps warrant certificate pinning; every app warrants zero plain-HTTP calls, including that one legacy analytics endpoint.

19Deep links validated before acting

A deep link is untrusted input. Links that trigger payments, open WebViews, or prefill forms need the same validation as any API input.

20Dependency vulnerabilities reviewed on a schedule

npm audit noise is real, but so are the criticals hiding in it. A monthly triage habit beats a panicked upgrade the week of a pen test.

5. Auth & Data Integrity

21Token refresh is deduplicated and race-free

Five parallel 401s must trigger one refresh, not five. Refresh races are the classic cause of 'randomly logged out' bug reports.

22Logout actually clears everything

Tokens, caches, query stores, persisted state — a logout that leaves the previous user's data behind is a privacy incident on shared devices.

23No PII leaking into logs or analytics

Emails and tokens in breadcrumbs or event payloads become a compliance problem the day you sign an enterprise customer.

24Persisted local data has a migration strategy

Changing a persisted store's shape without migrations crashes exactly the users who've had the app longest — your best users.

25API error contract is consistent

If every endpoint fails differently, the app handles none of them well. One error envelope, handled in one interceptor.

6. Release Engineering

26CI builds and tests both platforms on every PR

'It builds on my Mac' is not a release process. EAS or equivalent CI catching platform breaks before merge is table stakes.

27OTA update strategy with a rollback plan

Over-the-air updates fix JS bugs in hours instead of store-review days — but only if rollback is one command and someone owns the button.

28Store rollouts are staged

Shipping to 100% of users on day one turns any missed bug into a support fire. 10% → 50% → 100% with crash-rate gates between.

29Versioning and release notes are disciplined

When a user reports a bug, you need to know exactly which JS bundle and native build they run. Chaos here makes every incident slower.

30Store listings are current and owned

Screenshots from three redesigns ago and an unowned developer account are conversion and continuity risks nobody notices until it hurts.

7. Testing & Quality

31Critical paths have E2E coverage

Login, purchase, and the core loop covered by Maestro or Detox — the flows where a regression costs money get automated first.

32Business logic has unit tests

Not 100% coverage — targeted tests on the functions that compute money, permissions, and state transitions.

33API responses validated at runtime

A zod schema at the network boundary turns 'backend changed a field and the app crashes' into a logged, handled error.

34A real device matrix exists

Mid-range Android with 3GB RAM is where performance dies first. If every test device costs $1000+, the app is untested for most users.

35Accessibility basics pass

Labels on touchables, contrast, and font-scaling that doesn't break layouts — legally required in more markets every year, and it widens your user base.

8. Observability & Handoff

36Core funnel events are tracked and trusted

If signup-to-activation can't be answered from analytics, product decisions are guesses. Five reliable events beat fifty noisy ones.

37Someone owns the dashboards and alerts

Crash-rate and API-error alerts that page a named human. Monitoring nobody reads is decoration.

38Feature flags gate risky changes

The ability to turn a misbehaving feature off remotely — without a release — has saved every serious app I've worked on at least once.

39README gets a new engineer running in under an hour

Setup folklore that lives in one person's head is a bus-factor problem. The audit test: can I run the app from the README alone?

40A runbook exists for the top three incidents

App down, API down, bad release — written steps, owners, and rollback commands. Incident response designed during an incident goes badly.

Keep up with new guides

New deep-dive guides on React Native, Python, and AI ship regularly. Subscribe via RSS or follow on LinkedIn.

Want me to run this audit on your app?

30-minute scoping call · Clear milestones · Senior engineer ownership