A dependency mirror refers to an alternate source location which exactly replicates the contents of the original source. [1]

I often end up in the same situation: I need to tweak an internal package that a project depends on. The usual options are:

  • Drag and drop the repo into Xcode (Xcode replaces the remote dependency with the local copy)
  • Change Package.swift to a local path dependency

Both work, but I prefer a CLI-only workflow. Turns out SPM has a cleaner alternative: dependency mirroring!

Set a Mirror

Point the remote URL to a local repo:

swift package config set-mirror --original "THE_ORIGINAL_URL" --mirror "LOCAL_PATH"

# Example
# swift package config set-mirror --original "https://github.com/apple/swift-argument-parser" \
#   --mirror "/Users/user/Developer/swift-argument-parser"

To confirm:

swift package config get-mirror --original "https://github.com/apple/swift-argument-parser"

Important Notes

  • A mirror only changes where SPM fetches the repo from. It still resolves a version, branch, or revision.
  • If you want local edits to show up, you must commit them in the mirrored repo.
  • Use a branch or revision in Package.swift:
dependencies: [
    .package(url: "https://github.com/apple/swift-argument-parser", branch: "main"),
]
  • Mirrors are matched by the exact URL string. If your dependency uses the .git suffix, set a mirror for that URL too.

Remove the Mirror

Once you are done, remove it:

swift package config unset-mirror --original https://github.com/apple/swift-argument-parser

If you added a .git mirror, remove that one as well.

Closing Thoughts

Mirrors are not a drop-in replacement for local path dependencies. You still need to commit changes, but in return you get a clean, repeatable CLI workflow that works across projects without touching Xcode.

Resources