Creating a Swift Package
At it's core, the entire Edge developer experience is built around Swift and Swift Packages.
Developer Requirements
- It's recommended that you develop on a macOS or Linux Machine. If you have a Windows machine, you can use the Windows Subsystem for Linux (WSL) to develop on a Linux machine.
- We highly recommend only targeting Swift 6.1 and above.
Make sure you have swift installed.
Creating a Swift Package
To create a Swift Package, you can use the swift package init
command. This will create a new Swift Package in the current directory.
macOS
# Create a new directory for the package
mkdir MyCoolLibrary
# Navigate to the directory
cd MyCoolLibrary
# Initialize the package
swift package init --type library --name MyCoolLibrary
This will create a new Swift Package in the current directory. The --type library
flag will create a library package.
With your favorite text editor; (we recommend VSCode, Cursor, or Windsurf) open the directory with:
macOS
# if you have VSCode installed
code .
# if you have Cursor installed
cursor .
# if you have Windsurf installed
windsurf .
Then begin coding.
- All of your swift source code should be in the
Sources
directory. - All of your tests should be in the
Tests
directory. - If you have any resources such as images, files, or other assets, you can put them in the
Resources
directory and make sure to add them to thePackage.swift
file like so:
Package.swift
let package = Package(
name: "MyCoolLibrary",
resources: [.process("Resources")]
)
Source Code
Add all of your source code to the Sources
directory like so:
Sources/MyCoolLibrary.swift
public func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
Any method you want to be accessible to other Swift Packages should be marked as public
.
Testing
You'll always want to write unit tests for your code. We highly recommend only using Swift Testing for your tests instead of XCTest.
Add all of your tests to the Tests
directory like so:
Tests/ContinentsTests.swift
@testable import MyCoolLibrary
@Test("Addition of two numbers", arguments: [
(1, 2),
(2, 3),
(3, 4),
(4, 5),
])
func additionOfTwoNumbers(a: Int, b: Int) async throws {
let result = try await MyCoolLibrary.add(a, b)
#expect(result == a + b)
}
macOS
swift test
Building
To build your package, you can use the swift build
command. This will build your package and output the binary to the ./build
directory.
Releasing a package
- We recommend publishing your package to GitHub where the current directory is the root of the package.
- Then make a new release on GitHub. If you have the
gh
CLI installed, you can use thegh release create
command to create a new release with:
macOS
gh release create v1.0.0
Tips
We recommend taking a look at our CBOR library as inspiration for your own package. You could clone it, and modify it to be a good starting point for your own package.
Using Your Package from GitHub
Once you've published your package to GitHub, other developers can easily use it in their projects. In the downstream project's Package.swift
file, add your package as a dependency:
Package.swift
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyApp",
dependencies: [
// Add your package from GitHub
.package(url: "https://github.com/yourusername/MyCoolLibrary.git", from: "1.0.0")
],
targets: [
.target(
name: "MyApp",
dependencies: [
// Add the package to your target dependencies
.product(name: "MyCoolLibrary", package: "MyCoolLibrary")
]
)
]
)
You can specify the version in different ways:
from: "1.0.0"
- Use version 1.0.0 or any newer versionexact: "1.0.0"
- Use exactly version 1.0.0.upToNextMajor(from: "1.0.0")
- Use any version from 1.0.0 up to (but not including) 2.0.0branch: "main"
- Use a specific branchrevision: "abc123..."
- Use a specific commit
Using Your Package Locally
During development, you might want to use a local version of your package. This is useful when you're developing both the package and the app that uses it simultaneously. You can specify a local path in your Package.swift
:
Package.swift
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyApp",
dependencies: [
// Add your package from a local path
.package(path: "../MyCoolLibrary")
],
targets: [
.target(
name: "MyApp",
dependencies: [
// Add the package to your target dependencies
.product(name: "MyCoolLibrary", package: "MyCoolLibrary")
]
)
]
)
When using a local package path:
- The path is relative to the location of the
Package.swift
file - Changes to the local package are immediately reflected when you build
- This is perfect for testing package changes before publishing
- Remember to switch back to a versioned dependency before releasing your app