Publishing a Swift Package

This article is the third post in a series about SPM. If you don’t know what a Swift Package is, I recommend you to take a look at the first and second articles. Today we’ll explore how we can publish and version a package.

Centralized vs. Decentralized

Dependency managers can have two different strategies for organizing and fetching their packages. They can be centralized or decentralized.

A centralized dependency manager has a central place where all packages are located. It then uses this place to fetch a dependency. The advantage of this approach is that it offers easy discoverability (e.g: a website we can use to search for dependencies).

A decentralized dependency manager doesn’t have a specific place containing all registered packages. It allows dependencies to be published independently, requiring us to inform their URL to fetch them. The advantage of this approach is that it doesn’t rely on a single source, which makes it more flexible and resilient to failures.

Git usage

SPM is decentralized, and makes heavy use of Git. Xcode offers an option to initialize a local Git repository when we create a package:

You can initialize the git repository when creating a package.

It also adds an initial commit for us:

The initial commit Xcode added for us.

The default folder structure even comes with the and .gitignore files (notice we also have the .git folder for our local repository):

The listed files under our package folder.

Creating a remote repository

To publish a package, all we need to do is create a remote Git repository and push our local package commits to it. SPM will then be able to fetch the package. We’ll be using Github, but we can publish a package to other Git servers as well.

When creating the repository, make sure you mark it as public and that it’s empty (doesn’t include a or license):

Creating a repository on Github.

Once the remote repository is created, we need to configure the remote inside our package:

Configuring a remote.

After we push our local commits, we can use the repository URL to fetch the package:

Fetching our package.

Private packages

It’s pretty common to develop and use private packages. They belong to a person or organization, and are shared internally with multiple apps or packages. Their publication process is the same, but the repository is private.

To fetch private packages, we need to configure how we authenticate to the Git server we’re using. SPM will then be able to access our private repositories. There are two common protocols we might use: HTTPS and SSH.

To setup authentication, we first need to configure a Github account in the preferences panel (preferences -> Accounts). Xcode will require a personal access token. To get one, follow the steps in this link.

Accounts panel: preferences -> accounts


Authenticating with HTTPS is simple. Once we have the account in place, we need to ensure it will clone the repositories using this protocol:

A Github account using HTTPS.


SSH is more complicated to be configured. This link explains it in detail. When creating the keys, make sure you don’t use the ssh-ed25519 encryption algorithm, because it’s unsupported (we need to use RSA instead):

Don’t use the ed25519 algorithm.
Use RSA instead. The instructions are in this link.

Once we have SSH setup, we need to configure our Xcode account to use our private key. Notice that we also need to clone using SSH:

Configuring the account to use ssh.


Once we publish our package, we need to ensure its clients receive updates. SPM uses git tags to mark the versions of a package, and we use semantic versioning to organize them. We release a new version when we want the clients to receive a change. It might be a bug fix or performance improvement, for example.

The workflow for releasing a new version is pretty simple:

# To list our versions:
git tag

# To create a local version:
git tag -a major.minor.patch -m "tag description"

# To publish a version:
git push origin major.minor.patch

# To remove a version already published:
git push origin --delete major.minor.patch
git tag -d major.minor.patch

To summarize

  • SPM makes heavy use of Git
  • We can initialize a Git repository when creating a package
  • To publish a package, push its local changes to a remote repository
  • To fetch private repositories, configure the Xcode account with either HTTPS or SSH
  • Use git tags to manage the versions of a package

Versioning packages is an important topic that deserves attention. In the upcoming article, we’ll look into it in more detail.

2 thoughts on “Publishing a Swift Package

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s