Is Xcode Preinstalled on macOS Runners?

Yes. Xcode ships inside the macOS runner image, so a job compiles with no download step. What else is preinstalled, and what still installs per job.

Yes. Xcode is baked into the macOS runner image, so a job that calls xcodebuild in its first step compiles right away with no toolchain download at job start. WarpBuild macOS images are built from the matching upstream GitHub macOS arm64 images and carry the same tooling (preinstalled software documentation, checked on 2026-08-13), and the macOS 26 labels additionally ship Xcode 27.0 (build 27A5194q) with its simulator runtimes (macOS 26 tooling).

Answer

The macOS image decides which Xcode bundles exist on the machine, so the runs-on label is the thing that picks your toolchain set. Every WarpBuild macOS image tracks its upstream GitHub equivalent, and GitHub publishes a per-build inventory readme for each one.

macOS imageWarpBuild labelsPreinstalled Xcode toolingPublished inventory
macOS 26warp-macos-26-arm64-6x, warp-macos-26-arm64-12xThe Xcode bundles in the upstream GitHub macOS 26 arm64 image, plus Xcode 27.0 (build 27A5194q) installed by WarpBuild, with the iOS 27.0, tvOS 27.0, watchOS 27.0, and visionOS 27.0 simulator runtimesmacos-26-arm64 readme and macOS 26 tooling
macOS 15warp-macos-15-arm64-6x, warp-macos-15-arm64-12x, plus the aliases warp-macos-latest-arm64-6x and warp-macos-latest-arm64-12xThe Xcode bundles in the upstream GitHub macOS 15 arm64 image, with the simulator runtimes each bundle carriesmacos-15-arm64 readme
macOS 14warp-macos-14-arm64-6xThe Xcode 15 line, with 15.4 as the image defaultmacos-14-arm64 readme

Each Xcode bundle brings the command line tools with it, so xcodebuild, xcrun, xcode-select, swift, simctl, and notarytool resolve on PATH from the first step of the job. The platform SDKs live inside the bundle, which is why an SDK version and an Xcode version are the same decision on a runner.

Two of those labels are aliases. warp-macos-latest-arm64-6x and warp-macos-latest-arm64-12x resolve to the macOS 15 labels, in sync with GitHub's macos-latest tag (cloud runners documentation), so a job on an alias moves to a different image and a different preinstalled set the day the alias moves. Pin the versioned label when the toolchain matters. macOS 13 runners were removed on June 8, 2026, so a workflow still naming a macOS 13 label queues without a match.

WarpBuild provides Linux x64, Linux ARM64, macOS, and Windows runners. The full macOS lineup with sizes and rates is on the macOS runner hub, and the readme link for every image sits in one place on the preinstalled software page.

Detail

What "preinstalled" covers, and what it does not

Preinstalled means the bytes are already on the boot volume when the job starts. On a macOS image that covers the Xcode bundles under /Applications, the command line tools inside each bundle, the platform SDKs those bundles carry, and the simulator runtimes bundled with them. It does not cover anything specific to your repository or your Apple Developer account.

Four things routinely have to happen inside the job:

Signing certificates and provisioning profiles. These are account secrets, so no shared image carries them. A release job imports them from repository secrets into a temporary keychain on each run. Runner storage is ephemeral and is deleted when the runner terminates, so the keychain never survives to the next job.

Simulator runtimes the image does not carry. A destination string naming a runtime that is absent fails the job, and the fix inside the workflow is sudo xcodebuild -downloadPlatform iOS. Runtimes are multi-gigabyte downloads, so this adds transfer minutes to every run and competes for the 120GB SSD on the 6 vCPU shape.

Repository dependencies. Swift Package Manager checkouts, CocoaPods pods, and the gems pinned by your Gemfile.lock are resolved per job. The image ships the language runtimes listed in its readme; your dependency graph is fetched fresh unless you cache it.

Anything outside the readme. Extra Homebrew formulas, a linter your team standardized on last quarter, or an Xcode version that image never carried. Read the readme for the image before assuming a tool is present, because the inventory changes with each image release.

