Doctor
What every row of bun run doctor means, and what to do when one is red.
bun run doctorIt prints one line per check and exits non-zero if any of them failed. ✓ is fine, ! is
advisory, ✗ fails the run, and - means the check didn't apply to your selection.
Store and release identity - the bundle id, package, app name, urls, store ids, the EAS
project link, eas whoami and the placeholder app icon - is expected to be unset on day one, so
those rows are grouped at the end under Before you ship as !: a fresh default setup exits 0. bun run doctor --store turns every one of them into ✗, because by then they block a
submission.
✓ .readynative.json present (preset saas)
✗ EXPO_PUBLIC_SUPABASE_URL (auth/supabase) (missing in .env · dashboard: https://supabase.com/dashboard · guide: https://readynative.app/docs/features/auth/supabase#setup)
✓ package manager (bun (bun.lock))
Before you ship:
! readynative.config.ts app.ios.bundleId set (still "com.acme.app" - set your own reverse-DNS id)
! app icon replaced (assets/images/icon.png is the ReadyNative placeholder - …)The rows
| Row | Green when | If it's red |
|---|---|---|
.readynative.json present | setup has run and applied a selection. The detail shows the preset, or custom | Run bun run setup |
| One row per env key | The key is set in .env or in the process environment | Follow the two links in the detail (below) |
readynative.config.ts placeholders | No com.acme.app, no default app name, no empty urls or store ids (before you ship), and a links.domain that has a team id and fingerprints | Fill them in - see Config |
app icon replaced | assets/images/icon.png and assets/brand/icon.png are not the shipped placeholder (before you ship) | Put your 1024px PNG at assets/brand/icon.png and run bun run gen:assets |
eas whoami | You're logged in (before you ship). Skipped entirely when eas-cli is not installed | bunx eas-cli login - see Ship to TestFlight |
| Xcode / Android SDK | xcode-select -p resolves and ANDROID_HOME is set. Only checked when a selected module is expoGo: false | Install the toolchain, or build the dev build on EAS instead |
bun >= 1.2 / node >= 22.18 | Both runtimes are on your PATH and recent enough (bun only fails for a bun tree) | Install Node 24 LTS: below 22.18 node cannot run scripts/*.ts |
package manager | Always. It reports the answer rather than judging it: pnpm (pnpm-lock.yaml) | See Package managers if it isn't the one you expected |
The two links on a missing key
A missing env key prints where to get it and how to wire it up:
missing in .env · dashboard: <the vendor's page> · guide: <the setup walkthrough on this site>The dashboard link comes from the module's env[].docsUrl - the exact vendor page that
issues that key. The guide link is the #setup anchor of the module's Features page here,
which is the numbered walkthrough naming every dashboard screen in order. Either part is
dropped when a module doesn't carry it, so a keyless module still reads as a sentence.
setup prints the same guide link once per selected service when it finishes, so you can start
collecting keys before you ever run doctor.
The docs link at the bottom
After the checklist, doctor prints:
Docs for your stack: https://readynative.app/docs/?stack=ui:nativewind4,auth:supabase,…That query string is your .readynative.json selection. Open it and this whole site switches to
your stack: the tutorials show your options' code, the Features tree hides what you didn't pick.
You can also set it by hand in the Your stack panel at the top of the sidebar, or load it
there with Import .readynative.json.
Point the links at a local docs server by setting READYNATIVE_DOCS_URL.
Running it elsewhere
--root <dir> runs the checks against another checkout:
bun run doctor --root ../my-other-app