Open-source project
TextureGroup/Texture avatar
TextureGroup/Texture

Texture for iOS: moving layout, text sizing and image decoding off the main thread

Smooth asynchronous user interfaces for iOS apps.

8,178 stars1,310 forksObjective-C++NOASSERTION

At a glance

What is it?
Texture (formerly AsyncDisplayKit) gives iOS and tvOS apps a thread-safe node layer over UIView. The pitch is simple: keep the 16 ms frame budget free by doing expensive UI work in parallel.
Who is it for?
Adopt Texture if you have a UIKit codebase with scrolling feeds, image grids or text-heavy lists that drop frames, and you are willing to learn the node model rather than mix it into view code. Do not adopt it for a small static app or a project already committed to SwiftUI, because the framework exists to fix main-thread contention and adds a parallel hierarchy to maintain.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly Objective-C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The frame budget problem Texture was built to solve

UIKit expects layout and drawing to happen on the main thread. On a 60 Hz display the main thread has about 16 milliseconds per frame, and the README notes that system overhead usually leaves under ten milliseconds of usable work before a frame is dropped. Image decoding, text sizing and layout all compete for that window. When a list scrolls, they lose.

Texture's answer is to stop treating views as the only unit of composition. Its basic unit is the node, and an ASDisplayNode is described in the README as an abstraction over UIView, which is itself an abstraction over CALayer. The difference that matters is thread safety. Views can only be used on the main thread; nodes can be instantiated and configured in parallel on background threads. That single property is what allows an entire hierarchy to be built off the main thread.

The audience is narrow and specific. This is for iOS and tvOS developers maintaining UIKit interfaces, typically feeds, grids, chat threads or anything with heavy text and images. A small settings screen gains nothing. A social app with mixed media cells is the case the framework was designed around, and the examples directory reflects that with sample projects such as ASDKgram, CatDealsCollectionView, SocialAppLayout and PagerNode.

How nodes, thread safety and preloading fit together

The mechanism is a parallel object graph. You create ASDisplayNode instances on a background thread, configure their properties there, and let Texture attach them to real views later on the main thread. Because the node holds the layout and content description, the main thread's job shrinks to committing already-computed state.

The README states that Texture moves image decoding, text sizing and rendering, layout, and other expensive UI operations off the main thread. Those are the four categories that most often break the frame budget, and each maps to a different node type in the framework rather than to a single generic wrapper.

Preloading is the second half of the design. The README names cell reuse bugs and preloading data for a page or scroll interface as problems the framework addresses. Preloading means the expensive work for cells that are about to appear can start before they appear, so the scroll stays ahead of the user instead of reacting to them. That is a different strategy from simply caching rendered output, because the layout and sizing work itself is done early rather than reused.

The trade-off is real. You now maintain two hierarchies: nodes and views. Debugging a layout issue means deciding whether the problem is in the node's computed layout or in how it was attached, and the view debugger shows you only half the picture.

Installing Texture with CocoaPods or Carthage

The README says Texture is available via CocoaPods or Carthage and points to the Installation guide at texturegroup.org/docs/installation.html for instructions. The repository also carries a Texture.podspec, a Cartfile, a Podfile and a Cartfile.resolved, so both dependency managers are represented in the tree. The README does not reproduce the exact version string or a full Podfile snippet, so treat the guide as the source of truth rather than copying a version from a blog post.

A CocoaPods setup follows the usual shape. Add the pod to your target's Podfile and run the install command:

bash
pod install

After that, open the generated workspace rather than the original project file. The repository ships AsyncDisplayKit.xcworkspace, which is a sign of how the maintainers work with the codebase themselves.

For Carthage, the Cartfile is the entry point, and the framework is listed as Carthage compatible in the README badges:

bash
carthage update

Once the dependency resolves, the first real use is a node replacing a view. The README does not print a code sample, so the honest starting point is the Getting Started guide and the sample projects under examples/. Pick a small screen in your app, replace one UIView subclass with an ASDisplayNode subclass, and confirm the layout still matches before converting a second screen. Converting a whole app in one pass is how teams end up unable to tell whether a regression came from the framework or from their own migration.

Where Texture is the wrong tool

Texture assumes you are building on UIKit. If your app is written in SwiftUI, the framework's premise does not apply: there is no main-thread view hierarchy for you to take work out of in the same way, and adding a node layer underneath a declarative system creates two mental models for one screen. The README's language badges list ObjC and Swift, not SwiftUI.

The second boundary is scope. The framework adds boilerplate-eliminating structures, but those structures have to be learned. For a handful of screens with light content, the cost of adopting a node model exceeds any frame-time saved, because there was no frame-time problem to begin with.

