All three patterns share a model and a view. They disagree about the piece in between: a controller in MVC, a presenter in MVP, a ViewModel in MVVM. Server-rendered frameworks such as Rails and Spring MVC fit MVC, and WinForms and other platforms with limited binding end up on MVP. WPF, .NET MAUI and Android went with MVVM.
Martin Fowler’s Presentation Model page (martinfowler.com, 2004) lists MVVM as an alternative name for that pattern, which traces MVVM to Presentation Model rather than straight to MVC.
The quickest way to tell them apart in code is the view reference. A presenter holds the view through an interface. A classic MVC controller and a ViewModel hold no view reference.
What are the differences between MVC, MVP and MVVM?

Model, view and a go-between. That structure is common to all three, and the go-between is where they split. Each one gets state onto the screen in its own way.
| Aspect | MVC | MVP | MVVM |
|---|---|---|---|
| Mediator | Controller | Presenter | ViewModel |
| Handles user input | Controller | Presenter, after the view forwards the event | ViewModel commands bound from the view |
| Holds a view reference | No in classic MVC (UIKit view controllers do) | Yes, through an interface | No |
| How the screen updates | Controller refreshes the view when the model changes | Presenter sets values through the view interface | Binding or observed state reads from the ViewModel |
| Common home | Rails, UIKit | WinForms, ASP.NET Web Forms | WPF, .NET MAUI, Android |
That third row does most of the work. An AsianPLoP 2017 paper puts it plainly: the presenter reaches the view through an interface, while the MVC controller does not know the view.
Roughly, a controller decides what the user sees next and a presenter tells the view what to show, while in MVVM the view just reads whatever the ViewModel exposes.
How MVP and MVVM grew out of MVC
The history is short, and it starts at Xerox PARC.
- Trygve Reenskaug wrote his two original MVC reports at Xerox PARC, dated 12 May and 10 December 1979 (University of Oslo repository).
- Mike Potel’s 1996 paper described MVP as the Taligent programming model for C++ and Java (Taligent).
- Fowler published Presentation Model on 19 July 2004, and his page now also files it under the name MVVM (martinfowler.com).
- John Gossman introduced Model/View/ViewModel for WPF on his Microsoft blog in 2005.
- In 2006 Fowler retired his Model View Presenter page and split it into Supervising Controller and Passive View. The retirement note is dated 11 July 2006 and the Passive View page 18 July 2006 (martinfowler.com).
Sources disagree on who MVVM’s parent is. O’Reilly’s Learning JavaScript Design Patterns calls both MVP and MVVM derivatives of MVC. AppMaster’s explainer calls MVVM an evolution of MVP. Fowler lists MVVM as another name for Presentation Model, and Microsoft’s retired patterns and practices guidance calls Presentation Model a variant of MVP.
They all fit one chain, really: MVC, then MVP, then Presentation Model, then MVVM. Each source just skips a different number of steps.
Gossman blamed the drift on the controller. He wrote in October 2005 that everyone agrees on separating model from view, but the controller was always the odd one out, and newer UI technology kept folding it into the view or the framework.
How MVC works

The model owns the data and rules. The view draws. The controller turns user input into model changes, and when the model changes the view gets updated, either through the controller or through an observer link.
The roles stay small on purpose, and the basic MVC structure looks the same across the three settings below. What changes is who owns the view.
Classic MVC in Smalltalk
Reenskaug wrote the original reports as a visiting scientist at Xerox PARC and described MVC as a general answer to users controlling large, complex data sets (University of Oslo repository).
In that form, view and controller were the display and input halves of a single on-screen control, according to Matt Gallagher’s analysis at Cocoa with Love. A controller never loaded or managed a view, and none served several.
The model held data and rules and knew nothing about any view. The view drew model state, and the controller turned gestures into model changes.
MVC on the web
Server frameworks fixed these roles by convention.
The Rails Guides call the controller a middle man between models and views: it makes model data available to the view and saves user data back to the model.
A request goes through the router first, which picks the controller and action. The controller reads params and loads or saves model data, then the view renders the response. The controller draws nothing, and the model never sees the request.
MVC in UIKit
UIKit changed the controller’s job.
Apple’s archived Cocoa documentation (updated 2018) says iOS view controllers often take over the coordinating controller role. A UIViewController manages a screenful of content, keeps a reference to its view, and handles transitions, low-memory warnings and rotation.
Screen-level concerns pile into one class, which is where the massive view controller complaints come from.
How does MVP work, and what are Passive View and Supervising Controller?

