Expo native debug loop
Use when debugging Expo or React Native issues on iOS or Android where JavaScript, native modules, simulators or emulators, authentication handoff, native views, permissions, or local EAS builds may disagree or fail at runtime.From its SKILL.md
npx -y skills add yoniyes/agent-skills --skill expo-native-debug-loopAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.1 KB, as published. Nobody here has run it
Expo Native Debug Loop
Overview
Run a tight reproduce-observe-fix loop for Expo native issues. Prefer instrumented diagnosis over guessing, keep a written attempt log, and separate JS problems, layout problems, auth/deep-link problems, and native rendering problems before changing code.
Core Loop
-
Reproduce the issue in the real target environment. Use
npx expo start -cplus the relevant simulator, emulator, or physical device. -
Observe before editing. Collect:
- Metro logs
- platform-native logs (
adb logcat, Xcode/device logs, or component callbacks) - screenshots when visual state matters
- current route, auth state, and permissions state
-
Add targeted instrumentation. Prefer small logs on:
- component mount/render
- native event handlers
- auth request/response callbacks
- native-view ready/load/error/layout callbacks
- API responses that gate rendering
-
Change one hypothesis at a time. Avoid broad refactors during debugging. Make the smallest change that can disprove a concrete theory.
-
Re-run the exact flow. Use the same sequence after every fix attempt so results are comparable.
-
Record the attempt. Append:
- goal
- change
- result
- observed facts
- conclusion
-
Exit the loop only when the user-facing behavior is fixed. A successful build is not success if runtime behavior is still wrong.
Triage Rules
Start by deciding which bucket the issue belongs to:
-
Build-time: Local EAS, Gradle, CocoaPods, config plugins, missing native files, signing, NDK/SDK mismatch.
-
Launch/runtime: App opens but crashes, red screen, native module unavailable, unresolved Metro module, dev client cannot reach Metro.
-
Auth/deep-link: External or native sign-in does not return, or an identity-provider step succeeds but the app session does not advance.
-
Rendering/layout: Gray/white/blank native view, overlays cover the surface, zero-size layout, callbacks never fire.
-
Backend-gated UI: Auth succeeds but later providers or API fetches throw and mask the real screen.
Do not assume a blank screen originates in the visible component. It may be authentication, layout, permission state, or another provider crashing upstream.
Native View Debugging
When debugging a native-backed view such as a map, camera, media player, or document renderer:
-
Log render inputs first. Include component props, readiness flags, dimensions, and whether required configuration exists.
-
Add all relevant native callbacks. Log the library's ready, load, render, error, state-change, and layout callbacks.
-
Distinguish these states:
- native view never mounts
- native view mounts but has zero size
- native view initializes but does not load resources
- native view renders behind or under another view
- parent screen never passes valid props or state
-
Inspect layout explicitly. Blank native views often turn out to have zero height. Log
onLayoutand verify width and height. -
Reduce control surfaces. Start with a known-good baseline:
- one native view
- one initial state
- one representative content item
- no unnecessary provider switching
-
Keep overlays outside the native view. Confirm absolute overlays do not cover or suppress the surface.
-
Treat the rendering backend as a hypothesis only when the library supports alternatives. Capture a relevant native error first, then test one documented backend change and verify whether ready, render, and idle callbacks begin firing.
-
If resources load but nothing is visible, compare:
- layout dimensions
- state-change events
- load-complete events
- render-frame-complete events These facts are more useful than screenshots alone.
Read references/native-debug-recipes.md when you need concrete command patterns and native-view heuristics.
Auth And Deep-Link Debugging
- Log the exact redirect URI and request URL before opening auth.
- Log the prompt result and auth response after submit.
- Check whether the external browser or native provider UI returns to JavaScript at all.
- If browser-based Android auth never resolves, evaluate the provider's supported native SDK rather than repeatedly changing redirect schemes.
- Separate:
- external identity-provider success
- backend credential or session-exchange success
- app session/user-context success
- downstream data fetch success
Do not stop at "sign-in succeeded" if the post-auth screen still breaks.
Local Build Discipline
- Prefer local development builds when cloud quota is limited.
- Verify generated/native files are actually included in local build context.
Hidden gotcha:
.gitignorecan exclude files from local EAS archives even when they exist locally. - Avoid editing autogenerated native directories directly unless the user explicitly wants that workflow.
- Prefer fixing Expo config, plugins, env wiring, or JS/native integration first.
Attempt Log Discipline
Keep a single markdown file for debugging attempts. Each attempt should answer:
- What exact problem was tested?
- What was changed?
- Why was that change chosen?
- What happened?
- What concrete evidence was observed?
- What conclusion should future debuggers reuse?
This prevents cycling through the same failed ideas.
Anti-Patterns
Avoid:
- changing multiple layers at once
- deleting native integrations before proving they are the cause
- assuming simulator screenshots capture every native surface correctly
- treating warning noise as root cause without runtime evidence
- stopping at "build succeeded"
- editing autogenerated
android/orios/output casually
Deliverables
When finishing a debug pass, provide:
- concise root-cause summary
- the fixes made
- what remains unresolved, if anything
- what exact evidence supports the conclusion