QuickLayout is a declarative layout library for iOS, designed to work seamlessly with UIKit. It is lightning-fast, incredibly simple to use, and offers a powerful set of modern layout primitives.
QuickLayout's API will feel natural to many iOS engineers. With a small and well tested codebase, it is production ready. QuickLayout has significant usage across many of Instagram's core features.
import QuickLayout
@QuickLayout
class MyCellView: UIView {
let titleLabel = UILabel()
let subtitleLabel = UILabel()
var body: Layout {
HStack {
VStack(alignment: leading) {
titleLabel
Spacer(4)
subtitleLabel
}
Spacer()
}
.padding(.horizontal, 16)
.padding(.vertical, 8)
}
}Above is a fully functional view. Subviews are managed automatically, layout is performed at the correct time, and sizeThatFits returns an accurate value.
- ⭐️ Lightning-Fast: Custom layout engine for blazing fast performance—no Auto Layout or Flexbox overhead.
- 🧩 Modern Layout Primitives: Includes
HStack,VStack,ZStack,Grid, andFlowas lightweight, pure Swift structs that don’t add extra views. - 🚀 Easy Integration: Simple @QuickLayout macro for fast setup and automatic subview management.
- 🧵 Thread-Safe: With some caveats, our API can be used concurrently and off the main thread.
QuickLayout achieves lightning-fast performance by using a custom-built layout engine that completely avoids Auto Layout and Flexbox, eliminating the overhead of constraint solving and the risk of constraint errors. Instead, QuickLayout provides a declarative API with lightweight layout primitives implemented as pure Swift structs that do not add extra views to the view hierarchy. This results in lower memory usage and faster layout calculations.
In benchmarks, QuickLayout is up to 3× faster and 4× more memory efficient than UIStackViews built with Auto Layout. By eliminating constraint solving and extra container views, QuickLayout delivers consistently high performance and a smaller memory footprint, making it ideal for demanding app surfaces.
For a comprehensive overview of all features, usage examples, and best practices, check out the QuickLayout Handbook.
QuickLayout is a declarative layout library built to be used with regular UIViews. It can coexist with manual layout methods, allowing for gradual adoption.
At the heart of QuickLayout are Stacks:
- VStack layouts child elements vertically,
- HStack positions child elements horizontally.
For example, to make the following layout (image below), you can use VStack with leading alignment and spacing of four points:
let label1 = UILabel(text: "Kylee Lessie")
let label2 = UILabel(text: "Developer")
var body: Layout {
VStack(alignment: .leading, spacing: 4) {
label1
label2
}
}You can nest Stacks as many times as you wish. For instance, you can add an icon to the left of two labels by using HStack:
let avatarView = UIImage(image: avatarIcon)
let label1 = UILabel(text: "Kylee Lessie")
let label2 = UILabel(text: "Developer")
var body: Layout {
HStack(spacing: 8) {
avatarView
VStack(alignment: .leading, spacing: 4) {
label1
label2
}
}
}The alignment property in stacks does not position the stack within its parent; instead, it controls the alignment of the child elements inside the stack.
The alignment property of a VStack only applies to the horizontal alignment of the contained views. Similarly, the alignment property for an HStack only controls the vertical alignment.
A flexible Spacer is an adaptive element that expands as much as possible. For example, when placed within an HStack, a spacer expands horizontally as much as the stack allows, moving sibling views out of the way within the stack’s size limits.
var body: Layout {
HStack {
view1
Spacer()
}
}var body: Layout {
HStack {
view1
Spacer()
view2
}
}var body: Layout {
HStack {
Spacer()
view1
}
}A fixed space between views can be specified with a Spacer as in the snippet below:
var body: Layout {
HStack {
view1
Spacer(8)
view2
Spacer(8)
view3
}
}You can achieve the same fixed spacing between views using the Stack's spacing parameter:
var body: Layout {
HStack(spacing: 8) {
view1
view2
view3
}
}A padding can be added to any view or layout element:
var body: Layout {
HStack(spacing: 8) {
view1
view2
view3
}
.padding(.horizontal, 16)
}The frame does not directly change the size of the target view, but it acts like a "picture frame" by suggesting the child its size and positioning it inside its bounds. For example, if the UIImageView in the following layout has an icon that is 10x10 points in size, the icon will be surrounded by 45 points of empty space on each side. However, if the icon has a size of 90x90 points, it will be surrounded only by 5 points of empty space on each side.
var body: Layout {
imageView
.frame(width: 100, height: 100)
}To make UIImageView acquire the size of the frame, it needs to be wrapped into resizable modifier:
var body: Layout {
imageView
.resizable()
.frame(width: 100, height: 100)
}For full documentation, visit the QuickLayout Handbook.
Use Swift Package Manager. Link and import QuickLayout target.
- Constantine Fry — Concept, architecture, layout and API design
- Jordan Smith — @QuickLayout macro and API design, body API and automatic subview management
- Fabio Milano — Demo showcase, BUCK support
- Jordan Smith & Fabio Milano — Instagram adoption
- Andrey Mishanin & Constantine Fry — Stack Layout
- Constantine Fry & Saadh Zahid — Flow and Grid Layout
- Jordan Smith — Custom alignment and alignment guides
- Thong Nguyen — Fast Result Builder
To Scott James Remnant of netsplit.com and Javier of SwiftUI Labs for their research and articles on SwiftUI.
To Chris Eidhof, Daniel Eggert, and Florian Kugler of objc.io for their continued work on exploring SwiftUI layout.
To Luc Dion for his work on LayoutFrameworkBenchmark.
To the early adopters - Sash Zats, Cory Wilhite, Chaoshuai Lyu, Steven Liu, Erik Kunz, Min Kim, and many others - for their feedback and early adoption efforts.
QuickLayout is MIT-licensed, as found in the LICENSE file.
Copyright © Meta Platforms, Inc • Terms of Use • Privacy Policy