The view hands user events to a presenter. The presenter reads and writes the view through an interface and updates the model, which never touches the view.
The MVP pattern exists mainly to make presentation logic testable without a UI framework. DevIQ makes the point with ASP.NET Core Razor Pages, whose page model acts as a presenter that is tightly paired with its view, unlike MVC where any controller can render any view.
Microsoft patterns and practices guidance passes the view into the presenter at construction, a plain case of dependency injection. Tests can then hand in a fake view.
Passive View
Fowler’s Passive View write-up strips the view down to the minimum and gives the presenter everything else, including reloading the view from the model. The view receives gestures and passes them straight along. The presenter updates the model, then reloads the view from it, and there is no view-to-model link at all.
Fowler names testing as the primary driver. A stub or mock replaces the view, so the presenter is tested without any UI interaction.
Supervising Controller
Here the view talks to the model directly for simple, declarative data binding. The presenter steps in only for complex logic, such as recoloring a control or hiding and showing others (Microsoft patterns and practices guidance, retired content).
Simple field-to-property binding stays in the view. Responding to input and handling complex view logic falls to the presenter.
The cost is test coverage. Microsoft’s guidance ranks simpler code above complete testability in this variant, which needs less code because binding does the display work.
Microsoft’s Hilo sample for Windows Store apps using JavaScript picked this variant over Passive View for its HTML templating support.
How MVVM works without a controller or presenter

MVVM replaces the controller with a ViewModel that exposes state and commands. The view binds to them, and change notifications keep both sides in sync, so nothing pushes updates by hand.
Fowler’s earlier Presentation Model describes the same structure, and his page now lists MVVM as an alternative name, with ViewModel naming the presentation model element. The MVVM pattern is that structure plus a binding mechanism that removes the synchronization code.
Microsoft Learn’s .NET MAUI documentation spells out the wiring. The ViewModel raises PropertyChanged so two-way binding stays current, and commands are ICommand properties bound to a control’s Command property. The ViewModel also shields the view from the model, so the model can change on its own.
Does MVVM need a binding engine?
Fowler called view-to-model synchronization the most annoying part of Presentation Model and hoped a framework such as .NET data binding would automate it.
WPF did exactly that, Gossman wrote in October 2005. Its binding engine took over the observer plumbing and added two-way binding, declaratively.
.NET MAUI binds to ViewModel properties too, but unlike WPF it does not detect CanExecute changes on its own, so code raises CanExecuteChanged (Microsoft Learn). On Android, a ViewModel exposes UI state as a StateFlow that the UI collects in a lifecycle-aware way (Android Developers). WinJS has no two-way binding, which is why Microsoft’s Hilo team skipped MVVM in its JavaScript version (the C++ and XAML version of Hilo used MVVM).
Binding differs by platform. What stays constant is a ViewModel with no reference to the view, and Android’s architecture recommendations tell teams not to hand a ViewModel Activity, Context or Resources references.
Which pattern is easiest to unit test?

