MVC (Model-View-Controller)
MVC (Model-View-Controller) is a software architecture pattern that splits an application into three connected parts: the Model (data and business logic), the View (what the user sees), and the Controller (the layer that wires the two together).
Definition
MVC (Model-View-Controller) is a software architecture pattern that splits an application into three connected parts: the Model (data and business logic), the View (what the user sees), and the Controller (the layer that wires the two together). The point of the split is separation of concerns. A change to how data is displayed should not force a change to the business rules, and a change to the rules should not force a redesign of the screen.
On Salesforce, MVC is the design pattern behind Visualforce. The Salesforce documentation states it plainly: Visualforce uses the traditional model-view-controller paradigm. A Visualforce page is the View, an Apex controller is the Controller, and the database (sObjects such as Account and Contact, plus any Apex that reads or writes them) is the Model. The same separation carries forward into Lightning Web Components and Aura, where the vocabulary changes but the layering does not.
How MVC shows up across the Salesforce stack
The three layers and why the split exists
The Model holds data and business logic. The View presents that data to a user. The Controller sits between them and coordinates the flow. Salesforce describes the relationship directly: the View interacts with a controller, and the controller provides functionality to the page. The controller in turn interacts with the model, making data available that the view might want to display, or pushing changes back to the database. The value is in the boundaries. When the View and Model talk only through the Controller, you can restyle a page without touching business rules, and you can change a rule without redesigning the screen. That isolation is what keeps a growing application maintainable. It also keeps each layer testable on its own terms, because logic can be exercised without rendering a UI, and a UI can be checked without re-deriving the logic. MVC came out of Smalltalk in the late 1970s, long before Salesforce existed, but the platform adopted the same vocabulary so developers had a shared mental model for where code belongs.
Visualforce: the canonical Salesforce example
Visualforce makes the three layers concrete, which is why it is the example most Salesforce developers learn first. The page itself, written in tag-based markup that resembles HTML, is the View. It declares what the screen looks like and which actions its buttons and links trigger. The Apex controller is the Controller. It exposes public properties that the page reads and public methods that page actions invoke. The Model is the set of sObjects the page works with, plus any Apex that queries or updates them through SOQL and DML. A button labeled Save does not contain save logic in the markup. The markup points at a controller method, the method runs the business rule and the database write, and the page re-renders with the result. Because the markup never embeds the logic, two developers can work in parallel, one shaping the layout and another writing the Apex, as long as they agree on the property and method names that form the contract between View and Controller.
Standard controllers do the common work for you
Salesforce ships built-in controllers so developers do not rewrite routine database plumbing for every page. According to the documentation, a standard controller provides a set of standard actions such as create, edit, save, and delete that you add to a page using ordinary buttons and links. Every standard object and every custom object has a standard controller, so a page bound to the Account standard controller can display and edit an Account record without a single line of Apex. This is MVC with the Controller layer supplied by the platform. You associate a standard controller by naming it in the page tag, after which the View gets typed access to the record and the prebuilt CRUD actions. Standard controllers also enforce the running user's sharing and field-level security by default, which means the platform-provided Controller respects permissions without extra code. For pages that only need to view or edit one record with the usual behavior, this is the fastest correct path, and it keeps the Model interaction entirely inside Salesforce-managed code.
Custom controllers and controller extensions
When the standard actions are not enough, you write your own Controller in Apex. A custom controller is an Apex class that implements all of a page's logic on its own. A page that uses a custom controller does not use a standard controller, because the custom class is now fully responsible for fetching data and handling actions. A controller extension is the middle ground. It is an Apex class that adds functionality on top of a standard controller, so you keep the prebuilt CRUD behavior for a record and layer extra methods or properties beside it. A common pattern is a page bound to the Account standard controller with an extension that adds a custom action the standard controller does not offer, such as recalculating a rollup or calling an external service. The choice maps cleanly onto MVC. Standard controller alone means the platform owns the Controller. An extension means you share it. A custom controller means you own it entirely, which gives the most freedom and also the most code to test.
The same pattern in Lightning Web Components
Lightning Web Components keep the MVC separation while changing every name. The HTML template is the View. The JavaScript class is the Controller, since it owns the component's state and responds to user events. The Model is the Apex method exposed to the component, annotated so the framework can call it. An Apex method used by a Lightning web component must be static, public or global, and marked with @AuraEnabled. The component reads data through the reactive wire service with the @wire decorator, or it calls Apex imperatively when it needs to control exactly when a read runs or when it modifies records. The split is identical to Visualforce in spirit. The template never queries the database, and the Apex never renders markup. They meet at the boundary the JavaScript class manages. Reactive variables, prefixed with a dollar sign in a wired call, let the View signal the Model that an input changed so fresh data flows back. The lesson learned in Visualforce, keep presentation and data access apart, transfers directly to modern component work.
Aura and the line back to Visualforce
Aura Components were the Salesforce-proprietary framework that bridged the Visualforce era and Lightning Web Components, and they follow MVC too. The .cmp markup is the View. A JavaScript controller and an optional helper file act as the Controller, holding event handlers and shared functions. The Apex @AuraEnabled methods serve as the Model, exactly as they later would for LWC. Lightning Web Components modernized the approach by building on web standards such as native custom elements and ES modules, rather than a proprietary component model, but the underlying MVC layering stayed in place. Seeing the pattern repeat across three frameworks is the point. The frameworks change with the platform's UI strategy, yet the question of where a given piece of code belongs, data access in the Model, orchestration in the Controller, presentation in the View, has a stable answer. A developer who internalizes that answer can read a fifteen-year-old Visualforce page and a brand-new LWC and recognize the same skeleton underneath both.
Keeping controllers thin and layers honest
The separation only pays off if you respect it, and the most common failure is the fat controller. When business logic and data access pile up inside a Visualforce controller or an LWC JavaScript class, the layer that was supposed to coordinate starts doing everything, and it becomes hard to test and harder to change. The fix is to push logic down into the Model. In practice that means moving real business rules into separate Apex classes that the controller calls, so those rules can be unit tested in isolation with no UI involved. Many enterprise Salesforce teams formalize this with extra layers beyond plain MVC, a service layer for business operations and a separate data access layer for queries and DML, with the controller reduced to a thin adapter the component talks to. You do not need that ceremony for a small page. You do need the instinct it encodes. Watch for logic creeping into Views and data access creeping into Controllers, because both are signs a layer is leaking and the cost of that leak compounds as the codebase grows.
Trust & references
Cross-checked against the following references.
Straight from the source - Salesforce's reference material on MVC (Model-View-Controller).
Hands-on resources to go deeper on MVC (Model-View-Controller).
About the Author
Dipojjal Chakrabarti is a B2C Solution Architect with 29 Salesforce certifications and over 13 years in the Salesforce ecosystem. He runs salesforcedictionary.com to help admins, developers, architects, and cert/interview candidates sharpen their fundamentals. More about Dipojjal.
Test your knowledge
Q1. What does MVC stand for?
Q2. What plays each role in Salesforce?
Q3. Why use MVC?
Discussion
Loading discussion…