Debug React Native app in iOS simulator. Execute JavaScript functions via WebSocket, tap/swipe UI elements, take screenshots, inspect accessibility tree, control GPS, and manage app lifecycle. Use when testing or debugging the app during development.
Complete debugging toolkit for React Native on iOS Simulator:
idb (tap, swipe, text input)pnpm ios)ws npm package (install once: cd <skill-dir> && npm install)idb (iOS Development Bridge) — already installedRun any JS expression in the running app context via WebSocket:
./scripts/js-eval.js '<expression>'
./scripts/js-eval.js '__showSubscription()'
./scripts/js-eval.js '__setSubscription("global_driver")'
./scripts/js-eval.js '__setSubscription("road_traveller")'
./scripts/js-eval.js '__setSubscription("lifetime")'
./scripts/js-eval.js '__clearSubscription()'
Tiers: free (default), road_traveller (Basic — British spelling), global_driver (Unlimited), lifetime
./scripts/js-eval.js '2 + 2'
./scripts/js-eval.js 'Object.keys(globalThis).filter(k => k.startsWith("__")).join(", ")'
./scripts/tap.sh X Y [duration]
Examples:
./scripts/tap.sh 200 400 # Quick tap
./scripts/tap.sh 200 400 1.0 # Long press (1 second)
./scripts/swipe.sh X1 Y1 X2 Y2 [duration]
Examples:
./scripts/swipe.sh 200 600 200 200 # Swipe up
./scripts/swipe.sh 100 400 500 400 # Swipe right
./scripts/type.sh "text to type"
./scripts/button.sh HOME
./scripts/button.sh LOCK
./scripts/button.sh SIRI
./scripts/button.sh SIDE_BUTTON
./scripts/screenshot.sh [output_path]
./scripts/screenshot.sh # Saves to /tmp/idb_screenshot_*.png
./scripts/screenshot.sh ~/Desktop/app.png # Custom path
./scripts/describe.sh all # Full accessibility tree (JSON)
./scripts/describe.sh 200 400 # Element at coordinates (JSON)
The accessibility tree shows:
./scripts/location.sh LAT LNG
./scripts/location.sh 37.7749 -122.4194 # San Francisco (NorCal)
./scripts/location.sh 34.0522 -118.2437 # Los Angeles (SoCal)
./scripts/location.sh 29.7604 -95.3698 # Houston, Texas
./scripts/location.sh 59.3293 18.0686 # Stockholm, Sweden
xcrun simctl ui booted appearance dark
xcrun simctl ui booted appearance light
xcrun simctl terminate booted com.nordhud.app
xcrun simctl launch booted com.nordhud.app
curl -s "http://localhost:8081/reload" # Hot reload Metro
Complete end-to-end testing example:
# 1. Take screenshot to see current state
./scripts/screenshot.sh
# 2. Get accessibility tree to find elements
./scripts/describe.sh all | jq '.[] | select(.label | contains("Settings"))'
# 3. Tap the Settings button (found at coordinates)
./scripts/tap.sh 690 970
# 4. Change subscription via JavaScript
./scripts/js-eval.js '__setSubscription("global_driver")'
# 5. Verify UI updated
./scripts/screenshot.sh
# 6. Navigate back (tap back button at top-left)
./scripts/tap.sh 38 81
# 7. Test location-based features
./scripts/location.sh 37.7749 -122.4194
# 8. Take final screenshot
./scripts/screenshot.sh
Use describe.sh all to get the accessibility tree, then extract coordinates:
# Get all buttons and their positions
./scripts/describe.sh all | jq '.[] | select(.type == "Button") | {label, frame}'
# Find specific element
./scripts/describe.sh all | jq '.[] | select(.label | contains("Settings")) | .frame'
# Output: {"x": 660, "y": 940, "width": 60, "height": 60}
# Tap center: x + width/2, y + height/2 = 690, 970
If running Metro in tmux:
tmux capture-pane -t dev -p | tail -30 # Last 30 lines
tmux capture-pane -t dev -p | grep -i subscription # Filter
./scripts/tap.sh 200 600 # Show toolbar (if hidden)
./scripts/tap.sh 690 970 # Tap Settings button
./scripts/js-eval.js '__setSubscription("global_driver")'
./scripts/screenshot.sh
./scripts/describe.sh all | jq '.[] | select(.label | contains("Unlimited"))'
./scripts/location.sh 37.7749 -122.4194 # Set to NorCal
sleep 2 # Wait for app to react
./scripts/screenshot.sh
./scripts/describe.sh all | grep -i "norcal"
# Take initial screenshot
./scripts/screenshot.sh initial.png
# Change state via JS
./scripts/js-eval.js '__setSubscription("global_driver")'
# Navigate to feature that requires subscription
./scripts/tap.sh 690 970 # Settings
./scripts/tap.sh 400 600 # Some feature
./scripts/screenshot.sh feature.png
# Verify feature is unlocked
./scripts/describe.sh all | jq '.[] | select(.enabled == true)'
If the MCP ios-simulator tools are available, they provide similar functionality:
mcp__ios-simulator__ui_view # Screenshot
mcp__ios-simulator__ui_describe_all # Accessibility tree
mcp__ios-simulator__ui_tap # Tap at (x, y)
mcp__ios-simulator__ui_swipe # Swipe gesture
mcp__ios-simulator__ui_type # Type text
mcp__ios-simulator__launch_app # Launch by bundle ID
This skill's scripts (tap.sh, describe.sh, etc.) use idb directly and are faster for scripting.
Metro isn't running. Start with pnpm ios.
Install idb: brew tap facebook/fb && brew install idb-companion
App may have reloaded. Re-run the command.
./scripts/describe.sh allWait a moment after actions: sleep 1 && ./scripts/screenshot.sh
You can use idb directly for more features:
idb video record video.mp4 & # Start recording
# ... perform actions ...
killall idb # Stop recording
idb log --tail # Stream device logs
idb file push local.txt /tmp/app.txt # Push file to device
idb contacts update # Update contacts database
See idb --help for all commands.