FastList

0.3.0

A drop-in, NSTableView-backed replacement for SwiftUI List on macOS with instant scrolling and selection on huge lists.
adamtheturtle/FastList

What's New

0.3.0

2026-06-27T09:24:43Z

Added

  • onReachEnd(threshold:perform:) — fires when the last visible row comes within threshold rows of the end of the data as a user scroll settles, the trigger for load-more / infinite-scroll paging. Unlike onTopRowChange, it reflects the bottom of the viewport, so it fires correctly on any window size without estimating the visible-row count from row heights.

Closes #1.

FastList

A drop-in replacement for SwiftUI's List on macOS, backed by NSTableView. It materializes and recycles only the visible rows, so selection and scrolling stay fast on lists of any size, while keeping a SwiftUI-first, declarative API. SwiftUI's own List and Table rebuild every visible row on each selection change and slow down sharply at a few thousand rows.

API documentation

import FastList

FastList(people, selection: $selection) { person in
    PersonRow(person)
        .allowsHitTesting(false) // let clicks fall through to the table
}
.onDoubleClick { open($0) }
.onReturnKey { open($0) }
.swipeActions(edge: .trailing) { person in
    [SwipeAction(title: "Delete", role: .destructive, systemImage: "trash") { delete(person) }]
}

Selection (single, multiple, or none), swipe actions, right-click menus, drag and drop, and scroll-position restore are covered in the documentation.

Benchmark

Selecting a row costs the same whether the list holds a thousand rows or a million, because the table only renders the rows on screen. Measured against a real NSTableView:

Rows Selection change Reindex on data change
1,000 3.6 µs 0.40 ms
10,000 3.5 µs 3.6 ms
100,000 8.3 µs 64 ms
1,000,000 3.5 µs 0.32 s

Selection change stays flat as the list grows; reindex is the one-time cost when the filtered or sorted set changes. Reproduce with FASTLIST_BENCHMARK=1 swift test --filter Benchmark.

Installation

.package(url: "https://github.com/adamtheturtle/FastList.git", from: "0.1.0")

Requires macOS 13+ and Swift 5.9+. Run swift run FastListDemo for a 50,000-row demo.

Hit-testing

Each row hosts your SwiftUI view in an NSHostingView. Apply .allowsHitTesting(false) to the non-interactive parts of the row so left clicks fall through to the table for native selection; interactive controls in the row (a Toggle, a Button) still receive their clicks.

License

MIT. See LICENSE.

Description

  • Swift Tools 5.9.0
View More Packages from this Author

Dependencies

  • None
Last updated: Mon Jun 29 2026 09:31:48 GMT-0900 (Hawaii-Aleutian Daylight Time)