How to Build and Publish Swift Packages: Turn Your Code into Reusable Libraries (2025 Edition)
Transform your copy-paste code into professional Swift libraries. Complete guide to package creation, testing, versioning, and publishing…

🎯 Introduction
Every iOS developer has been there. You’re deep into a new project and suddenly think, “Wait, didn’t I already write this date formatter like three projects ago?”
So what do you do? You open up some dusty old repo, scroll through folders, copy the code, paste it in, maybe tweak it a little… Fast-forward six months, and now you’ve got five slightly different versions of the same extension scattered across your codebase. 🤦♂️
Here’s the thing: You’re not just copying code — you’re accidentally building libraries. You just haven’t packaged them yet.
That string extension you’ve duplicated four times? That’s a library waiting to happen. Those reusable UI components? Swift package material. Even that network manager you’ve perfected over time? Could be helping hundreds of other devs.
📚 This Complete Swift Package Series
This is Part 1 of a 3-part series that’ll turn your scattered snippets into powerful, professional Swift libraries:
- 📦 Part 1 (You’re here!) — Build your first Swift package and get it running
- 🧱 Part 2 — Structure it like a pro, write tests, and prep it for publishing
- 🌍 Part 3 — Master dependency management and grow a community around your code
By the end of this series, you won’t just write better Swift — you’ll build libraries that scale across teams, projects, and maybe even your career 🚀
🎯 What We’re Transforming Today
Today’s goal: go from copy-paste developer to package creator. We’re taking that tried-and-true utility code you always reuse — and turning it into your first working Swift package.
We’ll cover:
- ✨ Why Swift packages are a game-changer for your workflow
- 🛠 Step-by-step: how to build your first package from scratch
- 🧪 How to test and integrate it in real-world projects
- 💡 That “holy grail” moment when everything clicks and you never go back
Ready to stop copying and start creating? Let’s turn your code into a package. 📦
💡 Why Create Swift Packages?
Before we dive into the how, let’s talk about the why. Creating Swift packages is hands-down one of the smartest moves you can make as an iOS developer. Once you experience the benefits, you’ll wonder how you ever lived without them.
🙋♂️ Personal Benefits: Your Development Life Gets Easier
🔍 No More Code Archaeology
Remember spending 20 minutes digging through old projects just to find that one perfect function? With Swift packages, your best code lives in one clean, organized place. Need your custom date formatter? import Utilities — done.
📦 Consistency Across Projects
Your networking layer shouldn’t look different in every app. With packages, you write it once, perfect it once, and reuse it everywhere. Fix one bug, and all your projects benefit.
⚡ Faster Project Setup
Starting a new iOS project? Skip the copy-paste chaos. Just drop in your Swift packages as dependencies and go. No broken imports. No repeated setup. Just speed.
👔 Professional Benefits: Level Up Your Career
📂 A GitHub Profile That Actually Impresses
Well-documented, reusable code in package form shows you think like an engineer — not just a coder. It says, “I build systems,” not “I patch features.”
🧠 Proof of Problem-Solving Skills
Each package is a public receipt of your ability to identify recurring problems and solve them elegantly — the exact thing senior engineers and tech leads do.
🌱 Open Source Potential
Even if you start private, many packages eventually grow into open-source tools that help the community — and build your reputation in the process.
👥 Team Benefits: Better Collaboration
🔄 Shared Standards
When your team shares the same packages, you share a consistent architecture. New devs ramp up faster. Patterns are predictable. Everyone speaks the same code language.
🧼 Collective Code Quality
Packages naturally attract more collaboration, reviews, and polish. It’s like having your team continuously refactor and refine your utilities without even trying.
🧯 Reduced Technical Debt
Instead of duplicating variations of the same utility in every repo, you get one clean, tested, well-documented version maintained together.
🧠 The Mindset Shift
This is the real power of Swift packages: You stop writing code just for “this project” and start writing tools for your future self, your team, and your entire ecosystem.
Every package you build is a time-saving investment. Stop rewriting that network layer. Stop duplicating that button style. Package it once, and you’re set — forever.
Ready to make the shift? Let’s look at why Swift Package Manager is the perfect tool to help you get there. 🧰
⚔️ Swift Package Manager vs Alternatives
Now that you’re convinced packages are the way to go, you might be wondering: “Why Swift Package Manager? What about CocoaPods or Carthage?”
Great question! While all three can manage dependencies, SPM has become the clear winner for package creation in 2025. Here’s why:
SPM: Apple’s Official Solution
Native Xcode Integration 🍎 SPM is built right into Xcode. No separate installations, no workspace files, no build phases to configure. When you create a Swift package, Xcode understands it natively. When you want to add it to a project, it’s literally just File → Add Package Dependencies.
Zero Configuration Overhead With CocoaPods, you need Podfiles, workspace files, and sometimes complex build configurations. With SPM? You get a clean Package.swift file that’s actually readable. No Ruby gems to install, no version conflicts to resolve.
Future-Proof Choice Apple is clearly investing in SPM as the long-term solution. New features, better performance, and tighter integration keep coming with each Xcode release. Meanwhile, CocoaPods development has slowed, and Carthage is basically in maintenance mode.
The Reality Check
Here’s the honest truth about dependency management in 2025:
CocoaPods is still widely used, especially in large existing projects, but it’s becoming the “legacy” choice. Great for consuming packages, but creating new ones? SPM is simpler.
Carthage had its moment, but it’s been largely abandoned. Even if you encounter it in existing projects, you probably won’t choose it for new work.
SPM is where the ecosystem is heading. New packages are increasingly SPM-first, and Apple continues to improve tooling around it.
Why This Matters to You
When you create Swift packages, you want them to be as accessible as possible. SPM packages work everywhere without additional setup:
- ✅ iOS apps can add them instantly
- ✅ macOS, watchOS, and tvOS projects work seamlessly
- ✅ Other package creators can easily depend on your packages
- ✅ No compatibility matrix to worry about
Plus, when you’re building packages for your own use, SPM’s simplicity means you spend time writing code, not configuring build systems.
The Bottom Line
You could create packages using other tools, but why make it harder than it needs to be? SPM gives you the cleanest development experience and the widest compatibility.
_Want a deeper dive into the pros and cons of each approach? I’ve written a detailed comparison of_ **_CocoaPods vs Carthage vs Swift Package Manager (SPM) in 2025_** _that covers real-world scenarios and migration strategies._
**CocoaPods vs Carthage vs Swift Package Manager (SPM) in 2025: Which One Should iOS Devs Use?** _Everything iOS developers need to know about CocoaPods, Carthage, and Swift Package Manager in 2025 — features, pros…_medium.comhttps://medium.com/swift-pal/cocoapods-vs-carthage-vs-swift-package-manager-spm-in-2025-which-one-should-ios-devs-use-82b30253d200
Now that we’ve settled on SPM, let’s get our hands dirty and create your first Swift package!
🛠️ Your First Swift Package (Hands-On)
Alright, enough theory! Time to get our hands dirty and create your first Swift package. We’re going to start with something you probably already have — some utility code that you’ve written before.
Step 1: Identify Your Hidden Library
Before we create anything new, let’s find the perfect candidate in your existing projects. Open up one of your recent iOS projects and look for:
Perfect Package Candidates:
- Extensions on String, Date, or UIColor that you always need
- Custom UI components you’ve built multiple times
- Networking helpers or API response models
- Utility functions for formatting, validation, or calculations
- Custom property wrappers or view modifiers (if you’re using SwiftUI)
Found something? Great! For this tutorial, I’ll use a common example: a collection of useful String extensions. But follow along with whatever code you’ve identified.
Step 2: Create Your Package
In Xcode:
- File → New → Package (yes, it’s that simple!)
- Select Multiplatform from the package templates dialog.
- Select the Library template.
- Choose a name like “MyUtilities” or something specific like “StringExtensions”
- Pick a location (I recommend a dedicated “Packages” folder in your development directory)
- Hit Create
What You Get: Xcode creates a clean package structure with everything you need:
Package.swift- The configuration fileSources/[PackageName]/- Where your code livesTests/[PackageName]Tests/- Where your tests go.gitignoreandREADME.md- Ready for version control
Step 3: Understanding Package.swift
Open the Package.swift file. This is your package's blueprint, and it's surprisingly readable:
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyUtilities",
platforms: [
.iOS(.v17)
.macOS(.v10_15)
],
products: [
.library(
name: "MyUtilities",
targets: ["MyUtilities"]),
],
dependencies: [
// External dependencies go here
],
targets: [
.target(
name: "MyUtilities",
dependencies: []),
.testTarget(
name: "MyUtilitiesTests",
dependencies: ["MyUtilities"]),
]
)Key Points:
platformsdefines minimum OS versionsproductsis what other projects can importdependencieslists external packages you needtargetsdefines your actual code modules
Step 4: Add Your Code
Now for the fun part! Replace the generated code in Sources/MyUtilities/MyUtilities.swift with your actual utility code:
import Foundation
public extension String {
/// Removes whitespace and newlines from both ends
var trimmed: String {
return self.trimmingCharacters(in: .whitespacesAndNewlines)
}
/// Checks if string is a valid email format
var isValidEmail: Bool {
let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}"
let emailPred = NSPredicate(format:"SELF MATCHES %@", emailRegEx)
return emailPred.evaluate(with: self)
}
/// Capitalizes first letter of each word
var titleCased: String {
return self.capitalized
}
}
public extension Date {
/// Returns a user-friendly relative time string
var timeAgo: String {
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .full
return formatter.localizedString(for: self, relativeTo: Date())
}
}Important: Notice the public keywords! Without them, your code won't be accessible to projects that import your package.
Step 5: Test It Locally
The easiest way to test your package is to create a test right in the package:
import XCTest
@testable import MyUtilities
final class MyUtilitiesTests: XCTestCase {
func testStringTrimming() {
let messyString = " Hello World \n"
XCTAssertEqual(messyString.trimmed, "Hello World")
}
func testEmailValidation() {
XCTAssertTrue("test@example.com".isValidEmail)
XCTAssertFalse("invalid-email".isValidEmail)
}
func testTitleCase() {
XCTAssertEqual("hello world".titleCased, "Hello World")
}
}Run the tests with Cmd+U — they should pass! 🎉
Step 6: Use It in a Real Project
Now for the moment of truth. Open one of your iOS projects and:
- File → Add Package Dependencies
- Click “Add Local” and navigate to your package folder
- Add the package to your target (main target)
- Build your Xcode project (if it fails, restart Xcode)
Then in your code:
import MyUtilities
// In some view controller or SwiftUI view
let email = userInput.trimmed
if !email.isValidEmail {
showError("Please enter a valid email")
}It works! You’ve just created and used your first Swift package. No more copy-pasting that email validation logic — it’s now a reusable, testable library.
The Magic Moment
Take a second to appreciate what just happened. That code you wrote once is now available across any project with a single import. When you improve the email validation logic, every project that uses your package gets the improvement automatically.
You’ve officially graduated from copy-paste developer to package creator! 🎓
Next up, let’s talk about organizing your package properly and following best practices that’ll make your future self thank you.
🎯 What You’ve Accomplished
Congratulations! You’ve just created your first Swift package and experienced that magical moment when your scattered utility code becomes a professional, reusable library. You’ve officially graduated from copy-paste developer to package creator! 🎓
In this first part of our series, you’ve learned to:
- ✅ Identify the hidden libraries already living in your projects
- ✅ Create a Swift package from scratch using Xcode
- ✅ Structure your code with proper public APIs
- ✅ Test your package locally and integrate it into real projects
- ✅ Understand why SPM is the future of iOS dependency management
But we’re just getting started! Creating a basic package is one thing — making it professional, maintainable, and community-ready is where the real value lies.
🚀 What’s Next?
Your package works, but is it professional? In the next article, we’ll transform your basic package into something you’d be proud to show in a job interview:
“**Swift Package Best Practices: Structure, Testing & Publishing (2025 Edition)**”
We’ll cover:
- 📁 Package Architecture: Organizing code that scales as your package grows
- 🧪 Testing Strategies: Unit tests, performance tests, and catching edge cases that’ll save you from embarrassing bugs
- 🏷️ Professional Publishing: Semantic versioning, release management, and making your packages discoverable
- 📚 Documentation: Writing docs that actually help (and make your package look incredibly professional)
**Swift Package Best Practices: Structure, Testing & Publishing (2025 Edition)** _Level up your Swift packages with professional structure, comprehensive testing, and proper versioning. Complete guide…_medium.comhttps://medium.com/swift-pal/swift-package-best-practices-structure-testing-publishing-2025-edition-d6d1ef7fce93
📖 Part 3 Preview: Beyond Personal Use
Ready to take your packages to the next level? Part 3 will cover the advanced stuff that separates hobby projects from production-ready libraries:
- Dependency management strategies that prevent version conflicts
- Common gotchas that can break your users’ projects (and how to avoid them)
- Building an open source community around your packages
- Turning your Swift package expertise into career opportunities
🎉 Enjoyed this article? Your support means the world to me!
💬 Drop a comment below! I love hearing about your experiences and answering questions
🎬 Subscribe on Youtube and become early subscribers of my channel: https://www.youtube.com/@swift-pal
💼 Let’s connect on LinkedIn for more professional insights: https://www.linkedin.com/in/karan-pal
Happy coding! 🚀
New articles, straight to your inbox.
No spam, no filler — just new writing on iOS, the web, and AI when it ships. Unsubscribe anytime.
Keep reading
Why I'm Rebuilding My Blog From Scratch (and Leaving Medium)
After years of publishing on someone else's platform, I'm moving my writing to a home I actually own. Here's the reasoning, and what I'm building instead.
ReadData Is the Model: The Most Ignored Part of AI
A beginner-friendly guide to why data quality beats model hype.
Read