When to use built-in, 3rd party or a custom implementation for Async Image Loading in SwiftUI

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
Search for a command to run...

I am a Software Engineer working on open source and enterprise mobile SDKs for iOS and MacOS developers written in Swift. From 🇩🇪 and happily living in 🇺🇸
No comments yet. Be the first to comment.
WWDC26 kicked off on June 8, 2026. The information in this article reflects the information published by Apple on that date. There are 14 new frameworks. Name Description AccessoryAccess Manage

WWDC25 kicked off on June 9, 2025. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AlarmKitSchedule prominent alarms and countdowns to help people manage their time. AVR...

WWDC25 is almost here, and I couldn’t be more excited! Whether you're attending the official events, community meetups, or just soaking in the energy around Cupertino, there’s no better time to connect, share ideas, and celebrate everything we love a...

In this blog post, I’ll share an observation and advice regarding the caching behavior of network responses by Apple’s APIs. If you are unfamiliar with caching of network responses then I recommend Apple’s article Accessing cached data that introduce...
WWDC24 kicked off on June 10, 2024. The information in this article reflects the information published by Apple on that date. New Frameworks NameDescription AccessorySetupKitUse AccessorySetupKit to discover accessories with Bluetooth or Wi-Fi...

In this blog post I reflect on the various options to have async image loading in SwiftUI:
AsyncImageSDWebImageSwiftUI) I'll share my personal experiences and recommendations on when to use what.
SwiftUI on iOS 15 has AsyncImage that allows us to load images from the network.
AsyncImage(url: URL(string: "https://example.com/icon.png")) { image in
image.resizable()
} placeholder: {
ProgressView()
}
.frame(width: 50, height: 50)
The obvious drawback is that iOS 15+ is required. Other things to consider are:
URLSession)URL (rather than also accepting a URLRequest)These three popular open-source projects do offer SwiftUI views and underlying image loading capabilities:
All three projects are published under the MIT license.



In one of my projects I started with url-image but I switched to SDWebImageSwiftUI because I needed support for animated images.
Here are some stats (as of Feb 3rd 2022) to compare:
| SDWebImageSwiftUI | url-image | NukeUI | |
| GitHub Stars | ~ 1.3k | ~ 930 | ~360 |
| Last Release | March 2021 (2.0.2) | May 2021 (3.0.0) | January 2022 (0.8.0) |
| Supports Animated Images | Yes | No | Yes |
| iOS support | v13 | v12 | v12 |
| macOS support | v10_15 | v10_13 | v10_14 |
| watchOS support | v6 | v4 | v5 |
| tvOS support | v13 | v12 | v12 |
| Distribution | SPM, CocoaPods, Carthage | SPM | SPM, CocoaPods |
Do you wan to go with a custom implementation? Read Using Swift’s async/await to build an image loader from Donny Walls to learn how to do that. It features the use of modern Swift concurrency (async/await)
Here's what the SwiftUI view's implementation could look like:
struct RemoteImage: View {
private let source: URLRequest
@State private var image: UIImage?
@Environment(\.imageLoader) private var imageLoader
init(source: URL) {
self.init(source: URLRequest(url: source))
}
init(source: URLRequest) {
self.source = source
}
var body: some View {
Group {
if let image = image {
Image(uiImage: image)
} else {
Rectangle()
.background(Color.red)
}
}
.task {
await loadImage(at: source)
}
}
func loadImage(at source: URLRequest) async {
do {
image = try await imageLoader.fetch(source)
} catch {
print(error)
}
}
}
If your app or framework supports iOS 15+ and you don't need advanced caching capabilities or animated images, go ahead with AsyncImage from SwiftUI.
Otherwise look at one of the open-source projects mentioned in this blog post.
If you have very particular requirements and you want/need to avoid external dependencies, you might want to try to build your own image loader. Personally I would try to avoid this as much as possible.