HorizonCalendar: Airbnb's Declarative iOS Calendar Component
A declarative, performant, iOS calendar UI component that supports use cases ranging from simple date pickers all the way up to fully-featured calendar apps.
At a glance
- What is it?
- HorizonCalendar is an open-source iOS calendar UI component from Airbnb that supports both UIKit and SwiftUI, handles virtually infinite date ranges, and drives every calendar and date picker in the Airbnb iOS app. Its declarative API models calendar content as a value type rather than mutating UI state through delegates.
- Who is it for?
- HorizonCalendar is the right choice for iOS apps that need a date picker or calendar view beyond what UIKit provides out of the box, particularly when the design calls for custom day views, range selection, overlays, or non-Gregorian calendar systems. It is less appropriate if your deployment target is locked to a version below iOS 11, or if your team is already invested in FSCalendar and the migration cost outweighs the benefits of the declarative model.
- Can I use it commercially?
- Yes. Apache-2.0 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 27 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 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What HorizonCalendar Does and Who It Is For
HorizonCalendar solves the problem of building a calendar or date picker in an iOS app where the default UIKit and SwiftUI date controls fall short. The README states it is used to implement every calendar and date picker in the Airbnb iOS app, covering use cases from a simple single-day picker to a full availability calendar. It targets iOS developers who need custom day renderings, range selection with visual indicators, overlays such as tooltips, or support for non-Gregorian calendar systems.
The component is not a scheduling backend or a calendar server. It renders calendar UI and reports taps; all business logic for what the selected dates mean stays in the host application. The deployment target is iOS 11 and above, with Swift 5 and Xcode 10.2 required.
Declarative Content Model and How CalendarViewContent Works
The central design decision in HorizonCalendar is that all visual aspects of the calendar are controlled through a single value type called CalendarViewContent in UIKit, or through initializer parameters and modifiers on CalendarViewRepresentable in SwiftUI. The README describes this as a declarative API that encourages unidirectional data flow for updating calendar content.
In UIKit, to create a basic CalendarView you initialize it with an initial CalendarViewContent:
let calendarView = CalendarView(initialContent: makeContent())In SwiftUI, you initialize a CalendarViewRepresentable with a calendar, a visible date range, a months layout, and a dataDependency parameter:
CalendarViewRepresentable(
calendar: calendar,
visibleDateRange: startDate...endDate,
monthsLayout: .vertical(options: VerticalMonthsLayoutOptions()),
dataDependency: nil)This means updating the calendar state does not require calling mutation methods on a view object; instead, you construct a new content value and apply it. The component then handles animated transitions between states. The README lists animated content updates as a supported feature, which follows naturally from this architecture.
Month layouts can be vertical or horizontal. The horizontal layout adds paging support, which is useful for date range pickers where a user swipes between months. Both layouts support right-to-left language environments.
Installing HorizonCalendar into Your Project
HorizonCalendar supports three installation methods. For Swift Package Manager, add the package to your Package.swift:
.package(name: "HorizonCalendar", url: "https://github.com/airbnb/HorizonCalendar.git", from: "1.0.0")For Carthage, add this line to your Cartfile:
github "airbnb/HorizonCalendar"For CocoaPods, add this to your Podfile:
pod 'HorizonCalendar'Once installed, import the framework at the top of any file that uses it:
import HorizonCalendarThe README warns that when running the example app, you must open HorizonCalendarExample.xcworkspace and not the .xcodeproj file, because the .xcodeproj does not have access to HorizonCalendar.framework. This applies when exploring the included demos for single day selection, day range selection, tooltip overlays, and animated scroll-to-date.
The repository has no GitHub releases; the project is distributed through the package managers above rather than tagged releases on GitHub.
Customization Points: Day Views, Range Indicators, and Decorations
HorizonCalendar provides multiple layers of customization. At the simplest level, you can adjust layout metrics such as the spacing between days and months. You can pin the days-of-the-week row to the top of the scroll view, show a separator below it, and use insets to offset content without affecting the scrollable region.
For deeper customization, you can supply custom views for individual days, month headers, and days-of-the-week labels. The README also documents custom views for date range highlights, overlays that cover parts of the calendar (enabling tooltip patterns), and background decorations at both the month and day level for things like color fills and grid lines.
Selection handling comes in two forms. A day selection handler reports a single tapped day. A multi-day selection handler monitors when multiple days are selected through a drag gesture, which is the interaction pattern used in hotel and rental booking flows where a guest selects check-in and check-out dates.
The component supports partial boundary months, meaning you can display exactly a range like March 14 to April 20 without forcing full month boundaries. It also supports all calendar systems available through Foundation.Calendar, including Gregorian, Japanese, and Hebrew.
Hard Limits and Cases Where It Is the Wrong Tool
HorizonCalendar is a UIView subclass (in UIKit) and a SwiftUI view (through CalendarViewRepresentable). It requires iOS 11 and above, which is not a constraint in most current projects but remains a stated minimum. If your deployment target is iOS 10 or below, this component is not available.
The component handles rendering and interaction, not data. If your calendar needs to show events fetched from a server, synced with EventKit, or sourced from any external system, that data pipeline is entirely the host application's responsibility. HorizonCalendar provides the hooks to render custom views for those events, but it does not include data fetching, caching, or storage.
Scrolling to arbitrary dates and months is supported with or without animation, but the README does not document programmatic date range manipulation or an API for bulk-selecting dates from code. If your use case requires that kind of server-driven selection state, you need to build the state machine yourself and feed it back through the content model.
How HorizonCalendar Compares to FSCalendar and UICalendarView
FSCalendar is a popular iOS and macOS calendar library that uses an imperative, delegate-based approach. To configure what each day looks like, you implement delegate methods that FSCalendar calls cell-by-cell. HorizonCalendar's approach is different: you describe the entire calendar's content as a value and let the component reconcile what changed. For teams comfortable with UIKit delegates, FSCalendar's model may feel familiar; for teams already working with SwiftUI or unidirectional data patterns, HorizonCalendar's model is closer to the idioms they use elsewhere.
Apple's UICalendarView is the native iOS alternative. It is a system component and does not require a third-party dependency, which simplifies the dependency graph. HorizonCalendar's advantage over UICalendarView is its lower deployment target and the documentation that it powers Airbnb's own production calendars, making it easier to predict how it will behave in complex, high-traffic applications.
JTAppleCalendar is another Swift-based alternative focused on performance with large datasets. It uses a collection view architecture similar to HorizonCalendar. The README's related searches show these libraries are commonly compared by developers evaluating iOS calendar options.
Editorial conclusion
HorizonCalendar is the right choice for iOS apps that need a date picker or calendar view beyond what UIKit provides out of the box, particularly when the design calls for custom day views, range selection, overlays, or non-Gregorian calendar systems. It is less appropriate if your deployment target is locked to a version below iOS 11, or if your team is already invested in FSCalendar and the migration cost outweighs the benefits of the declarative model. Before adopting it, verify that the available example demos in HorizonCalendarExample.xcworkspace match the interaction model your app requires, and check that the Apache 2.0 license is compatible with your project.
Frequently asked questions
Which iOS versions does HorizonCalendar support?
HorizonCalendar requires a deployment target of iOS 11 or higher, with Swift 5 and Xcode 10.2 or newer. The README lists these as the stated requirements.
Does HorizonCalendar work with SwiftUI?
Yes. HorizonCalendar provides CalendarViewRepresentable, a SwiftUI view type where all customization is done through initializer parameters and modifiers. The UIKit version uses CalendarView, a UIView subclass configured through CalendarViewContent.
Which calendar systems does HorizonCalendar support?
HorizonCalendar supports all calendar systems available through Foundation.Calendar, including Gregorian, Japanese, and Hebrew. The README states this explicitly as a supported feature.
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/airbnb-horizoncalendar)