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 doctorchecks 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-reportinventories 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:
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:
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
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.
| mark | meaning | what to do |
|---|---|---|
| ✓ | at or above the oldest release Peach has been run against | nothing |
| ▲ | older than the oldest release Peach has run | it 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 URL | nothing, 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.
The package names above are examples. Your own output lists your real dependencies.
| mark | finding | what to do |
|---|---|---|
| ✓ | Supported: 90% or more implemented, or answered by a stub | nothing |
| ◐ | Partial: the major APIs work; the line names the first thing missing | check 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 ranges | it may still work; try it, or install a version inside the printed range |
| ? | Unknown native: a package Peach does not track that ships native code | answer its native names with a custom stub |
| ✗ | Unsupported: the package needs a native SDK Peach cannot run | the 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 inert | fine 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 it | try it; peach doctor --report helps us prioritize it |
| · | JavaScript only: no native code, so it runs from your bundle | nothing |
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:
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
--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
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:
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.
Related
- +Library compatibility: how the implementation percent is measured
- +Custom stubs: answer native code Peach does not know
- +Reporting issues