There is also a maintenance dimension worth checking rather than assuming. The most recent release listed is 3.2.0 from 2024-05-21, following 3.1.0 in 2021 and 3.0.0 in 2020. The repository itself was pushed on 2026-09-18, so work continues between releases. A reader should read that as a slow, deliberate release cadence rather than a fast-moving one, and should check the CHANGELOG.md and RELEASE.md before planning an upgrade across a major version.

Finally, the licence file is present in the repository, and the README describes the project as available under Apache 2.0. The repository metadata reports the licence as NOASSERTION, which means automated tooling could not classify it. Anyone embedding the framework in a shipped product should read LICENSE directly rather than relying on a badge or a package manager's summary. That is not legal advice, just a description of where the authoritative text sits.

Texture compared with plain UIKit and with IGListKit

The most direct alternative is doing nothing: plain UIKit with careful cell reuse and manual caching. The difference in approach is where the work happens. Plain UIKit keeps layout and sizing on the main thread and tries to make each operation cheap enough to fit. Texture keeps the operations expensive but moves them to background threads, then commits the result. If your bottleneck is a single slow operation you can cache, plain UIKit plus a cache is simpler. If your bottleneck is the aggregate cost of many cells, the threading model is the point.

A second comparison is IGListKit, which is commonly paired with Texture in iOS feed code. IGListKit addresses diffing and data-driven updates for collection views: it computes what changed between two data sets. Texture addresses where layout and rendering execute. They solve adjacent problems, and neither replaces the other. Choosing IGListKit alone leaves the frame budget question unanswered; choosing Texture alone leaves you writing your own diffing.

The examples in the repository show the intended shape of a real app rather than a toy. ASDKgram, SocialAppLayout and CatDealsCollectionView are all feed-style layouts, and PagerNode covers paged navigation. That is a fair signal of the problems the maintainers expect you to bring.

Upgrade cost and what to verify before you commit

Upgrade cost is governed by the release cadence. Three major versions are listed across six years, with 3.2.0 in 2024 as the latest. That spacing means major-version migrations are infrequent but substantial when they arrive, and the repository carries a ThreeMigrationGuide.md specifically for the 3.0 transition. If you are on 2.x, that document is the starting point, not the changelog.

There is a second migration path worth knowing about: the README opens by asking whether you are coming from AsyncDisplayKit and links to a Medium post introducing Texture as the new home for it. The project renamed rather than forked, and the Xcode project in the tree is still named AsyncDisplayKit.xcodeproj. Expect that naming split in build settings, scheme names and search results.

For licence, the README states Apache 2.0 and the LICENSE file is at the repository root. Because the repository metadata reports NOASSERTION, verify the file contents yourself if your organisation requires a classified dependency. Also check Texture.podspec for the declared licence field, since that is what your package manager will surface.

What to verify first is concrete: confirm the pod or Carthage version you intend to pin, read ThreeMigrationGuide.md if you are crossing 3.0, and open one of the examples that matches your layout shape before writing any migration code.

Editorial conclusion

Adopt Texture if you have a UIKit codebase with scrolling feeds, image grids or text-heavy lists that drop frames, and you are willing to learn the node model rather than mix it into view code. Do not adopt it for a small static app or a project already committed to SwiftUI, because the framework exists to fix main-thread contention and adds a parallel hierarchy to maintain. Before committing, check the installation guide at texturegroup.org, confirm the current release tag against the CHANGELOG, and read ThreeMigrationGuide.md if you are coming from AsyncDisplayKit.

Frequently asked questions

What is Texture (AsyncDisplayKit)?

Texture is a framework for building asynchronous user interfaces on iOS and tvOS, formerly known as AsyncDisplayKit. Its basic unit is the node, and an ASDisplayNode is an abstraction over UIView that can be created and configured on background threads.

How do I install Texture in an iOS project?

The README states that Texture is available via CocoaPods or Carthage and points to the Installation guide at texturegroup.org/docs/installation.html. The repository includes a Texture.podspec, a Cartfile and a Cartfile.resolved, so both managers are supported.

Does Texture work with Swift?

The README lists ObjC and Swift in its language badges, and the examples directory contains Swift sample projects such as CustomCollectionView-Swift and LayoutSpecExamples-Swift. The framework itself is written primarily in Objective-C++.

What licence does Texture use?

The README describes the project as available for free use under Apache 2.0, as described by the LICENSE file in the repository. The repository metadata reports the licence as NOASSERTION, so read the LICENSE file itself if you need a classified dependency.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. TextureGroup/Texture on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/texturegroup-texture.svg)](https://hysenlabs.com/projects/texturegroup-texture)