Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 181 additions & 0 deletions plugins/react-native/SMART-PLATFORM-DETECTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Smart Platform Detection

The React Native plugin automatically detects which platform you're using and skips initialization of the unused platform. This significantly speeds up shell initialization and eliminates confusing warnings.

## How It Works

### 1. Command-Based Detection (Highest Priority)

When you run a devbox command, the plugin examines the command to determine which platform is needed:

```bash
# iOS commands → automatically sets ANDROID_SKIP_SETUP=1
devbox run start:ios
devbox run build:ios
devbox run ios.sh simulator start

# Android commands → automatically sets IOS_SKIP_SETUP=1
devbox run start:android
devbox run build:android
devbox run android.sh emulator start
```

**Detected patterns:**
- iOS: `ios.sh`, `pod`, `xcodebuild`, `xcrun`, `simulator`
- Android: `android.sh`, `gradlew`, `adb`, `emulator`, `/android/`

### 2. Project Structure Detection (Fallback)

If command detection doesn't apply (e.g., `devbox shell`), the plugin checks your project structure:

```bash
# iOS-only project (has ios/ but no android/)
your-project/
├── ios/ ← has this
├── src/
└── devbox.json
# → Sets ANDROID_SKIP_SETUP=1 automatically

# Android-only project (has android/ but no ios/)
your-project/
├── android/ ← has this
├── src/
└── devbox.json
# → Sets IOS_SKIP_SETUP=1 automatically

# Full React Native project (has both)
your-project/
├── ios/ ← has both
├── android/ ←
├── src/
└── devbox.json
# → Initializes both platforms
```

### 3. Manual Override (Always Respected)

Explicitly set skip flags always take precedence:

```bash
# Force iOS-only (even if project has both platforms)
export ANDROID_SKIP_SETUP=1
devbox shell

# Force Android-only
export IOS_SKIP_SETUP=1
devbox shell

# Force both platforms (override auto-detection)
export RN_REQUIRE_ALL_PLATFORMS=1
devbox shell
```

## Performance Benefits

**Before (without smart detection):**
```bash
$ time devbox run start:ios
🔍 Evaluating Android SDK from Nix flake... # ← Unnecessary!
WARNING: Android SDK evaluation failed... # ← Confusing!
iOS simulator booted
real 0m45.2s
```

**After (with smart detection):**
```bash
$ time devbox run start:ios
iOS simulator booted # ← Clean!
real 0m8.5s
```

**Speed improvement:** ~5-6x faster for single-platform commands

## Opt-Out

If you need both platforms initialized simultaneously (rare), set:

```bash
export RN_REQUIRE_ALL_PLATFORMS=1
```

Then both Android and iOS will be initialized regardless of command or project structure.

## Use Cases

### iOS Development on macOS

```bash
# Just works - no Android SDK errors
cd my-rn-app
devbox run start:ios
devbox run build:ios
```

### Android Development

```bash
# Just works - no iOS setup overhead
cd my-rn-app
devbox run start:android
devbox run build:android
```

### Cross-Platform Development

```bash
# Need both platforms in same shell
export RN_REQUIRE_ALL_PLATFORMS=1
devbox shell

# Or use separate shells (recommended)
# Terminal 1:
devbox run -e ANDROID_SKIP_SETUP=1 start:ios

# Terminal 2:
devbox run -e IOS_SKIP_SETUP=1 start:android
```

## Troubleshooting

**Q: I'm seeing "Android SDK evaluation failed" on macOS**
A: This warning should be gone with smart detection. If you still see it, check:
- Is your command pattern recognized? (see patterns above)
- Did you set `RN_REQUIRE_ALL_PLATFORMS=1`?
- Try explicit flag: `devbox run -e ANDROID_SKIP_SETUP=1 <command>`

**Q: iOS commands are slow on first run**
A: First run evaluates the iOS SDK from Nix. Subsequent runs use cached evaluation (~instant).

**Q: I need both platforms but don't want to set RN_REQUIRE_ALL_PLATFORMS**
A: Use two separate devbox shells - one for iOS, one for Android. This is the recommended workflow.

## Migration Guide

**If you were using manual skip flags:**

```bash
# Before
devbox run -e ANDROID_SKIP_SETUP=1 start:ios
devbox run -e IOS_SKIP_SETUP=1 start:android

# After (automatic!)
devbox run start:ios
devbox run start:android
```

**If you were adding export statements to scripts:**

```bash
# Before (in devbox.json)
"build:ios": [
"export ANDROID_SKIP_SETUP=1",
"..."
]

# After (remove export - automatic!)
"build:ios": [
"..."
]
```

The manual flags still work (and take precedence), but are no longer necessary for common cases.
43 changes: 43 additions & 0 deletions plugins/react-native/virtenv/scripts/init/init-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,49 @@
# NOTE: This file is sourced (not executed) by devbox init_hook,
# so it must be POSIX sh compatible (no bash-isms).

# ============================================================================
# Smart Platform Detection
# Automatically skip unnecessary platform setup to speed up initialization
# ============================================================================

# Skip if user explicitly wants all platforms
if [ "${RN_REQUIRE_ALL_PLATFORMS:-0}" != "1" ]; then
# 1. Command-based detection (highest priority)
if [ -n "${DEVBOX_RUN_COMMAND:-}" ]; then
case "$DEVBOX_RUN_COMMAND" in
# iOS commands - skip Android
*ios.sh*|*pod\ *|*xcodebuild*|*xcrun*|*simulator*)
export ANDROID_SKIP_SETUP=1
;;
# Android commands - skip iOS
*android.sh*|*gradlew*|*adb*|*emulator*|*/android/*)
export IOS_SKIP_SETUP=1
;;
esac
fi

# 2. Project structure detection (fallback)
# Only applies if skip flags not already set
if [ -z "${ANDROID_SKIP_SETUP:-}" ] && [ -z "${IOS_SKIP_SETUP:-}" ]; then
project_root="${DEVBOX_PROJECT_ROOT:-${PWD}}"
has_ios=0
has_android=0

[ -d "$project_root/ios" ] && has_ios=1
[ -d "$project_root/android" ] && has_android=1

# iOS-only project
if [ $has_ios -eq 1 ] && [ $has_android -eq 0 ]; then
export ANDROID_SKIP_SETUP=1
fi

# Android-only project
if [ $has_android -eq 1 ] && [ $has_ios -eq 0 ]; then
export IOS_SKIP_SETUP=1
fi
fi
fi

# Add React Native scripts to PATH if not already present
if [ -n "${REACT_NATIVE_SCRIPTS_DIR:-}" ] && [ -d "${REACT_NATIVE_SCRIPTS_DIR}" ]; then
# Add user-facing scripts (rn.sh, metro.sh) to PATH
Expand Down
Loading