XCFramework: What It Is, Binary Distribution Format, and Application

Author: IT Sectr Published: 2026-06-05 Reading time: 7 min

XCFramework is an Apple binary format that combines libraries for iOS, macOS, tvOS, and watchOS in a single package. It was designed to replace .framework and eliminate the problems of fat binaries when building for different simulator and device architectures. According to Apple WWDC 2019, XCFramework became the mandatory format for distributing SDKs that support multiple platforms, and completely replaced the outdated approach with universal binaries.

Key Takeaways

  • XCFramework is Apple’s universal format for distributing libraries, supporting multiple platforms and architectures in a single bundle
  • Fat binary approach is replaced with separate slices for each platform, eliminating build issues with simulator architectures
  • Creation is done via xcodebuild -create-xcframework without manually merging binaries with lipo
  • Integration in Xcode is done through Embed & Sign without additional scripts to remove simulator architectures
  • Swift Package Manager does not fully replace XCFramework — binary dependencies in SPM are delivered in this exact format

What Is XCFramework?

XCFramework is a packaging format for binary libraries and frameworks introduced by Apple at WWDC 2019. Its main goal is to create a single bundle that contains compiled versions of a library for all target platforms and architectures.

Before XCFramework, developers used .framework with fat binaries combining multiple architectures via the lipo utility. This approach caused problems: when building a project for the simulator, the fat binary contained both simulator and device architectures, leading to errors when submitting the build to the App Store. Developers had to write Run Script phases to remove unnecessary architectures.

According to Apple Developer Documentation (2024), XCFramework supports all platforms in the Apple ecosystem: iOS, iPadOS, macOS, tvOS, watchOS, visionOS, and Mac Catalyst applications. Each platform gets a separate slice inside the package, eliminating architecture conflicts and simplifying SDK distribution.

When Do You Need XCFramework?

XCFramework is used in three main scenarios: distributing closed-source SDKs to third-party developers, distributing native modules for Flutter and React Native, and publishing libraries that require pre-compilation. The format is mandatory for all new SDKs published in the Apple ecosystem.

Developers choose XCFramework when source code cannot be disclosed, when the library uses proprietary algorithms, or when license protection is required. Unlike Swift Package Manager, which works with source code, XCFramework delivers already compiled binary files.

How Does XCFramework Solve the Fat Binary Problem?

The fat binary problem was that a universal binary contained multiple architectures in a single Mach-O file. When building an app for the simulator, Xcode included both the device arm64 architecture and the simulator x86_64 architecture — the App Store only accepted the device architecture.

The traditional solution involved adding a Run Script phase calling lipo to remove simulator architectures from the final build. This approach was fragile and broke with Xcode updates or when new architectures appeared (e.g., arm64 for the simulator on Apple Silicon).

According to Swift.org (2023), the Swift Package Manager team initially encountered this problem when trying to support binary dependencies. XCFramework solved it at the format level: each slice is a separate folder with an Info.plist describing the target platform and architecture. Xcode automatically selects the required slice at build time, requiring no post-processing.

Advantages of the Separate Slices Approach

Each slice in XCFramework contains only one platform-architecture combination. For example, ios-arm64 contains the binary only for iOS devices, and ios-x86_64-simulator only for the Intel Mac simulator. Xcode automatically selects the correct slice, eliminating the need for architecture removal scripts and reducing the risk of build errors.

The ios-arm64-x86_64-simulator slice was introduced to support Apple Silicon Macs. Previously, the simulator required a separate binary for arm64 (Apple Silicon) and x86_64 (Intel). XCFramework allows a fat binary inside a single simulator slice — this is the only exception where fat binary is justified.

XCFramework Package Structure

An XCFramework package is a directory with the .xcframework extension, containing an Info.plist at the top level and folders with binary slices. Each slice includes a .framework or .a library for a specific platform.

bash
MyLibrary.xcframework/
  Info.plist
  ios-arm64/
    MyLibrary.framework/
      Info.plist
      MyLibrary
  ios-x86_64-simulator/
    MyLibrary.framework/
      Info.plist
      MyLibrary
  macos-arm64-x86_64/
    MyLibrary.framework/
      Info.plist
      MyLibrary

The package Info.plist contains the AvailableLibraries key, listing LibraryIdentifier, LibraryPath, and SupportedPlatform for each slice. Xcode reads this file when adding an XCFramework to a project and automatically configures search paths and the Embed Frameworks phase.

Each slice is a full .framework or static library with its own Info.plist. This allows XCFramework to support mixed types: static libraries for some platforms and dynamic frameworks for others, although in practice one type is used for all slices.

Creating XCFramework from the Command Line

Creating an XCFramework is done via xcodebuild -create-xcframework. The command takes already built .framework or .a libraries for each platform and combines them into a single package.

The process consists of two steps: first, binaries are built for each target platform, then they are packaged into an XCFramework. Standard Xcode destination flags are used for building.

bash
# Step 1: build frameworks for each platform
xcodebuild archive -scheme MyLibrary -destination "generic/platform=iOS Simulator"
xcodebuild archive -scheme MyLibrary -destination "generic/platform=iOS"
xcodebuild archive -scheme MyLibrary -destination "generic/platform=macOS"

# Step 2: create XCFramework
xcodebuild -create-xcframework -framework ./iOS/MyLibrary.framework -framework ./iOSSim/MyLibrary.framework -framework ./macOS/MyLibrary.framework -output ./MyLibrary.xcframework