MVP and MVVM test best, because their mediators run without a UI: a presenter against a fake view, a ViewModel against fake dependencies. MVC depends on the framework, since ASP.NET Core MVC is built for controller tests while a UIViewController keeps a reference to its view.
| Pattern | Unit under test | Test double | Left untested |
|---|---|---|---|
| MVC | Controller | Stubbed services passed through the constructor | View rendering |
| MVP | Presenter | Fake or mock view behind an interface | Event wiring in the view |
| MVVM | ViewModel | Fake repository, no UI | The bindings themselves |
Presenter tests lean on mocking the view behind its interface, and Microsoft’s MVP guidance points readers to Fowler’s article on mocks versus stubs.
Android’s testing guidance goes the other way. It says to prefer fakes to mocks, and Google’s Now in Android project uses no mocking libraries at all.
That sample also requires every feature ViewModel to be unit tested on the JVM, targeting 100% coverage. A ViewModel test needs no emulator, per the Android documentation, because the class does not depend on the Android framework.
Fowler adds a placement rule. Synchronization code left in the view escapes tests on the Presentation Model, so teams that want it covered keep it in a Presentation Model that references the view.
Bindings stay untested either way, and Gossman calls declarative binding harder to debug than imperative code with breakpoints.
Pattern defaults on Android, iOS, .NET and web frameworks
Platforms mostly ended up with a default because they shipped the plumbing for it. Android and SwiftUI lean on observable state, and .NET splits by project type. Server frameworks kept MVC.
Android
Google’s Android Architecture Blueprints repository implements one to-do app in several patterns. The baseline sample is todo-mvp, used as the reference point for the rest. todo-mvvm-live adds ViewModels and LiveData from Architecture Components, plus the Data Binding library.
As of October 2026, Google’s architecture recommendations advise ViewModels where their benefits apply to the app, not as a blanket rule.
iOS
Apple’s SwiftUI documentation makes model changes visible to views by applying the @Observable macro to a data model class, with the view holding the instance in State. It requires iOS 17, macOS 14 and Xcode 15 or later.
That gives a ViewModel its wiring: a class that holds screen state and notifies the view. Apple also documents mixing the older ObservableObject protocol with the macro in one app, so adoption can go screen by screen.
.NET
MVVM is the native fit for WPF and .NET MAUI, and the other two patterns survive elsewhere in the stack.
- Microsoft calls ASP.NET Core MVC a highly testable presentation framework, with controllers receiving services through their constructors.
- The word ViewModel means something different there. In ASP.NET Core MVC it is a view-shaped data class the controller builds from the model, not the MVVM mediator.
- WinForms and ASP.NET Web Forms are where MVP lives, as in Phil Haack’s 2006 ASP.NET walkthrough, where the page class implements a view interface.
Web frameworks
| Framework | Where the controller role sits | Self-description |
|---|---|---|
| Spring MVC | DispatcherServlet, a front controller that dispatches to @Controller classes | MVC |
| ASP.NET Core MVC | Routing matches the URL and calls the controller action, which selects the view | MVC |
| Django | The framework’s URL dispatch, with a Python callback as the “view” | MTV, not strictly MVC |
Django’s FAQ says its view describes which data is presented, while the template describes how.
Where each pattern breaks down
Each one fails in a different place, and that failure point decides when to pick something else.
MVC
A controller that keeps absorbing logic turns into technical debt. Microsoft’s ASP.NET Core MVC guidance tells teams to push business logic out of the controller and into the domain model.
On the plus side, the model builds and tests independently of the view and controller (Microsoft Learn), and the roles line up with routing, controller action and template in server frameworks. The downsides are less tidy. UIKit view controllers collect screen-level duties, the source of the massive view controller (Educative). There is little built-in binding, so view updates stay manual, and controller logic bloats unless it is moved into the model.
MVP
| Pros | Cons |
|---|---|
| Presentation logic tests without a UI | More solution elements to manage (Microsoft patterns and practices) |
| Passive View needs no synchronization mechanism (Fowler) | Views and presenters need a way to be created and connected |
| Works where the platform has no binding | The presenter’s view reference is what Google’s guidance bars Android ViewModels from holding |
| Supervising Controller trims code with binding | Some developers call it overkill for simple apps (Educative) |
MVVM

MVVM cuts glue code in code-behind, and a ViewModel tests without UI automation (Gossman, Microsoft blog, 2006).
Against that, Gossman calls it overkill for simple UIs, and in bigger cases it is hard to give a ViewModel the right generality up front. Declarative bindings are also harder to debug than imperative code. Memory can bite too. In one WPF build with 50,000 bindings, swapping them for a single static callback saved nearly 100MB.
A University of Stuttgart review (Fuksa, Speth and Becker, 2025) lists those same drawbacks as the standard ones. It found 15 additional drawbacks across blogs, papers and books.
Sources split on the small end. Gossman calls MVVM overkill for simple UIs, while critic Alexander Biskop, quoted on a Microsoft MSDN blog, rates it well for record-editing and simple projects and against large-scale ones.
How do you choose between MVC, MVP and MVVM?

