Skip to content

Combine Swift Imports with a Wrapper Module

Create a single import that re-exports all your commonly used frameworks using @_exported import.

The Repetitive Import Problem

In any Swift project of moderate size, you end up with the same set of imports at the top of nearly every file. Foundation, SwiftUI, OSLog, maybe Observation – the list grows as you adopt new frameworks. With the move to structured logging via OSLog, I found myself adding import OSLog to almost every file alongside the usual suspects.

The solution is a wrapper module that re-exports everything you commonly need through a single import.

Setting Up the Wrapper Module

Create a new target in your Swift package or Xcode project. In my case, I called it AppFoundation. The entire module consists of a single file:

// Sources/AppFoundation/Exports.swift
@_exported import Foundation
@_exported import SwiftUI
@_exported import OSLog
@_exported import Observation

The @_exported attribute makes all public symbols from each framework available to any file that imports AppFoundation. Now, every file in your app just needs:

import AppFoundation

In your Package.swift, the target has no source code of its own beyond the exports file. Your app target declares a dependency on AppFoundation, and all the re-exported frameworks become available everywhere.

Trade-Offs to Consider

This approach has clear benefits: less boilerplate, fewer merge conflicts in import sections, and a single place to add new framework imports. But there are trade-offs.

First, @_exported is an underscored attribute, meaning it is not officially part of the stable Swift API. In practice, it has been stable for years and is used widely in the ecosystem, but it carries no formal guarantee.

Second, implicit dependencies can make it harder to understand what a file actually uses. When every file has access to everything, you lose the documentation value of explicit imports. If you later extract a module into a standalone package, you will need to add the explicit imports back.

For app targets where convenience matters more than strict modularity, the wrapper module pattern saves real time. For reusable libraries, explicit imports remain the better choice.

Found this helpful? Follow me on Bluesky and Mastodon for more Swift tips and indie dev updates.