The -create-xcframework flag was introduced in Xcode 11. The command automatically creates the correct directory structure and generates Info.plist with descriptions of all platforms. If one of the .framework files is damaged or built with the wrong architecture, xcodebuild reports an error at the validation stage.

Automation via Build Scripts

For CI/CD, a shell script is used to automate building for all platforms and creating the XCFramework. A popular approach is a wrapper in the form of a Makefile or Fastlane lane with parameterized scheme and output path.

bash
# build_xcframework.sh - automation script
set -e
SCHEME="MyLibrary"
OUTPUT="./build"

xcodebuild archive -scheme "$SCHEME" -sdk iphonesimulator -archivePath "$OUTPUT/sim.xcarchive"
xcodebuild archive -scheme "$SCHEME" -sdk iphoneos -archivePath "$OUTPUT/dev.xcarchive"
xcodebuild -create-xcframework -framework "$OUTPUT/dev.xcarchive/Products/Library/Frameworks/MyLibrary.framework" -framework "$OUTPUT/sim.xcarchive/Products/Library/Frameworks/MyLibrary.framework" -output "$OUTPUT/MyLibrary.xcframework"

Such a script runs in a CI pipeline (GitHub Actions, Bitrise, Jenkins) after tests pass. The resulting XCFramework is archived and uploaded as a release artifact or published through a dependency manager like CocoaPods using pod spec.

Integrating XCFramework into an Xcode Project

Integrating an XCFramework into an Xcode project does not require manual configuration of search paths. Simply drag the .xcframework into the Frameworks, Libraries, and Embedded Content section in the General settings of the target.

Unlike .framework, XCFramework does not require adding a Run Script phase to remove simulator architectures. Xcode automatically determines available slices and includes only the ones needed for the current build scheme. For a physical device, the ios-arm64 slice is used; for the simulator, ios-arm64-x86_64-simulator or ios-x86_64-simulator.

swift
import MyLibrary

func processData() {
    // XCFramework resolves the correct slice at build time
    let processor = DataProcessor()
    let result = processor.analyze(input: "sample")
    print(result)
}

For CocoaPods, integration is done through a podspec with vendored_frameworks and a list of supported platforms. The dependency manager automatically determines which slices are needed for the project. Many commercial SDKs — Firebase, Adjust, AppsFlyer — have switched to XCFramework to simplify installation.

XCFramework vs Swift Package Manager

Swift Package Manager and XCFramework are not competitors but complement each other. SPM works with source code and builds dependencies on each project build. XCFramework provides ready-made binaries without requiring compilation on the consumer side.

  • XCFramework — binary distribution, source code protection, support for all Apple platforms in one package
  • SPM — open source code, inspectability, automatic build for the target platform
  • SPM binary dependencies use XCFramework as the packaging format, combining both approaches

With the release of Swift Package Manager 5.3, Apple added support for binary dependencies — SPM can now download an XCFramework as a remote dependency. Package.swift specifies the URL of the binary artifact and its checksum for verification.

According to Swift Package Manager documentation (2024), binary dependencies are recommended for SDKs that do not disclose source code, or for libraries whose build time is disproportionately long. For open-source projects, source code distribution via SPM is preferred.

CriterionXCFrameworkSwift Package Manager
FormatBinary (.xcframework)Source code
Code protectionFullNone
Build timeMinimal (copying)Depends on code volume
Platform flexibilityAll Apple platformsDepends on Package.swift
IntegrationDrag-and-drop or SPMPackage.swift

Frequently Asked Questions

What is the difference between XCFramework and .framework?

.framework is a legacy format containing a fat binary with device and simulator architectures. XCFramework stores each slice separately, eliminating architecture conflicts during builds. Apple recommends XCFramework for all new projects and for migrating existing ones.

Can I use XCFramework with CocoaPods?

CocoaPods has supported XCFramework since version 1.9. In podspec, simply specify spec.vendored_frameworks and spec.static_framework. The manager automatically resolves dependencies, taking into account available slices for the project platform.

Is it mandatory to migrate from .framework to XCFramework?

Apple does not remove support for .framework, but recommends XCFramework exclusively for new SDKs. When submitting an app to the App Store with a fat binary in the old format, Invalid Bundle errors may occur due to simulator architectures, making XCFramework a practical necessity.

How does XCFramework work with Swift Package Manager?

Starting with Swift 5.3, binary dependencies in SPM use XCFramework. Package.swift specifies the url and checksum of the binary package. SPM downloads, verifies integrity, and connects the XCFramework as a system dependency without compiling source code.

Does XCFramework support the visionOS platform?

visionOS is supported in XCFramework starting with Xcode 15. At WWDC 2023, Apple confirmed that the format has been extended for Apple Vision Pro. The slice for visionOS has SupportedPlatform = xros and includes the arm64 architecture.

Summary

  • XCFramework is Apple’s modern format for binary library distribution, replacing .framework and solving fat binary problems
  • Separate slices for each platform and architecture eliminate build conflicts and the need for Run Script phases
  • Creation via xcodebuild -create-xcframework is automated in CI/CD and does not require manual binary merging with lipo
  • Integration into an Xcode project is done by dragging .xcframework into the Embedded Binaries section without configuring search paths
  • Swift Package Manager supports XCFramework for binary dependencies, combining management convenience with code protection
  • All Apple platforms — iOS, macOS, tvOS, watchOS, and visionOS — are supported in a single package
  • Recommended to use XCFramework for all new SDKs and when migrating existing .framework libraries

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also