Add a Local Swift Package to an Xcode App Target Without a Git Remote
Learn how to link a local Swift package into an Xcode app target using filesystem references, validate the build, and recover from common path and resolution errors.
19 May 2026, 10:53 UTC

The Problem: Sharing Code Without a Remote Host
When you extract shared logic into a Swift package, the default Xcode workflow assumes a remote Git repository. That assumption adds friction for internal libraries, prototype modules, or code shared across a few projects on the same machine. A local Swift package lets you draw a clear module boundary and reuse code through Swift Package Manager (SPM) without publishing anything or managing remote authentication.
What You Need First
- An Xcode project with at least one app target. Xcode 11 and later support adding local package dependencies.
- A local directory containing a valid
Package.swiftmanifest and aSourcesfolder. - A Swift tools-version declared in the manifest that your selected Xcode toolchain supports.
Local packages are stored as filesystem references, not copies. Xcode records the path to the folder; it does not vendor the source into your project file.
Step 1: Confirm the Package Manifest and Product Name
Before linking, open the package folder and inspect Package.swift. The product name is what you import in Swift code, and it may differ from the package name.
// swift-tools-version:5.7
import PackageDescription
let package = Package(
name: "NetworkingKit",
products: [
.library(name: "NetworkingKit", targets: ["NetworkingKit"]),
],
targets: [
.target(name: "NetworkingKit"),
]
)
In this example, both the package and product are named NetworkingKit. If the product were named something else, your import statement would need to match the product name, not the package name.
Step 2: Add the Local Package to the Project
- In Xcode, choose File > Add Package Dependencies….
- In the sheet that appears, click Add Local… instead of entering a repository URL.
- Navigate to the folder that contains
Package.swiftand select it. - Xcode resolves the manifest and presents the available products. Add the product you need.
After this step, the package appears in the project navigator under the Package Dependencies section. Xcode stores the location as a path reference.
Step 3: Link the Product to the App Target
Adding the package to the project does not automatically link it to every target.
- Select the project file in the navigator, then select your app target.
- Open the General tab and find Frameworks, Libraries, and Embedded Content.
- Click the + button and choose the package product from the list.
- For a standard Swift package, leave the embed setting as Do Not Embed unless the package bundles resources that require signing.
If you skip this step, the package may resolve in the navigator but your app target will still fail to compile any file that imports it.
Step 4: Import the Module
In any Swift file inside the app target, add the import statement matching the product name:
import NetworkingKit
// Use the shared code here
Validate the Integration
Run these checks after linking:
| Check | Expected Result |
|---|---|
Build the app target (Cmd+B) | No No such module errors for the package |
| Project navigator | Package listed under Package Dependencies with a valid path |
| Unit tests that import the package | Tests compile and execute |
Recovery Options
Broken Path After Moving the Folder
Because local packages are path references, moving or renaming the folder breaks resolution. Remove the package from the project's package dependencies and re-add it using Add Local… with the new path.
Stale Build Artifacts
If the package contents change but Xcode reports old errors, delete Derived Data:
- Xcode UI: Open Settings > Locations > Derived Data, click the arrow, then delete the folder for your project.
- Terminal: Run
rm -rf ~/Library/Developer/Xcode/DerivedDatato clear all projects. This removes cached build artifacts for every project, so use it when the UI path is impractical.
Import Does Not Match Product
If you see No such module 'X' but the package appears linked, compare the products array in Package.swift against your import statement. The import must match the library product name exactly.
Remote and Local Identity Conflicts
If a remote package with the same identity already exists in the project, Xcode may resolve to one source depending on project configuration. Keep local package names distinct from remote dependencies to avoid ambiguity.
Rollback: Removing the Local Reference
If you need to undo the integration, select the project, open the Package Dependencies section in the project editor, select the local package, and click the – button. Then remove the product from the app target's Frameworks, Libraries, and Embedded Content list. This removes the reference but does not delete the package folder from disk.
Limitations to Keep in Mind
- Path fragility: The reference is tied to a filesystem location. Sharing the project with another machine requires the package to exist at the same path, or the reference must be recreated.
- Tools-version ceiling: The
swift-tools-versionin the manifest must not exceed what your selected Xcode toolchain supports. If it does, Xcode will refuse to resolve the package. - No automatic updates: Unlike remote packages, Xcode will not fetch updates. You edit the local source directly, and the app target picks up changes on the next build.
A Practical Way to Confirm Success
After building, open the Report Navigator (Cmd+9) and select the most recent build log. Expand the compile steps for a file that imports the package. If the module resolves, you will see the package's source files participating in the dependency graph without module-not-found diagnostics. If tests exist, run the test plan and confirm the tests that import the package execute rather than fail at compile time.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.