Comparison · 2026 · 07 · 16 · Architecture
napkin vs VIPER: from pattern to framework
VIPER and napkin are relatives, not rivals. VIPER is a five-role architecture pattern from 2014; Uber's RIBs was, in Uber's own words, inspired by it; napkin is a Swift 6 rebuild of the RIBs shape. This page maps the components nearly one-to-one and says plainly where each generation of the idea fits in 2026.
What VIPER actually is
The canonical source is "Architecting iOS Apps with VIPER" by Jeff Gilbert and Conrad Stoll (objc.io, Issue 13, June 2014). VIPER came out of Mutual Mobile's push to improve testing, and the article says exactly what it is: "VIPER is an application of Clean Architecture to iOS apps." The word is a backronym — View, Interactor, Presenter, Entity, Routing — five roles per screen module, each with a strict job: the Interactor "contains the business logic as specified by a use case"; the View "displays what it is told to by the Presenter"; Entities are "never passed from the Interactor to the Presenter"; and navigation is done by a wireframe that owns the window and view controllers — "together, they describe a route from one screen to the next."
Note what VIPER is not: a library. You adopt it by writing (or generating) the five roles yourself. The dedicated tooling has gone quiet — Viperit, the best-known VIPER library, hasn't shipped a release since September 2021, and Infinum's Xcode templates last cut a release in 2023 (with some branch activity since). The pattern still works; the ecosystem around it is mostly historical.
The family tree: VIPER → RIBs → napkin
Uber's engineers wrote in their 2016 rider-app architecture post: "When considering alternatives to MVC, we were inspired by the way VIPER could be used as an application of Clean Architecture to iOS apps." RIBs kept VIPER's Clean-Architecture instincts and changed the unit of composition — and today's RIBs-iOS README states the classification plainly: "MVC, MVP, MVI, MVVM and VIPER are architecture patterns. RIBs is a framework."
napkin sits one generation further along the same branch: the RIBs shape (Router-Interactor-Builder tree), with the reactive layer replaced by Swift 6 concurrency. (RIBs-iOS itself runs on iOS 15+, if you want the tree shape below napkin's floor.) If you know VIPER, napkin will feel familiar — the concepts below map almost one-to-one.
Component mapping
| VIPER | napkin | What changed |
|---|---|---|
| View | ViewControllable / SwiftUI view | Same job. In napkin the view is optional — headless units exist; in VIPER, V is a mandatory letter. |
| Interactor | Interactor (a final actor) | Same job — the use-case brain. napkin makes its isolation physical: it runs off the main thread by construction. |
| Presenter | Presenter (@MainActor, @Observable) | Same job, also optional in napkin. View state becomes observable properties instead of hand-wired callbacks. |
| Entity | Your service layer's models | napkin has no Entity role — model types belong to the services you inject, and the same "don't leak them into the UI" discipline applies at the actor boundary, which at least makes the hand-off explicit. |
| Routing (wireframe) | Router + Builder | VIPER's wireframe both navigates and assembles the module. napkin splits that: the Router owns attach/detach of children; the Builder owns construction and dependency injection. |
The two real structural differences
1. Screen modules vs a unit tree. In VIPER, the presenter and wireframe together describe "a route from one screen to the next" — the unit of composition is the screen, and wireframes chain them. napkin (like RIBs) composes a tree: parents attach child units, children report back through listener protocols, and — as Uber's README puts it — "business logic drives the app, not the view tree." A unit doesn't need a view at all, which is how flows like authentication or session management get modeled as first-class units instead of living awkwardly inside some screen's Interactor.
2. Who enforces the rules. VIPER's separations — Entities never reach the Presenter, Views stay passive — are discipline: five roles per screen that you (or your code review) keep honest, which in practice means a lot of files and protocol plumbing per screen. That structural verbosity is the price of the pattern. To be fair, napkin doesn't shrink the file count much — a unit is still a Builder, Router, Interactor, and optional Presenter, and napkin ships Xcode templates to stamp them out. What changes is who enforces the seams: in napkin the isolation boundary is compiler-checked — business logic lives in an actor, UI in @MainActor types, and crossing between them without await is a build error, not a review comment. (The compiler checks the crossing, not the cargo: keeping entities out of the UI is still your discipline to keep.)
When to choose VIPER
- You maintain an existing VIPER codebase that works — the pattern didn't stop working; don't churn for fashion.
- You need to support OS versions below iOS 26, where napkin can't follow you.
- Your team wants a pattern with zero framework dependency at all — VIPER is just files you own.
- You value a decade of accumulated writing, answers, and engineers who already know the pattern — napkin is young (v2.1.x, a tiny community) and can't offer that yet.
When to choose napkin
- You liked VIPER's separation of concerns but not maintaining it by hand — napkin keeps the separation and hands enforcement to the Swift 6 compiler.
- Your app has flow-shaped complexity that screen-to-screen wireframes model poorly — the unit tree, with headless units, is built for it.
- You're starting fresh on iOS 26/macOS 26 with Swift Concurrency as the house style.
Related: napkin vs RIBs · napkin vs TCA · When to use napkin · FAQ