Local iOS builds using Expo Prebuild and Fastlane

TL;DR: Skip to the full Fastfile example below

I have an app written in react native that I’m using expo for. I recently switched to prebuild, and and wanted to preserve my fastlane release workflow. Here’s how I did it.


Before you start, ensure you install fastlane into your project folder, and your app store connect account is already configured for your app’s bundle ID and signing certificates are installed. Running expo run:ios should configure some of this.

app.json Auto-incrementing build number

We can use jq to increment the build number within our app.json If you don’t yet have jq, it is available under that name in most package managers.

Fastlane’s sh module allows us to run a raw shell command. In the final script, this must be wrapped in an Dir.chdir("..") doend block since shell scripts within fastlane run inside the fastlane/ folder as opposed to the project root.

This first edits it using jq, and then replaces the existing app.json with our modified version.

sh("cat app.json | jq -e '.expo.ios.buildNumber |= (tonumber +1 | tostring)' | tee app.json.tmp > /dev/null && mv app.json.tmp app.json")

Running Prebuild in Fastlane

This is fairly straightforward, next we can just tell prebuild to run to ensure everything is up to date:

sh("npx expo prebuild")

Putting it all together


# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane


platform :ios do
  desc "Push a new beta build to TestFlight"
  lane :beta do

      # inside the app directory
      Dir.chdir("..") do
        # TASK: make sure `expo.ios.buildNumber` is set in your app.json first!
        # increment app.json build number
        sh("cat app.json | jq -e '.expo.ios.buildNumber |= (tonumber +1 | tostring)' | tee app.json.tmp > /dev/null && mv app.json.tmp app.json")

        # run expo prebuild to regenerate the native app
        sh("npx expo prebuild")

      # build the scheme
      # TODO: edit the scheme / xcworkspace name with your own
      build_app(workspace: "./ios/MyAppName.xcworkspace", scheme: "MyAppName")

      # upload to testflight


# TODO: customize these to match your team / app settings
app_identifier("com.example.appname") # The bundle identifier of your app
apple_id("you@example.com") # Your Apple Developer Portal username

itc_team_id("12345678") # App Store Connect Team ID
team_id("9H123S4TFE") # Developer Portal Team ID

# For more information about the Appfile, see:
#     https://docs.fastlane.tools/advanced/#appfile

Change Log

  • 2024-02-07 - Initial Revision

Found a typo or technical problem? file an issue!