Since 2015
Powerful image loading system
Load images in SwiftUI, UIKit, and AppKit. Nuke handles memory and disk caching, processing, progressive decoding, animated images, and prefetching.
Nuke 14 is in beta, with animated images, diagnostics, and speedups of up to 5×. Read the release notes and the migration guide.
Testimonials
-
It's well maintained, uses the latest Swift features… I've been using it for several years now and haven't been disappointed.
-
It's always nice to see a mature, stable, well-loved open-source project get an update, and that's what Nuke from Alexander Grebenyuk is.
-
All in all, Nuke is a great library. Its advanced features and constant updates make it an easy choice for many projects.
-
When I first met Nuke, I was ready for spending much too much time on some mundane image download stuff… 15mn later I was already done ❤️
-
I switched from Kingfisher to @a_grebenyuk's Nuke. It's so much more efficient right out of the box.
-
I'm using Nuke in 99% of places. Couldn't deal with AsyncImage random bugs anymore.
Simple to start, powerful when you need it
Display an image with one line of code, then customize every step of the pipeline under it, yourself or with an AI agent.
https://github.com/kean/Nuke
struct ContentView: View {
let url: URL
var body: some View {
LazyImage(url: url) { state in
if let image = state.image {
image.resizable().scaledToFill()
} else {
Color.gray.opacity(0.2)
}
}
.processors([.resize(width: 320)])
.priority(.high)
}
}// Loads an image into a UIImageView or
// NSImageView, cancelling the previous load into
// the same view, which is perfect for cell reuse
ImageLoader.load(
url,
into: imageView,
presentation: .init(
placeholder: UIImage(named: "placeholder"),
transition: .fadeIn(duration: 0.33)
)
)func loadImage() async throws {
let pipeline = ImagePipeline.shared
let task = pipeline.imageTask(with: url)
for await progress in task.progress {
print("Loaded \(progress.fraction * 100)%")
}
imageView.image = try await task.image
}Everything an app needs from images
Ten years of real-world use went into the details, so the defaults are fast and the hard cases are handled.
Smooth Scrolling
Nuke does as little as possible on the main thread. Decoding, decompression, and processing run in the background, and the prefetcher loads what's next at a low priority, so scrolling stays smooth.
- Prefetching with
ImagePrefetcherand the collection view prefetching APIs - Downloads limited to a few at a time, with some always left free for what's on screen
- Requests rate limited when someone scrolls really fast
Prefetching in the demo app, with its pipeline diagnostics
Animated Images
LazyImage and LazyImageView play GIF, APNG, animated WebP, and HEIC and AVIF sequences with no setup.
- Parsed once and cached with the image, so a cell that scrolls back plays right away
- Views share decoders and one frame pool with a fixed memory budget
- Frames are decoded no larger than the view displays them
- Playback modeled on WebKit, down to 30 Hz in Low Power Mode
A GIF in the demo app, with its playback diagnostics
Processors
Nuke applies the processors of a request in order, in the background, and caches the result, so the work is done once.
ImageRequest(url: url, processors: [
])
Select a processor in the code to turn it on or off
Diagnostics
Turn on isDiagnosticsEnabled, and every task records where the image came from and where its time went, down to the DNS lookup and the TLS handshake. Print the record for a timeline, or follow the pipeline in Instruments with signposts.
ImageTask #2 "feed" · success · 140.9 ms · from networkurl: https://cdn.example.com/photos/1024.jpgimage: 1350×900 · jpeg · 4.9 MB in memorytransfer: 317 KB j4 loadImage [resize] 139.5 ms99%├─ memoryLookup <0.1 ms├─ diskLookup 0.3 ms├─ j5 loadImage 96.3 ms68%│ └─ j6 fetchOriginalImage 96.0 ms68%│ ├─ j7 fetchOriginalData 95.2 ms68%│ │ ├─ download 93.6 ms66%│ │ │ └─ networkLoad 93.1 ms66%│ │ │ ├─ domainLookup 1.0 ms1%│ │ │ ├─ connect 10.0 ms7%│ │ │ ├─ secureConnection 21.0 ms15%│ │ │ ├─ waiting 16.1 ms11%│ │ │ └─ response 43.3 ms31%│ │ └─ diskStore <0.1 ms│ └─ decode 0.3 ms├─ process 42.6 ms30%└─ memoryStore 0.1 mstotal 140.9 ms
-
Caching
A fast LRU memory cache, an aggressive LRU disk cache, and the HTTP disk cache.
-
Image Formats
JPEG, PNG, HEIC, WebP, AVIF, and everything else Image I/O reads, plus custom decoders.
-
Progressive Decoding
Show progressive JPEGs scan by scan as they download, so people see the image right away.
-
Thumbnails
Decode and downsample a large image in one step, without ever decoding it at full size.
-
Coalescing & Priority
Requests for the same image share one download, and a change of priority moves it in line.
-
Resumable Downloads
A download that fails or gets cancelled picks up where it left off, using HTTP range requests.
-
Swift 6
Async/await APIs and
Sendabletypes, checked by the compiler in the strict concurrency mode. -
Extensible
Bring your own data loader, caches, decoders, or processors, or use the Alamofire plugin.
-
Video
Play short videos in place of GIFs with NukeVideo, from a poster frame to a looping player.
Support Nuke
Nuke is free and open source, and I've been working on it since 2015. Sponsorship pays for the time it takes to keep it up to date and fix bugs.
Sponsor
Thanks to
Proxyman for sponsoring Nuke