Define routes as functions on an @Observable class. The @Scaffoldable macro generates a type-safe Destinations enum from your methods — no manual cases,
no switch statements, no boilerplate.
route(to:) only pushes. present(_:as:) handles
sheets and full-screen covers — and is available on every coordinator type.
Navigation
// Push onto the stack — type-safe destination.coordinator.route(to: .detail(item: planet))
// Present a modal — sheet or full-screen cover.coordinator.present(.settings, as: .sheet)
coordinator.present(.login, as: .fullScreenCover)
// Go back.coordinator.pop()
03 / Architecture
How it composes, end to end.
Roots switch state, tabs hold flows, flows push screens. Hover to peek a node, click to pin it
— the path back to the root highlights so you can see how it's wired.
RootTabFlowScreen·setRoottabroutepresent
○Hover to peek · click a node to pin
04 / Playground
See it in motion.
The phone is a working prototype — tap rows, tabs, the gear, the back
chevron. The action panel mirrors what's callable from the current coordinator: only valid Scaffolding functions
appear at any given moment.
9:41●●●
Planets
Tap rows, tabs, gear, or back arrow to drive the simulation.