Kingfisher: Swift image downloading and caching for UIKit and SwiftUI
A lightweight, pure-Swift library for downloading and caching images from the web.
At a glance
- What is it?
- Kingfisher is a pure-Swift library that downloads remote images, caches them in memory and on disk, and applies processors before display. It fits iOS, macOS, tvOS, watchOS and visionOS apps that show remote images at scale.
- Who is it for?
- Adopt Kingfisher if you ship a UIKit or SwiftUI app that loads remote images and you want downloading, a memory-plus-disk cache, and image processors behind one API. Skip it if your images are bundled assets, if you only need a single one-off fetch, or if you cannot move to Swift 5.9 or the minimum OS versions listed for version 8.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly Swift, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Kingfisher solves in a Swift app
Fetching a remote image in an app looks like one line of code and turns into five concerns: the network request, decoding, a memory cache so scrolling does not refetch, a disk cache so a cold launch does not refetch, and cancellation when a cell is reused. Kingfisher packages all of that. The README describes it as a "pure-Swift library for downloading and caching images from the web", and the feature list covers asynchronous downloading and caching, a multiple-layer hybrid cache for memory and disk, cancelable downloading, prefetching, and SwiftUI support.
The audience is narrow and specific: developers building apps with UIKit or AppKit, or SwiftUI, who display images that come from URLs rather than from the bundle. The README lists extensions for UIImageView, NSImageView, NSButton, UIButton, NSTextAttachment, WKInterfaceImage, TVMonogramView and CPListItem, which maps onto iOS, macOS, watchOS, tvOS and CarPlay surfaces. If your images ship inside the app bundle, none of this applies.
How the downloader, cache and processors fit together
The README describes independent components: a downloader, a caching system, and image processors, each usable separately. The default path is that Kingfisher downloads from a URL, sends the result to both the memory cache and the disk cache, and displays it in the view. Set the same URL again and the image comes from the cache instead of the network.
Processors are composable with the pipe operator, which is the part worth understanding before you design a screen. In the advanced example, DownsamplingImageProcessor and RoundCornerImageProcessor are chained so the downloaded high-resolution image is downsampled to the image view's size and then rounded, and the .cacheOriginalImage option keeps the original large file on disk for a later detail view. That split matters: what you display can be a transformed, smaller image while what you cache stays the full-resolution source.
Cache behavior is configurable, with expiration dates and size limits mentioned in the feature list. The README also notes that KingfisherManager has an opt-in async cache probing mode, which the project describes as a way to avoid blocking the caller thread on disk cache checks. That is an opt-in, not the default, so a team that cares about main-thread disk work should look at it deliberately.
Installing Kingfisher and setting a first image
The README points to two tutorials on the Swift Package Index, one for UIKit and one for SwiftUI, and says you can follow either of those or the methods below. The Swift Package Manager route is described as adding the dependency through Xcode and entering the repository URL. The README also lists CocoaPods and a podspec exists in the repository root as Kingfisher.podspec, so the pod route is present in the project even though the README excerpt shown here does not spell out the Podfile line.
The simplest use case from the README sets an image on an image view with the kf extension:
import Kingfisher
let url = URL(string: "https://example.com/image.png")
imageView.kf.setImage(with: url)After that call, the image is downloaded, written to both caches, and shown in the view. Run the same line again with the same URL and the image is served from the cache. In SwiftUI the equivalent is a view:
var body: some View {
KFImage(URL(string: "https://example.com/image.png")!)
}The README notes that the KF builder and KFImage share the same chain, so a chain written for UIKit can be moved to SwiftUI by changing KF to KFImage. That is the migration path the project itself offers.
Version 8 requirements and what they rule out
Version 8 raises the floor. The README lists iOS 13.0+, macOS 10.15+, tvOS 13.0+, watchOS 6.0+ and visionOS 1.0+ for UIKit and AppKit, and iOS 14.0+, macOS 11.0+, tvOS 14.0+, watchOS 7.0+ and visionOS 1.0+ for SwiftUI, with Swift 5.9+ required. Version 7 is documented separately with lower floors: iOS 12.0+, macOS 10.14+, tvOS 12.0+, watchOS 5.0+, and Swift 5.0+.
That split is the first thing to check before adopting. An app with an iOS 12 deployment target cannot take version 8 and would need to stay on the 7.x line, which means it also misses whatever landed in 8.x. The README does not describe a backport policy for fixes to 7.x, so a team pinned to 7.x is on a branch whose support terms are not stated in the README.
The second constraint is architectural. Kingfisher is Swift and built for Apple platforms. There is no Android, Flutter or React Native binding in the README, and no server-side story. If your images are rendered by a cross-platform framework, this library is not the piece that solves your problem.
Where the cache design creates work for you
The hybrid cache is the reason to pick Kingfisher, and it is also where the sharp edges are. The README mentions customizable expiration dates and size limits but does not state defaults for either, nor does it document an eviction policy by name. Two images at the same URL are the same cache key, so if your server serves different bytes behind one URL, for example a user avatar that changes while the URL stays fixed, the cache will keep serving the old image until it expires. The README does not document a rollback or invalidation recipe beyond the expiration and size controls, so a team that needs per-image invalidation has to design it.
The .cacheOriginalImage option is a good illustration of the trade-off. It keeps the full-resolution download on disk so a detail view does not refetch, which is exactly what the advanced example wants. It also means disk usage tracks the size of the originals, not the size of the downsampled thumbnails you actually render. The size limit is the lever there, and the README leaves the value to you.
Finally, the README states that async cache probing in KingfisherManager is opt-in. Anyone who assumes disk cache checks are already off the caller thread has assumed wrong.
Kingfisher against SDWebImage and Nuke
The closest alternative most iOS teams weigh is SDWebImage, and the difference is the language boundary. SDWebImage is an Objective-C library with a Swift interface; Kingfisher is written in Swift, and the README leans on that repeatedly, describing processors, caches and downloaders as Swift components you can use on their own. For a codebase that is already all Swift and uses Swift Concurrency, Kingfisher's stated Swift 6 and strict concurrency preparation is a concrete difference, not a slogan.
Nuke is the other one worth naming, and the split is in the API shape. Kingfisher offers two styles for the same work: the kf extension, shown as imageView.kf.setImage(with: url), and a KF builder with chained calls. The README shows the same operation written both ways, and notes the chain can be reused in SwiftUI by swapping KF for KFImage. A team that wants one canonical call site will find the dual API a choice to make and enforce in review.
Neither comparison is settled by feature checklists here. The README does not publish benchmarks against either library, and nothing in the README supports a performance claim in either direction.
Maintenance, releases and the MIT licence
The repository is not archived and the last push was on 2026-09-15, so the project is being worked on. Releases are frequent and named: 8.12.0 ("Let It Go") on 2026-08-25, 8.11.0 ("Steady Flight") on 2026-07-20, and 8.10.0 ("Bean Counter") on 2026-06-12. A CHANGELOG.md sits in the repository root, which is where upgrade notes would live.
That release cadence is the upgrade cost. Three minor releases in roughly three months means a team on a pinned version will periodically decide whether to move. The README does not describe a long-term support policy, so a team that needs to stay on an older minor line has no stated commitment to rely on.
The licence is MIT, per the README badge and the LICENSE file in the repository root. MIT is permissive: it allows use in closed-source apps, and it requires that the copyright notice and permission notice be included. Whether that obligation is satisfied by your build tooling is a question for your own legal review; the repository does not answer it for you.
Editorial conclusion
Adopt Kingfisher if you ship a UIKit or SwiftUI app that loads remote images and you want downloading, a memory-plus-disk cache, and image processors behind one API. Skip it if your images are bundled assets, if you only need a single one-off fetch, or if you cannot move to Swift 5.9 or the minimum OS versions listed for version 8. Before writing code, check the version 8 requirements against your deployment targets and read the UIKit or SwiftUI tutorial linked from the README, since that is where the project points new users.
Frequently asked questions
How do I install Kingfisher in a Swift project?
The README lists Swift Package Manager and CocoaPods, and points to a UIKit tutorial and a SwiftUI tutorial on the Swift Package Index. With Swift Package Manager you add https://github.com/onevcat/Kingfisher.git as a package dependency.
How do I use Kingfisher in Swift?
Import Kingfisher and call the kf extension on an image view, for example imageView.kf.setImage(with: url). Kingfisher downloads the image, writes it to the memory and disk caches, and displays it, and a later call with the same URL is served from the cache.
How do I use Kingfisher in SwiftUI?
The README shows a KFImage view built from a URL, and notes that the KF builder chain can be reused in SwiftUI by changing KF to KFImage. SwiftUI support requires iOS 14.0+, macOS 11.0+, tvOS 14.0+, watchOS 7.0+ or visionOS 1.0+ in version 8.
What is Kingfisher?
Kingfisher is a pure-Swift library for downloading and caching images from the web, with a hybrid memory and disk cache, image processors and filters, prefetching, and extensions for UIKit, AppKit, SwiftUI and other Apple UI classes.
How do I use Kingfisher?
The README shows two styles for the same operation: the kf extension on a view, and the KF builder with chained calls such as .placeholder, .setProcessor, .fade and .onSuccess. The same chain works in SwiftUI when you change KF to KFImage.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/onevcat-kingfisher)
Community notes