§ 00·The framework
Apps as a tree of small, isolated, composable units.
napkin is a Swift 6.2 framework for clean-architecture iOS & macOS apps, modeled on Uber's RIBs and rebuilt around Swift Concurrency. Business logic lives in final actor interactors. Routing and presentation are @MainActor. Crossings are explicit.
1final actor HomeInteractor: PresentableInteractable {
2 nonisolated let lifecycle = InteractorLifecycle()
3 nonisolated let presenter: HomePresentable
4
5 init(presenter: HomePresentable) {
6 self.presenter = presenter
7 }
8
9 func didBecomeActive() async {
10 task {
11 for await user in users.stream() {
12 await presenter.update(user)
13 }
14 }
15 }
16}
Specifications
Four moves that distinguish napkin from every framework that came before it — including its parent.
-
Clean isolation, by the compiler
Business logic lives in
final actorinteractors — off the main thread, by construction. Routing and presentation are@MainActor. Swift enforces the dependency rule, not convention. -
No Combine. No RxSwift.
@Observablefor state.AsyncStreamfor events. Structured concurrency for everything that used to need a subscription bag. Combine is removed; Rx never arrives. -
iOS 26 · macOS 26 · Swift 6.2
Built on
isolated deinit,MutexfromSynchronization,@Observable, andObservations { }. Concrete bets on the modern stack — no polyfills, no compromises. -
Modeled on Uber's RIBs
Builder, Component, Interactor, Router, Presenter. The familiar architecture you can sketch on a napkin — rebuilt around
actorand friends, with composition where inheritance once lived.
The isolation map
Three regions. Each ring lives in a specific isolation domain. Every crossing is explicit and named.
constructs the napkin
DI container
owns the subtree
hosts the SwiftUI view
@Observable state
business logic, off main
await router?.routeTo(…)await presenter.update(…)dispatch { await listener?.didTap(…) }
Data flows down the tree. Events flow up through listener protocols. Every cross-region call is an await — an architectural seam, made legible.
§ ∞·Get started
Sketch your next app on a napkin.
Pull the package, read the docs, run the example. Three commands, one tree, one isolation rule the compiler is willing to enforce.
// Package.swift
.package(url: "https://github.com/WikipediaBrown/napkin.git", from: "2.0.15")