Kingfisher is a library for loading and caching images on iOS, macOS, and watchOS, written in pure Swift. According to the official repository, the library provides full support for Swift Concurrency, Combine, and SwiftUI, as well as automatic two-level caching. Kingfisher is known for its type-safe API and easy integration with Swift projects.
Key Takeaways
Kingfisher is a library for asynchronous image loading and caching on Apple platforms, written entirely in Swift. The library author is Wei Wang (onevcat). Kingfisher provides a set of tools for loading images from the network with automatic caching, transformations, and support for modern Swift technologies: async/await, Combine, Sendable.
The library has over 23,000 stars on GitHub and is used in applications such as Telegram, Snapchat, and Dropbox. Kingfisher supports GIF, APNG, HEIF, and all standard image formats. Each request returns a type-safe Result
The architecture of Kingfisher is built on three main components: Manager (download manager), Cache (two-level cache), and Processor (transformations). These components are connected through protocols, allowing any part to be replaced without changing dependencies.
KingfisherManager is the central class that coordinates image loading, caching, and processing. It holds references to ImageCache and ImageDownloader and provides a single method retrieveImage that returns a ready-to-use image after going through all stages.
When calling retrieveImage, the Manager first checks Memory Cache — an NSCache with UIImage, where the key is formed from the source URL and CacheSerializer. If the image is found, it is returned immediately. On a miss, it checks Disk Cache — reading from the file system with decryption via serializer. If the disk cache is empty, a network request is made through ImageDownloader, the result is decoded, transformed, and saved to both cache levels.
Starting from version 7.0, Kingfisher fully supports async/await. The retrieveImage method is available as an asynchronous function, returning Result directly without completion handlers. This allows using the library in modern Swift architectures with Structured Concurrency.
Kingfisher is divided into several modules, each solving its own task. This separation simplifies testing and component replacement.
KingfisherManager is a facade that combines loading, cache, and processors. By default, the singleton KingfisherManager.shared is used, but a separate instance with custom settings can be created for isolated scenarios (e.g., for unit tests).
ImageCache is a two-level cache with separate settings for memory and disk. Memory Cache has no limit on the number of objects but is cleared by the system when memory is low. Disk Cache stores files in a directory with configurable TTL (default 7 days), size limit (default 0 — no limit), and automatic cleanup.
ImageProcessor is a protocol with a single method process(item:options:) that returns the processed image. Built-in implementations: ResizingImageProcessor (resizing), RoundCornerImageProcessor (rounding), BlurImageProcessor (Gaussian blur), OverlayImageProcessor (color overlay). Processors can be combined using the |> operator.
The Kingfisher cache architecture is based on the write-through principle: data is written to both levels simultaneously, and reading starts from the fastest level — memory. The cache key is the absolute image URL after removing query parameters.
| Parameter | Memory Cache | Disk Cache |
|---|---|---|
| Storage | NSCache (RAM) | File system (SSD) |
| Format | UIImage (decoded) | Data (compressed, via serializer) |
| Cleanup | UIApplication.didReceiveMemoryWarningNotification | TTL + exceeding limit |
| Serialization | Not required | CacheSerializer (default PNG/JPEG) |
| Thread safety | Yes (synchronized access) | Yes (IO queue + barriers) |
To manage Disk Cache size, the total file size is calculated with sorting by last access date. When the limit is exceeded, files with the oldest access date are removed until the size falls below 50% of the limit. TTL cleanup occurs during cache initialization and on each call to cleanExpired.
Kingfisher provides several interfaces for loading images: an extension on UIImageView, a separate manager, and a SwiftUI View.
kf is a namespace property on UIImageView, providing setImage, cancelDownload methods, and loading indicators. The setImage method accepts URLSource and optional parameters Options and completionHandler.
import Kingfisher
imageView.kf.setImage(
with: URL(string: "https://example.com/image.jpg"),
placeholder: UIImage(named: "placeholder"),
options: [
.processor(RoundCornerImageProcessor(radius: .point(12))),
.transition(.fade(0.3)),
.cacheMemoryOnly
],
progressBlock: { receivedSize, totalSize in
print("Loaded \(receivedSize) / \(totalSize)")
}
)
The method returns a DownloadTask that supports cancellation via cancel and progress tracking. Internally, setImage calls KingfisherManager.shared.retrieveImage with automatic ImageView detection as Target.
Starting from Kingfisher 7.0, the setImage method is available in an async version. This allows integrating image loading into Swift Structured Concurrency without callbacks.
func loadAvatar() async {
do {
let result = try await imageView.kf.setImage(
with: url,
options: [.processor(ResizingImageProcessor(
targetSize: CGSize(width: 100, height: 100)
))]
)
// result.image contains UIImage
} catch {
print("Failed: \(error)")
}
}
KFImage is a SwiftUI View, similar to AsyncImage from iOS 15, but with full Kingfisher caching support. The View automatically uses KingfisherManager.shared but supports a custom manager through the .configure modifier.
struct AvatarView: View {
let url: URL
var body: some View {
KFImage(url)
.placeholder { ProgressView() }
.resizable()
.fade(duration: 0.25)
.forceTransition()
.frame(width: 80, height: 80)
.cornerRadius(40)
}
}
Kingfisher provides a built-in indicator system for displaying image loading progress. IndicatorType is an enum with three options: .activity (UIActivityIndicatorView), .progress (UIProgressView), and .custom (custom implementation of the Indicator protocol). The indicator automatically appears above the ImageView during loading and is hidden after completion.
For a custom indicator, you need to implement the Indicator protocol with startAnimatingView() and stopAnimatingView() methods. This allows for hybrid solutions: a skeleton with shimmer animation, a placeholder image with gradual reveal, or a logo with opacity animation. Kingfisher also supports setting the indicator globally via KingfisherManager.shared.defaultOptions.
On the iOS platform, Kingfisher and SDWebImage are the two dominant image loading libraries. The choice between them depends on the project language, performance requirements, and ecosystem.
| Criteria | Kingfisher | SDWebImage |
|---|---|---|
| Language | Swift (100%) | Objective-C + Swift |
| Async/Await | Native support | Via wrapper |
| Combine | Built-in Publisher | No |
| Sendable | Supports | Limited |
| Type safety | Full (Result type) | Via Any? |
| ImageProcessor | Composite via |> | Transformer via && |
| Size | ~900 KB | ~1.2 MB |
| GitHub Stars | 23,000+ | 25,000+ |
The key advantage of Kingfisher is its Swift-first architecture: full support for async/await, Combine Publishers, Sendable, and Result types. SDWebImage maintains leadership due to its broader plugin ecosystem (WebP, SVG, MapKit) and Objective-C support.
Kingfisher is installed via Swift Package Manager, CocoaPods, or Carthage. After installation, simply import the module and call any loading method — the library is ready to use without additional configuration.
// Swift Package Manager (Package.swift)
dependencies: [
.package(
url: "https://github.com/onevcat/Kingfisher.git",
from: "7.12.0"
)
]
// CocoaPods (Podfile)
pod 'Kingfisher', '~> 7.12'
For customizing global settings, use KingfisherManager.shared. You can change the downloader timeout, cache strategy, and default processors. Below is an example of configuring a 500 MB cache with a 14-day TTL.
let cache = ImageCache(name: "custom")
cache.memoryStorage.config.totalCostLimit = 100 * 1024 * 1024
cache.diskStorage.config.sizeLimit = 500 * 1024 * 1024
cache.diskStorage.config.expiration = .days(14)
KingfisherManager.shared.cache = cache
ImageDownloader is also configured through the manager: you can set a custom URLSessionConfiguration with timeouts, headers, and caching policies. For progress monitoring, the KFIndicator module is available with support for ActivityIndicator, ProgressView, and custom indicators.
Frequently Asked Questions
Kingfisher is a library for loading images on iOS, written in pure Swift. It is used for asynchronous loading, caching, and transforming images from the network with full integration into SwiftUI, UIKit, and modern Swift technologies.
Add the package https://github.com/onevcat/Kingfisher.git with version from 7.12.0 in Xcode via File → Add Packages. Or specify the dependency in Package.swift with the parameter from: "7.12.0". After installation, import the Kingfisher module.
Kingfisher supports JPEG, PNG, GIF, APNG, HEIF, and WebP. All formats are decoded through system frameworks (ImageIO, CoreGraphics). GIF is supported via CGImageSource with progressive loading and animation.
Kingfisher is written in pure Swift and fully supports async/await, Combine, and Sendable. It provides a type-safe Result API and a modular architecture through protocols, simplifying component replacement and testing.
To clear Memory Cache, call KingfisherManager.shared.cache.clearMemoryCache(). For Disk Cache, use clearDiskCache(). To remove only expired files — cleanExpiredDiskCache(). Cache size can be checked via cache.calculateDiskStorageSize().
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also