Simplified imports with @_exported attribute

Swift has a few lesser-known features that are genuinely useful in large codebases. One of them is @_exported, which lets a module re-export another module’s public API.

The usual import flow

In normal Swift code, each source file imports what it needs:

import Foundation

That is fine for small codebases, but in larger projects you often repeat the same imports across many files and targets.

What @_exported does

With @_exported, a module can expose another module transitively:

@_exported import Foundation

If another module imports yours, it can access Foundation symbols without importing Foundation directly.

Common multi-module use case

Imagine this setup:

// ModuleB.swift
@_exported import ModuleC
// ModuleA.swift
import ModuleB

ModuleA can now use public declarations from ModuleC through ModuleB.

When this helps

  • Shared internal platform modules
  • Wrapper modules that intentionally expose a curated API
  • Reducing repetitive imports in deeply modular projects

What to avoid

  • Do not use @_exported as a default in public SDKs where long-term API stability matters.
  • Do not use it to hide unclear architecture; if module boundaries are fuzzy, re-exporting can make dependencies harder to reason about.
  • Do not assume it removes normal imports inside your own module’s source files; imports are still file-scoped.

Caveat: underscored attribute

@_exported is not part of Swift’s stable public language surface. It appears in Swift’s Underscored Attributes and is marked as strongly discouraged outside the standard library.

That means:

  • behavior can change in future Swift versions
  • tooling support is less predictable
  • you should treat it as a pragmatic shortcut, not a long-term contract
  • for standard import visibility control, prefer official access-level imports (public import, internal import, etc.) described in SE-0409

Practical rule of thumb

Use @_exported only in modules that are intentionally acting as a dependency facade, and document that decision in the module README so consumers know the behavior is deliberate.

Final thought

@_exported can simplify dependency surfaces in modular Swift projects, but use it with intent and document why you chose it.