app-icon
Generate app icons for your React Native Expo app with iOS 26 support
Build a release APK and a simulator .app file locally for a React Native Expo app using gradlew and xcodebuild. Use when the user wants to produce installable artifacts without EAS (for e2e testing, sharing a build with a teammate, or quick iteration on a real device/simulator).
$ npx -y skills add Code-with-Beto/skills --skill local-build --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/local-buildContext preview
The summary Claude sees to decide when to auto-load this skill.
Build a release APK and a simulator .app file locally for a React Native Expo app using gradlew and xcodebuild. Use when the user wants to produce installable artifacts without EAS (for e2e testing, sharing a build with a teammate, or quick iteration on a real device/simulator).
name: local-build description: Build a release APK and a simulator .app file locally for a React Native Expo app using gradlew and xcodebuild. Use when the user wants to produce installable artifacts without EAS (for e2e testing, sharing a build with a teammate, or quick iteration on a real device/simulator). Generates two shell scripts wired up to the user's actual app name, scheme, and bundle identifier.
Generate two shell scripts that build release artifacts for an Expo / React Native project using the platform toolchains directly:
Both scripts replace the previous artifact on each run, so the output path is always predictable.
**Why this exists:** Debug builds on an Expo project include `expo-dev-client` and launch the "Development Servers" picker instead of the app UI. For e2e runs, teammate previews, or real device installs, you need a **Release** build, and that's what these scripts produce.
Before doing anything else, verify the current directory is an Expo/React Native project:
1. Check for `package.json` with `expo` in `dependencies`. 2. Check for `app.json` or `app.config.ts` / `app.config.js`.
If neither exists, stop and tell the user the skill only works inside an Expo project.
The scripts need three values specific to the user's project. **Do not hardcode "YourApp" or assume any name.** Read them from the config.
| Value | Where to find it | Used for | |-------|------------------|----------| | `name` | `app.config.ts` / `app.config.js` / `app.json` → `expo.name` | iOS scheme and `.app` filename | | `slug` | `expo.slug` | APK filename (fallback: lowercased `name`) | | `ios.bundleIdentifier` | `expo.ios.bundleIdentifier` | `xcrun simctl launch` command | | `android.package` | `expo.android.package` | `adb shell am start` command |
The iOS scheme file is generated from `expo.name` during `expo prebuild`. Confirm it's there before wiring it into the script:
ls ios/*.xcworkspace 2>/dev/null ls ios/*.xcodeproj/xcshareddata/xcschemes/*.xcscheme 2>/dev/null
The `.xcworkspace` name and the `.xcscheme` filename (without the extension) are what you pass to `xcodebuild -workspace` and `-scheme`. They usually match `expo.name`, but if they don't, **use what's on disk**.
If `ios/` or `android/` doesn't exist yet, run:
npx expo prebuild
Then re-check the scheme.
Write `scripts/build-android.sh`. Replace `<SLUG>` with the value from Step 1.
#!/usr/bin/env bash set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" ROOT="$(cd "$HERE/.." && pwd)" ARTIFACT="$ROOT/android/app/build/outputs/apk/release/app-release.apk" DEST_DIR="$ROOT/builds" DEST="$DEST_DIR/<SLUG>.apk" echo "==> Building Android release APK" cd "$ROOT/android" ./gradlew assembleRelease if [ ! -f "$ARTIFACT" ]; then echo "Build did not produce $ARTIFACT" >&2 exit 1 fi mkdir -p "$DEST_DIR" rm -f "$DEST" cp "$ARTIFACT" "$DEST" echo "Done: $DEST"
**Notes:**
Write `scripts/build-ios.sh`. Replace `<SCHEME>` with the value from Step 1 (it's the same string used for `-workspace <SCHEME>.xcworkspace` and `-scheme <SCHEME>`, and the output file is `<SCHEME>.app`).
#!/usr/bin/env bash set -euo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" ROOT="$(cd "$HERE/.." && pwd)" ARTIFACT="$ROOT/ios/build/Build/Products/Release-iphonesimulator/<SCHEME>.app" DEST_DIR="$ROOT/builds" DEST="$DEST_DIR/<SCHEME>.app" echo "==> Building iOS Simulator .app (Release)" cd "$ROOT/ios" xcodebuild \ -workspace <SCHEME>.xcworkspace \ -scheme <SCHEME> \ -configuration Release \ -sdk iphonesimulator \ -derivedDataPath build \ CODE_SIGNING_ALLOWED=NO \ -quiet if [ ! -d "$ARTIFACT" ]; then echo "Build did not produce $ARTIFACT" >&2 exit 1 fi mkdir -p "$DEST_DIR" rm -rf "$DEST" cp -R "$ARTIFACT" "$DEST" echo "Done: $DEST"
**Notes:**
chmod +x scripts/build-android.sh scripts/build-ios.sh
Append this to `.gitignore` (check it's not already there):
# Local build artifacts builds/
Give the user this summary:
Built two scripts for you: ./scripts/build-android.sh → builds/<slug>.apk ./scripts/build-ios.sh → builds/<scheme>.app Install and run: # Android (connected device or emulator) adb install -r builds/<slug>.apk adb shell am start -n <android.package>/.MainActivity # iOS Simulator xcrun simctl boot "iPhone 16" 2>/dev/null; open -a Simulator xcrun simctl install booted builds/<scheme>.app
Professional agent skills and plugins to help mobile developers ship better apps faster with AI assistance.
Generate app icons for your React Native Expo app with iOS 26 support
Scaffold production-ready React Native apps using the @codewithbeto/ship CLI. Use when the user wants to create a new app from a…
Scaffold a unified, cross-platform color theme system into an Expo Router app. Sets up semantic system colors (resolved from…