# Cross-Import Overlay status?

**URL:** <https://forums.swift.org/t/cross-import-overlay-status/74090>\
**Category:** Discussion\
**Created:** [August 21, 2024, 2:12pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090 "2024-08-21T14:12:26Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [August 21, 2024, 2:12pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/1 "2024-08-21T14:12:26Z")

</div>

What's going on with cross-import overlays? ([original pitch](https://forums.swift.org/t/cross-import-overlays/30868), [follow up](https://forums.swift.org/t/cross-import-overlays/36710)) As far as I can tell, I can't find any movement on them in the past three years, but they exist in the Apple device SDKs (macOS Sonoma has 20 of them in `/System/Library/Frameworks` and 6 more in `PrivateFrameworks`).

I would _love_ to have the ability to make these myself, especially via SPM. Just some casual examples off the top of my head:

- I have my [Time](https://github.com/davedelong/time) library, and I think it'd be great to add some extensions to SwiftUI to access clocks and regions via the Environment, or modifiers to observe the passing of temporal boundaries, etc. But I don't want to _force_ my users to import SwiftUI by linking it myself, nor do I really want to have a separate `TimeUI` target. Having an overlay would make these extensions automatically available to users if they've imported `Time` and `SwiftUI`.
- I've wanted to build a nice package that abstracts dealing with system permission prompts, but I don't want to have to import the entire world (CoreLocation, EventKit, ScreenRecording, HealthKit, CoreBluetooth, Photos, Contacts, HomeKit, ...) just to provide shims for things a package consumer might want to use. Having an overlay would make the right things show up to users if they happen to import both.
- I've got extensions to other frameworks in my Repo Of Swift Extensions that I don't always need; it'd be nice to shift those out into overlays so I only get the binary increase size at link time if I actually need them.

So … where are things at with these?

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [January 2, 2025, 10:15pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/3 "2025-01-02T22:15:24Z")

</div>

So I guess the answer here is that they've been abandoned and we won't get to use them? They'll remain an Apple-only tooling feature? 😢

---

<div class="post-metadata">

**Author:** ![tevelee](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/tevelee/32/9775_2.png) [@tevelee](https://forums.swift.org/u/tevelee)\
**Post date:** [January 2, 2025, 10:43pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/4 "2025-01-02T22:43:48Z")

</div>

I know it’s not quite the same, but with the acceptance of [SE-0450](https://github.com/swiftlang/swift-evolution/blob/main/proposals/0450-swiftpm-package-traits.md), perhaps now you can define a trait in SPM for each overlay respectively.

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [January 2, 2025, 10:56pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/5 "2025-01-02T22:56:19Z")

</div>

That is an _extremely_ intriguing idea. It does put a bit of burden on the client to make sure they define the correct traits, but I can think of ways to mitigate that as well.

Thank you for the idea! I need to go experiment 😁

---

<div class="post-metadata">

**Author:** ![Frizlab](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/frizlab/32/416_2.png) [@Frizlab](https://forums.swift.org/u/Frizlab)\
**Post date:** [January 2, 2025, 11:06pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/6 "2025-01-02T23:06:59Z")

</div>

Very interesting indeed!  
I’ll keep an eye on this thread; I’m very interested in this subject (`System` vs. `SystemPackage` in my case).

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [January 3, 2025, 12:12pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/7 "2025-01-03T12:12:54Z")

</div>

FYI package traits are now available in 6.1 development snapshots (proposal metadata hasn't been updated yet): [Mark SE-0450 (package traits) as implemented in 6.1 by MaxDesiatov · Pull Request #2641 · swiftlang/swift-evolution · GitHub](https://github.com/swiftlang/swift-evolution/pull/2641)

---

<div class="post-metadata">

**Author:** ![FranzBusch](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/franzbusch/32/19447_2.png) [@FranzBusch](https://forums.swift.org/u/FranzBusch)\
**Post date:** [January 3, 2025, 1:37pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/8 "2025-01-03T13:37:16Z")

</div>

> [@davedelong](#):
>
> That is an _extremely_ intriguing idea. It does put a bit of burden on the client to make sure they define the correct traits, but I can think of ways to mitigate that as well.
> 
> Thank you for the idea! I need to go experiment 😁

This is definitely one use-case we had in mind for package traits. While they don't automagically work when a module depends on both module `A` and `B` to expose these cross-overlay imports, they do allow a package to expose a feature that enables an optional dependency and additional API depending on that optional dependency.

I am really looking forward to see how we adopt those in the ecosystem.

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [February 23, 2025, 4:02pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/9 "2025-02-23T16:02:10Z")

</div>

I downloaded Xcode 16.3 beta 1 the other day to try out this approach, and I'm pleased to report that it _mostly_ works.

# The Good

- I can create a package with traits, and the trait names get exposed in code as active compilation conditions.

- I can depend on this package in another package and enable the traits in the `.dependency(...)` statement

- With these together and some creatively-applied `@available(*, unavailable, message: "...")` statements, I can make a package that proactively tells clients that they're trying to use an API without the proper trait enabled.

# The Meh

- Conditional compilation is kind of gross. It balloons the complexity of the code when used within method bodies, and using it to conditionalize the existence of methods themselves means that there's a constant battle to make sure that the true-branch method matches the false-branch method. I will need to investigate better ways to organize the code to see if I can mitigate this. Perhaps multiple targets combined with some `@_exported` imports? Or complex source file inclusion based on trait enablement somehow?

- It's a stringly-typed API, which means it's easy to fat-finger a trait name. Yes, the compiler will tell you that the mis-typed trait, but there is zero code-completion.

- I'm surprised that the trait applies to the entire _package_ and not to a specific _dependency_. It's common to deal with packages that have multiple products, and I'm surprised that each product has to use the same set of traits. Or you could easily imagine a package that defines a "debug" trait to enable extra introspection capabilities. A client of the package would only want to use that for specific targets, not _every_ target. The fact that you cannot specify traits on a per-usage basis seems like a pretty unfortunate design.

# The Ugly

- Xcode has no support for any of this in Xcode projects. There is no way to specify active traits when depending on a package. This is a feature that is only available to other packages. This means that, in its current form, it essentially unusable to me without the tedious chore of creating intermediate packages.

- Additionally when editing, there is no way to discover what the compilation condition of the trait actually is. I have to know _a priori_ how the compiler will translate my trait name into a condition. Since trait names are strings that can contain things like spaces or emoji or slashes or zalgo text... Once again I'm left completely high-and-dry by the tools to use this in any sort of way that is a single step beyond the most rudimentary:

 ![Screenshot 2025-02-23 at 9.13.05 AM](https://global.discourse-cdn.com/swift/original/3X/b/4/b4c30a776ffd8d0a3b64bd80d0b9ef9d7d0515cc.png)

**edit** : aha, it turns out that particular screenshotted trait name isn't legal. However, Xcode will still succeed building the package even though the package itself is invalid. 🤣 The point still stands though about the un-discoverability of condition names:

 ![Screenshot 2025-02-23 at 9.20.21 AM](https://global.discourse-cdn.com/swift/original/3X/e/9/e99dcce73c6f28b0cf4432c7fba57daac5a6c60a.png)

* * *

This feels like a step in the right direction, and I appreciate the hint to try this @tevelee! I can get this to mostly work right now, but I'm left wanting a whole lot more from the tooling.

---

<div class="post-metadata">

**Author:** ![FranzBusch](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/franzbusch/32/19447_2.png) [@FranzBusch](https://forums.swift.org/u/FranzBusch)\
**Post date:** [March 10, 2025, 1:25pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/10 "2025-03-10T13:25:35Z")

</div>

Thanks for the great feedback @davedelong and trying out the new feature! Really appreciate you putting in the time to explore it and write up your experience here.  
I think all of those are valid points and some of them I expected to pop up. Our goal was to land a solid foundation that we can expand on and improve the developer experience over time.

Could you help us and file issues for the missing features and for Xcode file a feedback request asking for better integration?

---

<div class="post-metadata">

**Author:** ![davedelong](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/davedelong/32/38708_2.png) [@davedelong](https://forums.swift.org/u/davedelong)\
**Post date:** [March 12, 2025, 2:16pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/11 "2025-03-12T14:16:40Z")

</div>

It would've been the work of a couple minutes to add it based on my feedback here, but here we are two days later:

SPM: [Traits apply to packages instead of products](https://github.com/swiftlang/swift-package-manager/issues/8350)  
SourceKit-LSP: [No way to discover a trait's compilation condition](https://github.com/swiftlang/sourcekit-lsp/issues/2059)  
#FB16837991: Xcode is missing all SPM Traits integration

---

<div class="post-metadata">

**Author:** ![stephencelis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stephencelis/32/2675_2.png) [@stephencelis](https://forums.swift.org/u/stephencelis)\
**Post date:** [July 22, 2025, 6:55pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/12 "2025-07-22T18:55:08Z")

</div>

I've been trying to find support for this in the Xcode 26 betas but as of beta 4 I still can't find anything. Is support still pending? Can we hope to see this resolved before release? This is a really great feature and it's a shame that packages can't really use traits right now without the major caveat that package users can't manage such a dependency in Xcode.

---

<div class="post-metadata">

**Author:** ![pierremb](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/pierremb/32/2020_2.png) [@pierremb](https://forums.swift.org/u/pierremb)\
**Post date:** [July 24, 2025, 12:33pm UTC](https://forums.swift.org/t/cross-import-overlay-status/74090/13 "2025-07-24T12:33:05Z")

</div>

I didn’t find anything either.