What a per-job install step costs

Every added minute in a job is a billed minute at the macOS rate for that label. Rates come from the pricing page and the cloud runners documentation, checked on 2026-08-13. The monthly column below assumes 600 macOS jobs a month, which is a team merging around 30 pull requests a weekday with one macOS job per push.

Runner labelShapeRate per minuteCost of one added minute per jobCost of one added minute across 600 jobs
warp-macos-26-arm64-6x, warp-macos-15-arm64-6x, warp-macos-14-arm64-6x6 vCPU, 22 GB$0.080$0.08$48.00
warp-macos-26-arm64-12x, warp-macos-15-arm64-12x12 vCPU, 44 GB$0.160$0.16$96.00

Scale the row by the length of the step. A three-minute toolchain or runtime install on the 6 vCPU shape is 1,800 added minutes a month, which is $144.00, and the same step on the 12 vCPU shape is $288.00. That arithmetic is the reason to pick a label whose image already carries what the job needs rather than reinstalling it 600 times.

A guard step that records the image at job start

The cheapest protection against an image update you did not read about is three lines of shell at the top of the job. They cost seconds and turn a toolchain change into a diff in the job log instead of a compile error nobody can explain.

name: ios-pr
on:
  pull_request:
    branches: [main]

jobs:
  build-and-test:
    runs-on: warp-macos-26-arm64-6x
    env:
      DEVELOPER_DIR: /Applications/Xcode_27.0.app/Contents/Developer
    steps:
      - uses: actions/checkout@v4

      - name: Record the preinstalled toolchain
        run: |
          ls -1 /Applications | grep Xcode
          xcode-select -p
          xcodebuild -version
          xcrun simctl list runtimes

      - name: Fail fast when the expected toolchain is missing
        run: |
          xcodebuild -version | grep -q "Xcode 27.0" || {
            echo "Expected Xcode 27.0 on this label"
            exit 1
          }

      - name: Build and test
        run: |
          xcodebuild test \
            -scheme AppScheme \
            -destination "platform=iOS Simulator,name=iPhone 16 Pro,OS=27.0"

xcodebuild -version prints the version and build number of the selected toolchain, xcode-select -p prints the developer directory in force, and xcrun simctl list runtimes prints every runtime the image carries with its build number and availability. The ls line names the bundles on disk, which is the fastest way to confirm a DEVELOPER_DIR pin. Keep the guard on the release job at minimum, since that is the job whose artifact ships.

Xcode 27.0 on macOS 26 has a support window worth a comment in the workflow. It is a WarpBuild addition on top of the upstream GitHub macOS 26 image while GitHub's upstream macOS 27 runner image is in beta, and a dedicated macOS 27 image follows once that image is released. Runner image changes land in the WarpBuild changelog.

Does a GitHub Actions job need to install Xcode before it can build?

No. Xcode is part of the macOS runner image, so xcodebuild, xcrun, swift, and simctl are on PATH from the first step. A job only installs a toolchain when it needs an Xcode version or a simulator runtime the image does not carry, and the Xcode image coverage page lists which image holds what.

Where do the Xcode bundles live on the runner?

Under /Applications, with version-suffixed bundle names set by the image, such as Xcode_27.0.app on the macOS 26 labels. Run ls -1 /Applications | grep Xcode once on the label you plan to use, then pin DEVELOPER_DIR to the Contents/Developer path inside that bundle. The Xcode selection answer covers the selection mechanisms and their failure modes.

Is the preinstalled list the same as on GitHub-hosted macOS runners?

Yes. Each WarpBuild macOS image is built from the matching upstream GitHub macOS arm64 image and carries the same tooling, with one addition: the macOS 26 labels also ship Xcode 27.0 (build 27A5194q) and its 27.0 simulator runtimes. The per-image readme links are on the preinstalled software page and in the preinstalled software documentation.

Pick a label on the macOS runner hub, confirm the toolchain with the guard step above, and price your own macOS minutes on the pricing page.

Start with $10 in free credits

Change the runner label in your workflow and keep the rest of your GitHub Actions setup. Runner time is billed per minute.