This recipe cites all best practices we follow and documents exactly how we created the Swift 6 Module Template which is the xxPROJECTxNAMExx folder in this repo.
Please follow along and you should create a template that is identical to the one we provided. If this recipe is not perfect (or your result is different from our template in any way) then please submit an issue or pull request.
This recipe may also be useful for other scenarios, for example maybe you want to make a project that has the Example app using storyboards instead of SwiftUI.
During the steps of this recipe we enter specific values where needed. These are chosen carefully so that the ./configure.swift script can later find and replace these values in the template to create your project.
-
xxPROJECTxNAMExx- This must be a valid C99 extended identifier (otherwise the Xcode check dependencies step fails). It cannot contain spaces.
- This must also be a Uniform Target Identifier (
/^[a-zA-Z0-9-.]+$/). - If this contains the characters
-or.then they will be transliterated to_for file names.
-
__ORGANIZATION_NAME__- This intentionally has a space which causes Xcode to use double quotes in its project configuration files.
-
com.AN.ORGANIZATION.IDENTIFIER -
__AUTHOR_NAME__- This intentionally has a space which causes Xcode to use double quotes in its project configuration files.
-
__TODAYS_DATE__ -
__TODAYS_YEAR__ -
__GITHUB_USERNAME__
Complete all these instructions on the same calendar day.
Use Xcode version 26.0.1 (17A400). This is the latest publicly released or Gold Master version.
A previous version of this recipe is also demonstrated in a YouTube flyover at https://youtu.be/ksYXtNn8lhE (15 minutes).
- In Xcode, choose File > New > Package…
- Choose Multiplatform > Library > Library, and click "Next"
- For testing system, select Swift Testing, and click "Next"
- Navigate to your Desktop folder
- Type the name
xxPROJECTxNAMExx - Ensure "Create Git repository on my Mac" is unchecked
- Click “Create"
-
Use Terminal.app to insert some files into the project
cd ~/Desktop/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/ curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/xxPROJECTxNAMExx.swift' -o xxPROJECTxNAMExx.swift curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/Sources/xxPROJECTxNAMExx/White%20King.swift' -o White\ King.swift curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/refs/heads/main/xxPROJECTxNAMExx/Tests/xxPROJECTxNAMExxTests/xxPROJECTxNAMExxTests.swift' -o ../../Tests/xxPROJECTxNAMExxTests/xxPROJECTxNAMExxTests.swift
-
Quit Xcode :information_source: This is a workaround for a bug introduced in Xcode 16.4 (16F6) where opening a Swift package then also opening a project containing that package at the same time produces the error:
Compiled module was created by a different version of the compiler '6.1.0.110.21'
ℹ️ This is also a separate workaround for a separate bug introduced in Xcode 16.4 (16F6) which reproducibly crashes the program at this step if you attempt to build the Example project and then close that window.
- In Xcode, choose File > New > Project…
- Choose a template
- Click iOS > Application > App, and click "Next"
- Set the project options
- Set Product Name to "Example"
- Set Team to "None"
- Set Organization Identifier to
com.AN.ORGANIZATION.IDENTIFIER - Set User Interface to "SwiftUI"
- Set Language to "Swift"
- Set Testing System to "Swift Testing with XCTest UI Tests"
- Set Storage to "None"
- Ensure "Host in CloudKit" is not selected
- Click “Next"
- Create the project
- Ensure “Create Git Repository on my Mac" is not selected
- Ensure "Add to" is “Don’t add to any project or workspace"
- Select the folder
xxPROJECTxNAMExxon the desktop (don't double click it) - Click “Create"
- Choose a template
- Move Example source code to a folder named "Sources"
ℹ️ The Alamofire project uses the folder name "Source" but we choose "Sources" here to be consistent with the default of Swift Package Manager.
-
Open the file Example.xcodeproj in Xcode (it's on your desktop, in the xxPROJECTxNAMExx > Example folder)
-
Show the Project navigator on the left (folder icon)
-
Use the Project navigator to select the "Example" folder (blue icon)
-
From the Project navigator, rename this folder as "Sources"
-
-
Use Terminal.app to insert some files into the project
cd ~/Desktop/xxPROJECTxNAMExx/Example/Sources curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/Example/Sources/ContentView.swift' -o ContentView.swift
ℹ️ You will see "Module compiled with Swift 6.1.2 cannot be imported by the Swift 6.2 compiler", but we will resolve this in the step "make your example application depend on your module" below.
- Open Example.xcodeproj in Xcode
- In Xcode, choose File > Add Package Dependencies...
- Click "Add Local..."
- Select the folder
xxPROJECTxNAMExxon the desktop (don't double click it) - Click "Add Package"
- In the choose package products, set the "add to target" to "Example", and click "Add Package"
These files represent best practices which every open source Swift module author should adopt for published code.
-
Use Terminal.app to add additional files to the project
cd ~/Desktop/xxPROJECTxNAMExx/ curl 'https://raw.githubusercontent.com/github/gitignore/main/Swift.gitignore' -o .gitignore mkdir -p .github/workflows curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/.github/workflows/ci.yml' -o .github/workflows/ci.yml curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/LICENSE' -o LICENSE curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/README.md' -o README.md curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/CHANGELOG.md' -o CHANGELOG.md curl 'https://raw.githubusercontent.com/fulldecent/swift6-module-template/main/xxPROJECTxNAMExx/CONTRIBUTING.md' -o CONTRIBUTING.md
This step allows everybody to achieve byte-for-byte consistency with the published Swift 6 Module Template but otherwise provides no value to you.
-
Use Terminal.app to find and replace all occurrences of hard-coded strings with template variables
find -E ~/Desktop/xxPROJECTxNAMExx \ -type f -name '*.swift' -exec sed -i '' -E -e ' s-(// +Created by ).*( on ).*\.-\1__AUTHOR_NAME__\2__TODAYS_DATE__.- s-(// +Copyright © ).*-\1__TODAYS_YEAR__ __ORGANIZATION_NAME__. All rights reserved.-' \ '{}' \;
-
Open Example.xcodeproj in Xcode
-
Use the scheme navigator to select Example and the latest iPhone version simulator
-
Choose Product > Run :white_check_mark: You should see a big white king (♔) after a few moments. That means it worked!
ℹ️ You may see a nag screen in your app about Apple Intelligence. This advertisement is installed by Apple and Apple prevents you from removing it.
-
Compare with the distributed Swift 6 Module Template repository
-
Use Terminal.app to clone the repository to your Developer folder
git clone https://github.com/fulldecent/swift6-module-template.git ~/Developer/swift6-module-template -
Compare the distributed version with your version
cd ~/Developer/swift6-module-template rm -rf xxPROJECTxNAMExx cp -r ~/Desktop/xxPROJECTxNAMExx . git diff
- ✅ You should see an empty screen indicating no differences (press q to close)
- 📣 If you see differences, please raise an issue in the project repository
-