[ Documentation ]
Diagnosing Your Project

Diagnosing Your Project

Two commands tell you how your project will fare in Peach before you open it. Both read your project locally and change nothing.

  • +
    peach doctor checks one app against the runtime you have installed: its React and React Native, every native library with its implementation percent, and native code Peach does not know.
  • +
    peach project-report inventories every React Native, Expo, iOS, Android and Swift project in your repository with its dependency and toolchain versions. It is what you attach when you report a problem.

Run peach doctor

From your app’s project root:

terminal
peach doctor

In a monorepo, run it from the app’s directory or pass --app apps/mobile. If you run it at a workspace root that holds more than one app, it lists them and prints the peach doctor --app <dir> command for each. Outside any app, it checks your CLI and runtime install and tells you where to run it.

To look at one library, name it:

terminal
peach doctor react-native-reanimated

The header names your app, its framework (Expo SDK 54, One or React Native), and your CLI and runtime versions. Doctor scores against the runtime your project uses, so a project that pins runtimeVersion in peach.config.ts is checked against that runtime. If that runtime is not installed, doctor stops and asks you to run peach upgrade.

React and React Native

React and React Native ✓ react-native 0.81.4 ✓ react 18.3.1 runs on React 19.2.3 no defaultProps on function components, string refs or legacy context

Every app runs on the runtime’s React. When your app declares an older React major, doctor reminds you what React 19 removed. Search your code for defaultProps on function components, string refs and legacy context, and move them to default parameters, callback or object refs, and createContext.

markmeaningwhat to do
✓at or above the oldest release Peach has been run againstnothing
▲older than the oldest release Peach has runit may still work; try it, and upgrade if you hit problems
?not a release version doctor can compare, such as a tag or a Git URLnothing, or pin a release version

Packages

The packages section lists every React Native package your app installs, worst first, with its implementation percent: how much of the package’s app-facing API Peach implements for your installed version. The line above the list counts each kind.

Packages 12 supported · 1 partial · 1 unverified version · 1 unknown native · 18 JavaScript only ? react-native-acme-scanner 2.1.0 native code Peach does not know; stub it below ▲ react-native-acme-store 4.0.0 outside supported >=2 <4; it may still work ◐ react-native-acme-maps 1.20.1 78% missing: custom tile overlays ✓ react-native-acme-camera 3.2.0 96% · run from your bundle, no native code: zustand, date-fns, ...

The package names above are examples. Your own output lists your real dependencies.

markfindingwhat to do
✓Supported: 90% or more implemented, or answered by a stubnothing
◐Partial: the major APIs work; the line names the first thing missingcheck whether your app uses what is missing; --verbose prints the full note
▲Unverified version: Peach tracks the package, but your installed version is outside its supported rangesit may still work; try it, or install a version inside the printed range
?Unknown native: a package Peach does not track that ships native codeanswer its native names with a custom stub
✗Unsupported: the package needs a native SDK Peach cannot runthe line says why, and names a replacement when one exists; otherwise stub out the feature with modules
·Light: the package loads and its native side is inertfine for packages your app only needs to import; nothing it does natively happens
·Tracked, not assessed yet: Peach knows the package but has no implementation figure for ittry it; peach doctor --report helps us prioritize it
·JavaScript only: no native code, so it runs from your bundlenothing

A light package is admitted so your app loads. It is never counted as supported, and its line says so. See Library compatibility.

Native code Peach does not know

When a package Peach does not track ships native code, or your app has its own native modules and views, doctor adds a section that names every native module and view your JavaScript asks for, and prints the config that answers them:

Native code Peach does not know ? react-native-acme-scanner module AcmeScanner, view AcmeScannerView ? view RNBalanceLabel src/components/Balance.tsx:12 stub them in peach.config.ts, by package: export default defineConfig({ packages: { 'react-native-acme-scanner': { modules: { AcmeScanner: './peach/AcmeScanner.ts', }, views: { AcmeScannerView: './peach/AcmeScannerView.tsx', }, }, 'my-app': { views: { RNBalanceLabel: './peach/RNBalanceLabel.tsx', }, }, }, })

Doctor finds a package’s native names by reading its JavaScript for TurboModuleRegistry, NativeModules, requireNativeModule, requireNativeComponent, requireNativeView and codegenNativeComponent. It finds your app’s own by reading your source and your workspace packages, and by reading the Name("...") each local Expo module declares. Each of your own names is listed with the file and line that asks for it, and filed under the package it lives in.

Until something answers a name, the module is an inert stand-in and the view renders empty. A module your app requires at startup can stop the app, so answer those first. You have three choices for each package:

  • +
    'noop' in place of the package’s object makes every native name it asks for inert. Use it for analytics, crash reporting and other native side effects you do not need in the simulator.
  • +
    A file per name gives the module or view real behavior. Copy the block doctor printed into peach.config.ts, then write each file. A view file default-exports the component that renders in the native view’s place; see Custom stubs.
  • +
    A stub package: if someone published peach-stub-<package>, installing it answers the package with no config.

Run peach doctor again. Each answered name now reads (answered), and the package moves to ✓ with who answers it.

Local Expo modules written in Swift are marked Swift. See iOS for running Swift code in an Expo or One app.

Stub packages and native view sources

When an installed peach-stub-<package>, or a library’s own package.json, answers a package, doctor lists it under Stub packages with how many modules and views it answers. Stub packages are marked third-party: community code Peach has not checked against the real native side. A stub whose versions range does not cover your installed version is listed with ▲ and is not applied.

Native views you answered with a source object, such as a video or a placeholder, are listed under Native view sources.

Send your findings

terminal
peach doctor --report

--report sends the findings to the Peach team with no login. It carries package names and versions, the findings and your CLI and runtime versions, never source, paths, your app’s name, environment or app data. Each network can send 10 reports a day. Reports tell us which libraries to implement next.

For a script or an agent, peach doctor --json prints the same findings as JSON. When none of your packages has measured results, overallScore is null and the implementation figure is reported separately as implementationEstimate.

Inventory your repository

terminal
peach project-report

project-report scans from your workspace or Git root and prints one entry per project it finds, with the settings and dependency versions that matter for running it:

peach project report machine: darwin 25.0.0 / arm64 tools: Xcode 26.0, Node v22.12.0, Bun 1.3.1 peach: CLI 0.9.2, active runtime 0.9.2 repository: npm-workspaces, bun 1.3.1 (declared) discovery: 2 app/package entries, 214 directories apps/mobile [expo] mobile jsEngine: hermes (configured) newArchitecture: true (configured; iOS) androidNewArchitecture: unknown (not configured in static metadata) expoSdk: 54.0.12 (installed; expo package version) react: 19.1.0 (installed) react-native: 0.81.4 (installed) expo: 54.0.12 (installed)

The header names your machine, toolchain and Peach versions, then the repository layout and how much of it was scanned. Each project entry starts with its path, its kind (expo, react-native, one, native-ios, swift-package or android) and its name.

Each dependency says whether its version came from the installed package, the lockfile or the declared range. A setting Peach cannot read without running your config or a native build reads unknown. The scan never runs app config, Swift or Gradle builds, skips dependency, build, cache and hidden directories, and stops at 12 directory levels, 10,000 directories or 200,000 entries; the discovery line says LIMIT REACHED when it stopped early. Use --app <dir> to scan one directory, and --json for a machine-readable report.

The report holds only relative paths, dependency versions and toolchain settings: no source, environment values, URLs or credentials. It stays on your machine until you send it with peach support report "<description>", which shows you a preview and asks you to confirm.