Go with whatever your UI framework already supports. MVC suits server-rendered web apps, MVVM suits platforms with built-in binding or observable state, and MVP fits where binding is limited or missing and tests matter.
- A server-rendered web app gets MVC, in whatever form Spring MVC, ASP.NET Core MVC or Django provides.
- WPF, .NET MAUI, SwiftUI or Android with ViewModel all point to MVVM.
- WinForms or ASP.NET Web Forms with a testing requirement calls for MVP with Passive View.
- If binding is available and simpler code ranks above full testability, Supervising Controller fits.
- For one small screen, keep the logic in the controller or view.
MVVM is the usual default now, and a reasonable one. It still loses on a one-field screen, because Gossman’s own verdict was that it is overkill for simple UIs.
Google’s Android guidance is conditional in the same way. ViewModels belong where their benefits apply to the app.
How to migrate from MVP to MVVM in an existing app
Migrate screen by screen: move state from the presenter into an observable ViewModel, replace view-interface calls with state observation, port the tests, then delete the presenter.
Treat the move as code refactoring, with the old presenter tests pinning behavior until the new ones pass.
- Pick one screen with decent presenter tests, and keep those tests as the behavior spec.
- Create a ViewModel and move the presenter’s state into it as observable properties or a state flow.
- Turn each presenter-to-view call into state. Google’s guidance says to handle the event in the ViewModel and publish the result as state, not to send events to the UI.
- Drop view, Activity and Context references from the moved logic.
- Port the tests to the ViewModel, using fakes instead of a mock view.
- Delete the view interface and presenter, then repeat on the next screen.
The hard screens depend on call order, such as open a dialog, then navigate. Step 3 flattens those calls into state, so the sequence has to be modeled again.
Reading the same app in both patterns first helps, and Google’s blueprint branches provide exactly that.
MVC vs MVVM vs MVP FAQ
Are MVC, MVP and MVVM architectural patterns or design patterns?
Mostly architectural. An InformIT chapter from Cocoa Design Patterns describes MVC as a high-level pattern for organizing large groups of cooperating objects into subsystems.
Fowler’s Passive View, Supervising Controller and Presentation Model sit in his Further Enterprise Application Architecture draft writing, which follows on from Patterns of Enterprise Application Architecture.
How much does the pattern choice affect app performance?
Slightly, and mostly through binding. Gossman rated WPF binding performance quite good on his Microsoft blog, but noted it creates a lot of bookkeeping data.
Watch the binding count on large views.
Is MVC still used in modern frameworks?
Yes. Spring’s reference calls Spring Web MVC the original web framework in the Spring Framework, and ASP.NET Core MVC and Rails follow the same pattern.
UIKit apps use it through view controllers.
Can one app mix MVC, MVP and MVVM?

Yes, screen by screen. Each screen needs one owner for its state, so a presenter and a ViewModel on the same screen duplicate it.
Mixed codebases are normal in the middle of a migration.
How does MVVM differ from MVI?
MVI, short for Model-View-Intent, is a fully reactive variant that Google’s Android Architecture Blueprints list as an external sample.
Google’s current guidance already has the ViewModel expose state and take actions as method calls, which amounts to unidirectional data flow. The practical gap is the intent stream.
When Switching Patterns Is Worth the Cost
Moving an app between MVC, MVP and MVVM pays off only when a recurring defect traces to the pattern itself, such as controller logic that cannot be tested without a screen. A framework’s default is not a defect.
Start by naming the defect and the screens it hits. Fix it inside the current pattern next, then migrate one screen as a trial.
Fixing in place comes first because it costs less than a rewrite and shows whether the pattern caused the defect. The trial screen comes last because its result decides whether the other screens follow.
A half-migrated app runs two state owners and two test styles until the last presenter is deleted.
As of October 2026, the advice rests on Google’s ViewModel-centered Android recommendations and Apple’s observation-based SwiftUI model data. A change in either default shifts the verdict, and the wider software architecture around the UI layer sets what a change costs.
- What Communications Teams Should Ask Before Commissioning a Mobile App - November 12, 2026
- How to Install Node JS in VS Code and Run Your First Script - November 11, 2026
- Protecting Users and Brand Standards Across Image-Driven Platforms - November 10, 2026



