“Module dependency cycle: UIKit.swiftmodule → … → UIKit.swiftmodule” means Xcode’s explicit-module dependency scan found a loop. UIKit itself is rarely the component to change. Follow the full path and remove the reciprocal import involving your framework, bridging header, module map, or public headers.
What the error means
Module dependency cycle:
UIKit.swiftmodule
→ MyFramework.swiftmodule
→ SomeClangModule.pcm
→ UIKit.swiftmodule
Xcode 26 enables Swift explicit modules by default for Swift targets. The compiler scans and builds module dependencies separately, exposing cycles that older implicit imports or incidental build ordering may have hidden.
Common conditions
- Framework A imports Framework B while B imports A.
- A bridging header imports its own generated
ProductModuleName-Swift.h. - An umbrella or public header imports unnecessary UIKit or internal frameworks.
- A custom
module.modulemapincludes private headers or another module’s umbrella header. - A public C or Objective-C header exposes an implementation-only dependency.
- The issue appears after moving to Xcode 26 and explicit dependency scanning.
Recommended fix
1. Read the complete cycle
Expand the full “Module dependency cycle” entry in the Issue navigator or build log. Do not stop at UIKit. Find the project framework, Clang module, or PCM immediately before the path returns to a module already listed.
UIKit at both ends does not establish that UIKit is defective. The project header or module map that introduces UIKit back into the chain is usually the actionable edge.
2. Make target dependencies one-directional
If the graph contains A→B→A, move shared protocols and value types into a smaller third module.
Before: FeatureA → FeatureB → FeatureA
After: FeatureA → SharedInterfaces ← FeatureB
Also inspect Target Dependencies, Link Binary With Libraries, and Swift Package target dependencies for an unnecessary reverse edge.
3. Inspect the bridging header
Do not import the target’s generated -Swift.h from its bridging header. To call Swift from Objective-C, import the generated header from the relevant Objective-C implementation file. Keep only Objective-C declarations required by Swift in the bridging header.
// MyProject-Bridging-Header.h
// Wrong: #import "MyProject-Swift.h"
#import "LegacyAPI.h"
4. Minimize public headers and module maps
- Remove unnecessary imports from public headers and use forward declarations where possible.
- Move implementation-only headers from Public to Project or Private.
- Avoid importing another framework’s umbrella header from your umbrella header.
- Review
umbrella,header, andexclude headerentries in custom module maps.
@class SomeViewController;
@protocol SomeService;
5. Rebuild from a clean dependency graph
- Choose Product > Clean Build Folder.
- Resolve Swift package versions again.
- Remove Derived Data and perform a clean build.
- Build with the same Xcode release on CI.
Temporary workaround
The Xcode 26 release notes allow projects with severe migration issues to temporarily opt out of Swift explicit modules:
SWIFT_ENABLE_EXPLICIT_MODULES = NO
This is a migration workaround, not a repair for the circular graph. Limit it to affected targets and correct the headers and module structure so explicit modules can be enabled again.
How to verify the fix
- A clean build no longer reports the dependency cycle.
- The project builds with explicit modules enabled.
- Simulator, device, and Archive builds all succeed.
- A clean CI environment or another Mac reproduces the successful build.
Important notes
Renaming modules or adding broad search paths can hide one edge while allowing headers to be compiled under multiple module identities. Preserve the full cycle path and remove the first project-controlled import that closes the loop.
As of September 16, 2026, Apple has not announced one Xcode fix covering every UIKit.swiftmodule cycle. Projects need to correct their specific dependency graph under Xcode 26’s explicit-module model.
Summary
The error reports a circular module graph, not a broken UIKit framework. Trace the cycle through your modules, remove bidirectional target dependencies, and clean up bridging headers, public headers, and module maps. Treat disabling explicit modules as a short-term migration aid only.
