# Swift Package Manager and supported platforms / avoiding \`@available(macOS 10.15.0, \*)\`

**URL:** <https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882>\
**Category:** Using Swift\
**Tags:** spm, packagemanager\
**Created:** [August 25, 2022, 7:02am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882 "2022-08-25T07:02:36Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![sspringer](https://avatars.discourse-cdn.com/v4/letter/s/e9c0ed/32.png) [@sspringer](https://forums.swift.org/u/sspringer)\
**Post date:** [August 25, 2022, 7:02am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/1 "2022-08-25T07:02:36Z")

</div>

The description of how to use the `platforms` in a SPM manifest (`Package.swift`) seems to be ambiguous:

[Citation](https://github.com/apple/swift-package-manager/blob/main/Documentation/PackageDescription.md#supportedplatform%3E):

> By default, the Swift Package Manager assigns a predefined minimum deployment version for each supported platforms unless you configure supported platforms using the `platforms` API. This predefined deployment version is the oldest deployment target version that the installed SDK supports for a given platform.

So what does this mean:

- If a `platforms` entry is used, do I have to list every platform I want to target?
- Or do I only add an entry for the target where I need a certain version?

I would like to avoid `@available(macOS 10.15.0, *)` at every function that uses `async` (not to add those seems to be OK for a normal build, but not for profiling(\*)). I would like to build for macOS \>= 10.15, Linux, and Windows. But [as documented](https://github.com/apple/swift-evolution/blob/master/proposals/0236-package-manager-platform-deployment-settings.md#future-directions) `Platform` or `SupportedPlatform` [does not have a `windows` entry](https://developer.apple.com/documentation/packagedescription/supportedplatform), and even `.linux` cannot be added in `Package.swift`.

* * *

(\*): Maybe this has something to do with SPM vs. Xcode projects, as profiling with Xcode is only possible for Xcode project and not for SPM projects because of the authentication error that occurs for SPM projects when trying to profile.

---

<div class="post-metadata">

**Author:** ![lukasa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lukasa/32/1232_2.png) [@lukasa](https://forums.swift.org/u/lukasa)\
**Post date:** [August 25, 2022, 9:10am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/2 "2022-08-25T09:10:18Z")

</div>

> [@sspringer](#):
>
> If a `platforms` entry is used, do I have to list every platform I want to target?

No. As you noted, you couldn't do that even if you wanted to. The `platforms` directive is intended to behave much like the `@available` directive, but where the `*` is implicit, and implies "all other platforms". So only the platforms you specify are affected.

---

<div class="post-metadata">

**Author:** ![bzamayo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bzamayo/32/764_2.png) [@bzamayo](https://forums.swift.org/u/bzamayo)\
**Post date:** [August 25, 2022, 12:09pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/3 "2022-08-25T12:09:37Z")

</div>

Don't sweat, I have experienced your exact confusion in the past. The `platforms` property is poorly named.

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [August 25, 2022, 11:29pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/4 "2022-08-25T23:29:47Z")

</div>

`platforms: [.macOS(.v10_15)]` is _almost_ the same as slapping `@available(macOS 10.15, *)` on every symbol in the package, except that there is no equivalent to `if #available` to enable clients to use it conditionally. That makes `platforms` very convenient for a top‐level application with no clients. But it also makes it a terrible mistake for any library package, as clients inevitably fork to convert to the more lenient `@available`, and then your package exists double in the ecosystem with clashing identity and you become forever associated with dependency hell.

---

<div class="post-metadata">

**Author:** ![NeoNacho](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/neonacho/32/1368_2.png) [@NeoNacho](https://forums.swift.org/u/NeoNacho)\
**Post date:** [August 26, 2022, 12:35am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/5 "2022-08-26T00:35:17Z")

</div>

> [@SDGGiesbrecht](#):
>
> But it also makes it a terrible mistake for any library package, as clients inevitably fork to convert to the more lenient `@available`, and then your package exists double in the ecosystem with clashing identity and you become forever associated with dependency hell.

This seems like an overly broad statement, e.g. if someone builds a library on top of SwiftUI, it doesn't really make sense to offer it to clients with deployment targets that don't even have SwiftUI.

I think the general rule is, if you make a library that builds entirely on an API or framework with limited availability, `platforms` is a good choice. If the library offers additional functionality that's dependent on a newer deployment target, availability with broader `platforms` is the tool of choice.

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [August 26, 2022, 1:01am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/6 "2022-08-26T01:01:29Z")

</div>

> [@NeoNacho](#):
>
> it doesn't really make sense to offer it to clients with deployment targets that don't even have SwiftUI

If the client has three targets, a data model along with a command line parser and a GUI interface for interacting with it, then the client either restricts the first two targets needlessly to recent platforms, drops your package as a dependency, or forks your package to fix the availability.

While the Swift toolchain packages themselves tend to go for option 1, in the wild I see 2 and 3 being way more popular. Option 2 seems favoured regarding potential new dependencies, which get rejected, and option 3 seems favoured whenever an established dependency adds platform restrictions later on.

---

<div class="post-metadata">

**Author:** ![sspringer](https://avatars.discourse-cdn.com/v4/letter/s/e9c0ed/32.png) [@sspringer](https://forums.swift.org/u/sspringer)\
**Post date:** [August 26, 2022, 5:03am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/7 "2022-08-26T05:03:22Z")

</div>

Good insights. So I think:

- If the core of your library really needs e.g. a certain macOS version, the `platforms` entry should be OK.
- If just a portion of your library needs a certain version and important parts of it do not, better use `availabe` annotations where needed.

( **Update:** See my next comment.)

Another point is if you annotate your library with these version infos at all: E.g. you can create and use a library that uses async/await very well without any version annotation, but if you then want to do profiling using an Xcode project, the profiler (instruments) will complain. So I think:

- If you do use features not available on older platforms, you _should_ use version annotations….

…but I am not sure how far this should go, and even how to know about using features that need version annotations (besides complaining when profiling, the compiler and/or Xcode are not very helpful here).

Also, the question arises if or when certain version annotations will get out-dated i.e. superfluous at a certain point, e.g. should `platforms: [.macOS(.v10_15)]` still be necessary in let´s say five years from now? My current use case is indeed async/await.

I also think that better documentation is needed here (or am I overlooking something?). Maybe a document about best practices with a link to it on the [Swift documentation page](https://www.swift.org/documentation/)?

---

<div class="post-metadata">

**Author:** ![sspringer](https://avatars.discourse-cdn.com/v4/letter/s/e9c0ed/32.png) [@sspringer](https://forums.swift.org/u/sspringer)\
**Post date:** [August 26, 2022, 5:20am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/8 "2022-08-26T05:20:55Z")

</div>

> [@sspringer](#):
>
> - If the core of your library really needs e.g. a certain macOS version, the `platforms` entry should be OK.
> - If just a portion of your library needs a certain version and important parts of it do not, better use `availabe` annotations where needed.

Ah, just when reading my last comment again I really understood one of the problems mentioned:

From the point of a library that really needs a certain version, the `platforms` entry _seems_ to be OK, but this forces another package using this library to the same (or higher) `platforms` entry although the there might be parts of the package that work well without this library. Hmm…

---

<div class="post-metadata">

**Author:** ![sspringer](https://avatars.discourse-cdn.com/v4/letter/s/e9c0ed/32.png) [@sspringer](https://forums.swift.org/u/sspringer)\
**Post date:** [August 26, 2022, 5:42am UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/9 "2022-08-26T05:42:21Z")

</div>

…So:

- As a first „rule“, use `available` and not `platforms` for a library.
- If it is clear that your application or any application using your library will only be used in a certain context, you might use `platforms` to avoid the many `available` annotations that you else would have to use.

---

<div class="post-metadata">

**Author:** ![taylorswift](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/taylorswift/32/43413_2.png) [@taylorswift](https://forums.swift.org/u/taylorswift)\
**Post date:** [February 17, 2023, 10:06pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/10 "2023-02-17T22:06:17Z")

</div>

> [@SDGGiesbrecht](#):
>
> `platforms: [.macOS(.v10_15)]` is _almost_ the same as slapping `@available(macOS 10.15, *)` on every symbol in the package, except that there is no equivalent to `if #available` to enable clients to use it conditionally. That makes `platforms` very convenient for a top‐level application with no clients. But it also makes it a terrible mistake for any library package, as clients inevitably fork to convert to the more lenient `@available`, and then your package exists double in the ecosystem with clashing identity and you become forever associated with dependency hell.

is there a way to apply this at the module level, as opposed to the package level? i have some modules that are quite useless without swift concurrency, but some other modules that have no relationship to swift concurrency, and `platforms: [.macOS(.v10_15)]` seems like overkill here.

---

<div class="post-metadata">

**Author:** ![SDGGiesbrecht](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sdggiesbrecht/32/4768_2.png) [@SDGGiesbrecht](https://forums.swift.org/u/SDGGiesbrecht)\
**Post date:** [February 17, 2023, 10:18pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/11 "2023-02-17T22:18:26Z")

</div>

Not from the manifest. But a plug‐in could automate slapping `@available` on everything in a module (either for check‐in or during the build), and macros might make it even easier soon.

---

<div class="post-metadata">

**Author:** ![mesqueeb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mesqueeb/32/35666_2.png) [@mesqueeb](https://forums.swift.org/u/mesqueeb)\
**Post date:** [July 8, 2025, 7:32pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/12 "2025-07-08T19:32:49Z")

</div>

I’d love to propose a future direction for SwiftPM:

Instead of requiring `platforms` or `@availability` just to access modern Swift features like concurrency, what if we could declare minimum Swift _language_ compatibility directly in Package.swift?

Something like:

```swift
dependencies: [.swiftVersion("5.9")]

```

This would be clearer for cross-platform libraries (Linux, Windows, etc.) where OS versioning doesn’t apply the same way.

Platforms like macOS can just use that information during compile time to determine if their version satisfies that constraint or not.

Would love to hear thoughts or see if this has been discussed already.

Does anyone know where I can share this vision with the relevant ecosystem maintainers?

---

<div class="post-metadata">

**Author:** ![lukasa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lukasa/32/1232_2.png) [@lukasa](https://forums.swift.org/u/lukasa)\
**Post date:** [July 14, 2025, 12:57pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/13 "2025-07-14T12:57:55Z")

</div>

SwiftPM already has this feature in the form of the `tools version` at the top of the package manifest.

If you are running a compiler version that is older than the tools version in the manifest, SwiftPM will not resolve the package version. The Swift Server projects use this as a way to formally drop older compilers without breaking those codebases, by incrementing that number each year.

Unfortunately, this does not replace the capabilities of `platforms`. The minimum deployment target of a binary is a separate concern from the tools used to build the binary. One of the features of Apple's platform, and Windows, and some limited number of Linuxes, is that you can _build_ with newer tools than you use to _run_. That is what the platform availability markers are for.

---

<div class="post-metadata">

**Author:** ![UniverseObserver](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/universeobserver/32/39985_2.png) [@UniverseObserver](https://forums.swift.org/u/UniverseObserver)\
**Post date:** [November 25, 2025, 2:15pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/14 "2025-11-25T14:15:26Z")

</div>

Would love to see a lenient version of `platforms`. Currently I'm working on a package that targets iOS 16 and wants to use a dependency available in iOS 18 when the package is used in iOS 18. I don't control the dependency source code; thus creating a fork of the dependency and marking everything using `@available` seems to be the only option. This doesn't seem sustainable in long run, especially for large dependencies. Would love to make a pitch to see people's opinion on this 🤔

---

<div class="post-metadata">

**Author:** ![dschaefer2](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dschaefer2/32/46516_2.png) [@dschaefer2](https://forums.swift.org/u/dschaefer2)\
**Post date:** [November 25, 2025, 4:31pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/15 "2025-11-25T16:31:14Z")

</div>

If packages are setting the minimum deployment target to an OS version, we are assuming it’s using APIs that are only in that version and later and won’t build with lower versions. That’s why the check is there. If that’s not true for a package then they’ve set the version wrong and should be considered a bug.

There has been discussion about taking into account minimum deployment when resolving packages so if there is a version available that supports a lower version, the resolver would pick that version instead to ensure the build works. Though it’s not clear how we’d implement that.

---

<div class="post-metadata">

**Author:** ![Jon\_Shier](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jon_shier/32/921_2.png) [@Jon\_Shier](https://forums.swift.org/u/Jon_Shier)\
**Post date:** [November 25, 2025, 8:43pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/16 "2025-11-25T20:43:00Z")

</div>

Yes, that's the strict checking people are asking to avoid. What many would like to see is a mode where the deployment target of the package is ignored in favor of the consumer's and the package's public API is given an automatic availability attribute equal that defined in the package. That would allow consumption by any consumer without forcing the package to conditionalize its entire public interface manually (I've had to do that, it's not fun).

---

<div class="post-metadata">

**Author:** ![mesqueeb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mesqueeb/32/35666_2.png) [@mesqueeb](https://forums.swift.org/u/mesqueeb)\
**Post date:** [November 25, 2025, 9:08pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/17 "2025-11-25T21:08:13Z")

</div>

Even for pure Swift libraries, new Swift language features often require new **Swift runtime support**.  
Because Apple ships the Swift runtime inside the OS, library authors today have to manually map “Swift language version → OS version”.

Declaring only `swift-tools-version` isn’t enough — the compiler will accept the code, but the runtime might not have the necessary symbols. That’s why authors are forced to use `platforms` even when the package uses absolutely no OS APIs like UIKit, swiftUI, ...

What would help enormously is the ability to declare a **minimum Swift runtime version** ,  
independent of OS availability. For example:

```
runtimeDependencies: [.swiftVersion("5.9")]

```

SwiftPM or Xcode could then automatically translate that into the appropriate minimum OS versions behind the scenes. The mapping exists, the compiler already knows which OS releases introduced runtime support for which features, and **no pure-Swift library author actually wants to maintain that matrix manually**.

This would allow `platforms` to stay focused on what it’s good at — OS-specific APIs — and let  
pure Swift libraries simply declare the Swift runtime semantics they rely on, **without being  
forced to reason about every platform’s OS timeline**.

---

<div class="post-metadata">

**Author:** ![Cyberbeni](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/cyberbeni/32/46241_2.png) [@Cyberbeni](https://forums.swift.org/u/Cyberbeni)\
**Post date:** [November 25, 2025, 10:20pm UTC](https://forums.swift.org/t/swift-package-manager-and-supported-platforms-avoiding-available-macos-10-15-0/59882/18 "2025-11-25T22:20:41Z")

</div>

There was a pitch recently about this: [[Pitch] Swift runtime availability](https://forums.swift.org/t/pitch-swift-runtime-availability/82742)
