SkeletonView: placeholder skeletons for UIKit apps, and what it does not cover
☠️ An elegant way to show users that something is happening and also prepare them to which contents they are awaiting
At a glance
- What is it?
- SkeletonView is a Swift library that turns UIKit views into animated placeholder skeletons while data loads. It is aimed at UIKit and storyboard-based iOS work, and it leaves SwiftUI out of scope.
- Who is it for?
- Adopt SkeletonView if you have a UIKit or storyboard-driven iOS app with table and collection views that need placeholder states, and you are willing to mark views skeletonable by hand. Do not adopt it if your screens are SwiftUI-first, or if you expect the library to infer your layout without per-view configuration.
- 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 98 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.
Editorial analysis
The waiting problem SkeletonView was built for
Almost every app has async work: API requests, long running processes. The README opens with exactly that observation and says developers usually place a loading view to show users that something is going on. SkeletonView was conceived to address that need, described in the README as an elegant way to show users that something is happening and also prepare them for which contents are waiting.
The distinction matters. A spinner tells the user to wait. A skeleton tells the user what shape the answer will take: an avatar circle, two lines of text, a thumbnail. SkeletonView is for the second job. It is a UIKit library in Swift, distributed through CocoaPods, Carthage and Swift Package Manager, and the README lists all UIViews as skeletonables. That last phrase is the design centre of the project: the unit of work is a view, not a screen or a route.
The audience is therefore narrow and specific. If your app is built from UIViewController subclasses, storyboards, UITableView and UICollectionView, this fits the grain of the code you already have. If your UI is declared in SwiftUI, the README gives you nothing.
How the skeleton mechanism works
The flow has three steps, and the README states them plainly. First you import SkeletonView. Then you set which views will be skeletonable, either in code with a boolean property or through Interface Builder, which the README shows with a storyboard screenshot. Then you call one of four show methods on a view.
The four methods are the whole visual vocabulary: showSkeleton for a solid fill, showGradientSkeleton for a gradient, showAnimatedSkeleton for solid with animation, and showAnimatedGradientSkeleton for gradient with animation. There is no fifth option documented in the README and no configuration object behind them in the usage section.
One behaviour is easy to miss and the README flags it as important: SkeletonView is recursive. If you want the skeleton in all skeletonable views, you only need to call the show method on the main container view, for example with UIViewControllers. So the marking step is per-view, but the showing step is per-container. That split is the part of the design worth understanding before you wire it into a screen, because it means the skeletonable flags scattered across a view hierarchy are what actually determine the result, not the call site.
For lists, the library does not reuse your existing data source directly. The README shows a SkeletonTableViewDataSource protocol that inherits from UITableViewDataSource and adds methods such as collectionSkeletonView(_:numberOfRowsInSection:) and collectionSkeletonView(_:cellIdentifierForRowAt:), plus a skeletonCellForRowAt method that defaults to nil and a prepareCellForSkeleton hook. You are describing the placeholder list separately from the real list.
Installing SkeletonView and showing a first skeleton
The README gives three package managers. For CocoaPods, add the pod to your Podfile:
pod 'SkeletonView'For Carthage, the README shows a single line for your Cartfile:
github "Juanpe/SkeletonView"For Swift Package Manager, the README gives this dependency entry, pinned from version 1.7.0:
dependencies: [
.package(url: "https://github.com/Juanpe/SkeletonView.git", from: "1.7.0")
]There is a caveat the README marks as important: since version 1.30.0, SkeletonView supports XCFrameworks, and if you want to install it as an XCFramework you should use the separate SkeletonView-XCFramework repository instead. That is a second repository to track, not a flag on this one.
Once installed, the first real use is three steps. Import the module:
import SkeletonViewMark the views you want covered. In code that is one property per view, or you set it through Interface Builder:
avatarImageView.isSkeletonable = trueThen show it. Because the library is recursive, calling the show method on the container is enough to cover every skeletonable view underneath it:
view.showAnimatedGradientSkeleton()What you should see is the marked views replaced by an animated gradient placeholder. If a view stays visible instead, the usual cause is that its isSkeletonable flag was never set, since the recursion only reaches views that opted in.
Where SkeletonView stops being the right tool
The README does not document a SwiftUI path. For an app whose screens are SwiftUI views, this library offers no entry point in the usage section, and the four show methods are methods on UIKit views. That is the clearest boundary in the project.
The second limitation is the manual marking. Every view that should be part of the skeleton needs isSkeletonable set, in code or in the storyboard. On a large hierarchy that is a lot of small edits, and the failure mode is quiet: a missed view simply renders its real content behind the skeleton, which looks like a layout bug rather than a missing flag. The recursion makes the show call cheap, but it does not make the marking automatic.
The third is lists. Adopting SkeletonTableViewDataSource means conforming to a protocol that inherits from UITableViewDataSource and implementing placeholder-specific methods. Your existing data source does not become a skeleton source for free. The README shows the protocol but does not document how the two sources stay in sync as rows change, so treat that as something to verify in the source before you rely on it.
Finally, the README does not document rollback or how to hide a skeleton once data arrives. The show methods are documented; the counterpart is not covered in the README.
SkeletonView against a plain loading indicator
The obvious alternative is UIActivityIndicatorView, or a custom spinner view placed in the same spot. The difference is not cosmetic. A spinner is a single view with no relationship to the content it replaces, so you add it once and it works everywhere. SkeletonView requires you to describe the shape of the incoming content, view by view, and in exchange the waiting state carries information about what is coming.
That trade is the whole decision. A spinner costs one view and no per-screen work. SkeletonView costs per-view marking plus, for lists, a second data source protocol, and it buys a placeholder that matches the real layout. On a settings screen with three rows, the spinner wins on effort. On a feed where the user will see an avatar, a name and two lines of body text, the skeleton communicates the structure before the request returns, which is the outcome the README is aiming at.
There is no comparison in the README to any other Swift skeleton library, so the honest framing is against the built-in indicator, not against a named competitor.
Maintenance, licence and the cost of upgrading
The repository is not archived. The last push was on 2026-06-23, which is within the last six months of the date used here, so the project is not dormant. The release history is uneven, though: 1.31.0 shipped on 2024-04-18, and the release before it, 1.30.4, was on 2022-10-20. That is a gap of roughly eighteen months between tagged releases, so pinning to a version and reading the CHANGELOG before moving is a reasonable habit. The repository keeps a CHANGELOG.md at the top level, alongside a Package.swift, a podspec and an Xcode workspace, which means three distribution paths to keep consistent when you upgrade.
The licence is MIT, stated in the README's licence section and present as a LICENSE file at the repository root. MIT is permissive: it allows use in closed source apps. This is a description of the licence identifier, not legal advice; check the LICENSE file yourself if the terms matter to your organisation.
Upgrade cost is mostly tied to the XCFramework note. Since 1.30.0 the XCFramework route lives in a separate repository, so a team that depends on that packaging has two version streams to reconcile rather than one.
Editorial conclusion
Adopt SkeletonView if you have a UIKit or storyboard-driven iOS app with table and collection views that need placeholder states, and you are willing to mark views skeletonable by hand. Do not adopt it if your screens are SwiftUI-first, or if you expect the library to infer your layout without per-view configuration. Before committing, check the SkeletonTableViewDataSource protocol signatures against your existing data source, and confirm which of the four show methods matches the visual treatment you want.
Frequently asked questions
What is skeleton UI?
It is a placeholder treatment shown while content loads, shaped like the content that is coming. SkeletonView implements it for UIKit by replacing marked views with a solid or gradient placeholder.
What is the skeleton code?
In SkeletonView the skeleton code is the three-step setup the README describes: import SkeletonView, set isSkeletonable on the views you want covered, then call one of the four show methods on a container view.
What are skeleton screens?
They are loading placeholders that mimic the layout of the content being fetched. The README describes SkeletonView as an elegant way to show users that something is happening and also prepare them for which contents are waiting.
What are the differences between loading spinners and skeleton screens?
A spinner only signals that work is in progress and has no relationship to the content it replaces. A skeleton mirrors the shape of the incoming content, which is the outcome SkeletonView targets, at the cost of marking each view skeletonable.
What is skeleton view?
SkeletonView is a Swift library for UIKit, distributed through CocoaPods, Carthage and Swift Package Manager, that shows solid, gradient, animated or animated gradient placeholders on views marked as skeletonable.
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/juanpe-skeletonview)