Swift Package Manager needs its own Nuget

I saw this PR today which made me worried:

Here are my thoughts below. (Machine translated from zh-Hans; I manually reviewed the texts.)


Strongly negative on the direction proposed in this PR, despite understanding the GOOD intention behind it.

Conclusion upfront: Swift needs a first-party, ecosystem-neutral package hosting solution (akin to NuGet), rather than further deepening coupling with any single third-party platform.

Concerns

  1. Over-reliance on GitHub as infrastructure

    Swift Package Manager already has a de facto dependency on GitHub, since a large portion of packages are hosted there. This PR appears to further institutionalize that dependency at the tooling level.

    From an ecosystem design perspective, this introduces a structural risk:

    • A single platform becomes a critical dependency for package discovery and distribution
    • Availability, access policy, or regional connectivity issues directly impact Swift development workflows
    • It weakens the long-term portability of the ecosystem
  2. Global accessibility and reliability

    In some regions, access to GitHub is unstable or degraded. While this may not be a primary concern for all contributors, it does affect real-world usability of SPM at scale.

    Tooling decisions should ideally avoid hard dependencies on infrastructure that is not universally reliable.

  3. Ecosystem neutrality

    A language-level package manager should remain platform-agnostic. Tight coupling with a specific hosting provider (even implicitly) creates:

    • Perception of vendor lock-in
    • Reduced incentive for alternative registries or mirrors
    • Barriers for organizations with internal or self-hosted infrastructure

Suggested Direction

Instead of reinforcing GitHub-centric workflows, I would strongly encourage exploring:

  • An official Swift package registry ecosystem (similar in spirit to NuGet)
  • First-class support for multiple registries and mirrors
  • Clear separation between package identity and hosting location

This would:

  • Improve resilience and global accessibility
  • Encourage a healthier, more decentralized ecosystem
  • Align Swift with the direction taken by other modern language ecosystems

Final Note

The intention behind improving usability is appreciated. However, the current direction may solve short-term friction at the cost of long-term ecosystem robustness.

I would recommend reconsidering the approach from a more infrastructure-neutral standpoint.

11 Likes

Thanks @ShikiSuen! I appreciate your words here.

Better mirroring support is one of the main areas we need to look at for SwiftPM. We know a lot of teams that have internal git mirrors of packages on GitHub, mainly for supply chain security and to ensure availability. Those teams may not benefit from a performance enhancement that is specific to GitHub APIs. I also see teams reaching for internal package registries as a performance solution. And that’s why we continue to support package registries today.

As you mention, SwiftPM does need a better way to declare that a package with a given identity is hosted at multiple locations and the user needs a good way to specify the priority order of those locations so SwiftPM can make the right choice depending on the circumstances.

I think this PR that speeds up packages stored GitHub is a good thing for a lot of users. We just need to make sure we keep the architecture clean as more and more of these solutions come about so that we can work them into a better mirroring solution and potentially other fundamental features we may add to packages over time, like a better way to do binary artifacts or integrate non-package source archives and external build systems, or whatever else we can dream up to make Swift Packages better :).

2 Likes

Hi, Doug. Thanks for the thoughtful reply. I really appreciate you taking the time to address my concerns.

I completely agree that better mirroring support is one of the highest-priority areas for SwiftPM. Your point about teams already using internal Git mirrors (for supply-chain security and availability) and the need for a clean way to declare that the same package identity can be hosted at multiple locations — with user-specified priority — is exactly the direction I was hoping for.

To make that concrete, I’d love to see a future feature that lets users configure their own URL-replacement map (original URL → mirror URL). This would allow SPM to automatically rewrite repository URLs at resolution time, including for transitive dependencies.

A practical real-world example: GitHub access is often unstable or very slow from within Mainland China. Domestic mirrors like Gitee and AtomGit already host many popular Swift packages (and SPM’s SHA verification keeps this safe), but the internal dependencies of those packages frequently still point back to GitHub. The result is that Xcode can hang for hours during dependency resolution.

A configurable mirror map would solve exactly this kind of scenario without requiring changes to every upstream Package.swift.

Again, thank you for the reply and for confirming that mirroring is already on the roadmap. Looking forward to seeing how this evolves.

(This reply is translated using Grok to make the English reading experience more-comfortable. I post-reviewed this translation result.)

2 Likes

We do have that capability today using swift package config set-mirror. It is a simple URL rewrite and will actually work with binary artifacts in upcoming releases too. However it doesn’t work if you’re trying to mirror to a package registry.

1 Like

Thanks for these intel. It helps a lot. I have 2 questions:

  1. You mentioned upcoming releases. Is this Swift 6.4?
  2. I can’t understand what is mirror to a package registry. Is package registry something different than a package URL?

Over-reliance on GitHub as infrastructure

GitHub is already relied on; this simply gives another endpoint to GitHub.
Support for GitLab and BitBucket can easily be added. Nothing is being taken away.

Global accessibility and reliability

I doubt that a small team can do a better global availability and reliability.

Ecosystem neutrality

It does remain agnostic; if a GitHub HTTP URL is detected, instead of cloning a full repository, a smaller tarball will be fetched; swift-nio download will become 2MB instead of 80MB; won't this make your Xcode downloads much faster and more stable?

  • An official Swift package registry ecosystem (similar in spirit to NuGet)

There needs to be a team to manage this, someone needs to pay for bandwidth costs, someone needs to ensure that the code hosted is correct and not-compromised and replaced from the source to what is being served out.

Neither https://proxy.golang.org/ nor https://crates.io/ host Git, they serve only source tarballs.

1 Like

Where there’s a long-standing need that’s long-neglected, there are typically structural reasons.

It’s easy to elaborate features that would be good for Swift open-source developers in this regard, but who can sustainably satisfy the high level of trust and engineering required to deliver and maintain, and why would they?

The people behind the PR have contributed a well-founded, well-engineered tweak to current practice that adds measurable benefits, but no extra downsides (assuming the added complexity doesn’t get tripped up). How would holding up this PR help with the structural problem?

2 Likes

The mirrors functionality has been there for a long time. It’s coming to binary artifacts in a cherry-pick I just pushed in for the next 6.3 release.

In a sense, package registries are a mirror at given versions of a package. They actually end up being new package identities so aren’t handled by the mirrors file. It would be nice to have a common solution that handles both.

1 Like

Git itself supports lightweight clones that don’t include the full history. I’m no guru so I can’t rattle off how to do it; but I’ve used this in the past to clone [subdirectories of] LLVM cheaply. Couldn’t this proposal use that feature instead of a GitHub-specific download API? (Or at least as an alternative when the repo isn’t hosted by GitHub?)

1 Like

The current git clone is done for version resolution so we know what versions we have and we can look at each version’s package manifest so we can see what each one depends on. Based on which version that package resolves to we then do a shallow clone into the scratch path from the clone in the SwiftPM cache.

A package registry or the currently proposed use of the Github APIs is intended to speed that up by providing alternative means of finding the versions and fetching the manifests and avoid the full clone and only fetch the resolved version’s source archive.

Git was a great way to launch the Swift ecosystem and has really paid off. Now that we have so many complex packages with lots of dependencies, we are seeing a lot of contributors working on different ways to speed things up. That’s great to see.