Angular MVVM, MVC, CBA – A look at different approaches to application architecture

Paweł Żurawski

Frontend i Mendix Developer

  • June 27, 2024

Contents

Angular is one of the most popular platforms for building web applications, enabling developers to create scalable, efficient, and modular solutions. It’s one of the oldest frameworks still in use today. Since its inception, Angular has gone through numerous modifications, adapting to the changing needs and expectations of both developers and end users. Unfortunately, over time, a lot of false or outdated information has also appeared around this technology, which you can still encounter today. In this article, I will try to explain one of the inconsistencies that constantly appears in developer communities.

As you have probably already deduced from the title of this article, the topic is the architecture of the Angular framework. If you are here, you are probably looking for an answer to the question: what architecture Angular actually uses? If you look on the Internet, you can find numerous sources saying it’s MVC, others mention MVVM, and still others stipulate none of the above is correct. 

So, let’s take a look at these abbreviations and what they have in common with Angular. When you understand these concepts and have a full view of the subject, you will be able to determine the true nature of Angular architecture. However, before I delve deeper into the architecture of the framework itself, I want to define what exactly I mean by the term “architecture” in the context of web application development.

What is architecture in the context of applications?

Software architecture refers to the overall plan or pattern by which individual components of an application are designed and organized – how they are interconnected, their relationships, and the rules by which they function to achieve a specific goal. Properly executed application design ensures that the system is scalable, efficient, secure, and easy to maintain. Well-designed architecture also allows you to easily add new functions, change existing functions, and solve problems and errors. Planning software architecture shouldn’t be done in haste – the fundamental structural decisions may turn out to be very costly if you need to make changes later.

In the case of web applications, architecture is crucial due to the need to effectively manage interactions between the client and the server and between the various elements of the application itself. A properly designed architecture contributes not only to easier maintenance, expansion and testing of applications, but also to a better user experience and, therefore, a higher level of end-user satisfaction. Now, let’s look at how these needs are met by the architectural approaches mentioned in the introduction.

MVC architecture

The history of the MVC architecture dates back to the late 1970s when it was developed by Trygve Reenskaug, who created it while working on solving the problem of user control of large and complex data sets. At that time, his solution was used to create GUI (graphical user interfaces) for desktop applications. However, over time, this architectural pattern was used more and more often in frameworks such as Ruby on Rails, Laravel, and AngularJS. As a result, it’s currently used mainly to create web and mobile applications. There are three main elements in the MVC architecture: Model, View, and Controller.

  1. Model – In the MVC architecture, Model represents the lowest level and refers to application data and business logic by performing data validation. Its scope is data management and processing. The Model layer is directly connected to the database, so all data operations, such as adding and retrieving, are performed only by it. This division allows you to separate the Controller logic (see below) from direct access to the database.
  2. View – This layer is responsible for presenting data by generating the user interface (UI). In the case of web applications, this is done using an HTML template and a CSS style sheet. Views are therefore a graphical presentation of data provided from the Model in a way that is understandable to the user. However, View doesn’t have the ability to communicate with Model. For this reason, View generation is based on the information received from the Controller. View is also responsible for transmitting information to the Controller about actions performed by the application user.
  3. Controller – The last, but key, element of the MVC architecture is Controller. It acts as an intermediary between Model and View. It receives events triggered by the user (such as clicking a button) and takes appropriate actions based on them, including updating the information stored in the model based on them. Controller communicates with Model by retrieving or updating data, and then passes it to the appropriate View for display. Due to the fact that View is passive and only presents data, Controller contains the logic that decides what actions to perform in response to user interactions. For this reason, it’s responsible for determining what data and Views will be displayed by the application interface.

The MVC architecture provides a solid structure that streamlines the process of creating, managing, and maintaining software. This is achieved by dividing the application into smaller, more manageable elements. The key advantage of MVC is the ability to independently implement and modify various application components, making it easier to reuse them, thus accelerating the application development process and increasing scalability.

Dividing the application into smaller elements also makes testing much easier. You can test individual, less complex parts of the application independently. This ultimately leads to improved code quality and faster verification of correct application operation. Additionally, it reduces the risk of code duplication and errors.

However, MVC also has some disadvantages. 

  1. Applying this architecture correctly requires more time. Its high complexity can be a challenge, especially in smaller projects where full implementation of the MVC architecture may be disproportionate to the benefits obtained. 
  2. In the case of large-scale applications, there are problems resulting from difficulties in maintaining consistency between layers. As your application grows, Views may become more complex, leading to problems with readability and maintainability of your code.
  3. In the case of extensive requirements, it may also turn out that the Controllers will become too complex, which would make maintaining and testing the code difficult. As the size of the application increases, the complexity of managing it and maintaining the created elements increases proportionally.

MVVM architecture

The MVVM (Model-View-ViewModel) architecture is the creation of Microsoft architects Ken Cooper and Ted Peters. MVVM is a design pattern often used to create user interfaces (UI), especially in applications based on technologies such as WPF (Windows Presentation Foundation) and Xamarin. Similar to the MVC architecture, MVVM aims to separate the presentation layer from the business logic, which contributes to better code organization, easier application management and maintenance. MVVM was announced in 2005 by John Gossman, the architect of Microsoft WPF and Silverlight.

Like MVC, MVVM has three main elements: Model, View and ViewModel.

  1. Model – In the MVVM architecture it’s similar to its counterpart in the MVC architecture. It refers to application data and business logic, such as data validation or operation processing. Model isn’t aware of View or ViewModel layers, which makes it independent of the presentation layer. In an MVVM architecture, Model typically represents the data that the application processes and displays.
  2. View – It’s responsible for the structure, layout, and appearance of what is presented to the user. Similarly to MVC, it represents the data model and receives user interactions, passing them to ViewModel using data binding. It consists of a user interface (UI) that is displayed to the user. View in MVVM doesn’t contain business logic. Instead, View connects to ViewModel, which provides the data and operations needed to display and interact with the data.
  3. ViewModel – A key element in the MVVM architecture. It’s an intermediary layer between View and Model. Unlike Controller in the MVC pattern, MVVM uses data binding, which automates communication between View and its associated properties in ViewModel. Therefore, ViewModel presents the state of the data in the Model and handles two-way communication between the Model and the View through data binding technique. ViewModel provides the data and operations that a View uses to display data and handle user interactions. Additionally, ViewModel can contain logic related to data processing and validation, which allows for more complex operations, such as filtering, sorting or grouping data, without the need to interfere with the view or model layer. It is important that the ViewModel in MVVM does not contain any code related to data presentation, which facilitates better separation of layers and facilitates application testing.

The MVVM architecture extends traditional design patterns by emphasizing a clear separation between the user interface and business logic, promoting modularity and ease of testing. It’s especially effective in frameworks that support rich data-binding capabilities, such as WPF and Xamarin. A distinguishing feature of MVVM is its reliance on data binding, which connects the View and the ViewModel, ensuring that changes in the Model state are automatically reflected in the user interface without requiring manual updates. This automation significantly reduces boilerplate code associated with UI updates, allowing developers to focus more on business logic rather than maintaining UI synchronization.

The MVVM architecture is particularly advantageous for applications with complex user interfaces or those requiring frequent updates and real-time interaction, as it promotes a clean and maintainable codebase. The pattern encourages the use of declarative data binding and command patterns, decoupling the View from the Model. Despite its benefits, MVVM can introduce complexity, especially in smaller projects where its extensive infrastructure might be excessive. Additionally, mastering MVVM requires a solid understanding of data binding and command patterns, which can pose a stiff learning curve for developers new to this architecture. Nonetheless, MVVM remains a powerful and widely-adopted pattern, particularly in frameworks where its strengths in managing intricate UI logic and enhancing testability are most evident.

The Component-Based Architecture revolution

In 2013, with the appearance of the React library, the way we perceive the architecture of front-end applications changed fundamentally. The so-called Component-based Architecture proposed by this technology – an innovative way of creating applications as a set of smaller, customizable elements – has completely revolutionized the market. Instead of using traditional template-based approaches or direct DOM manipulation, the focus was on decomposing complex systems into modular, reusable units called components.

To understand the source of this solution’s popularity, we need to examine the main principles of this architecture, including the following features:

  • Components as basic units – Applications built using component-based architecture treat components as the basic units. Each component represents a precisely defined part of the user interface and is not only independent in its operation, but also independent of other elements. Components can be treated as smaller blocks that can be used to create larger structures with easily replaceable components.
  • Code modularization – Code modularization is a key aspect of this architecture that allows the application to be divided into independent elements. Modularisation aims to increase the code’s readability, manageability and reusability, which contributes to improving its quality and maintainability. A single module often addresses a specific business scenario or represents specific functionality in an application.
  • Data transfer using props – Communication between components is carried out by passing props (properties), which enable the provision of data affecting the components’ appearance, behavior or content. Thanks to unidirectional data flow, props are transferred from top to bottom, ensuring transparency, predictability and ease of tracking the transferred data (props are transferred from parent to child unidirectionally, i.e., the child cannot transmit data to the parent).

Unlike MVC and MVVM, CBA doesn’t impose a strict separation of responsibilities between components, which gives developers greater flexibility in organizing and structuring their code. As I’ve mentioned, components in CBA can be easily composed into larger wholes to create complex user interfaces, and changes in one component do not necessarily affect the others. This approach promotes code reusability, maintainability, and scalability, making it suitable for large applications with variable requirements.

Unfortunately, the CBA architecture also has some drawbacks. The main challenge in programming environments using this architecture is determining the appropriate level of interface fragmentation into smaller elements. Excessive fragmentation can cause the application to lose readability, transparency, and ease of management and could potentially lead to slower performance. Additionally, a large number of smaller components may result in difficulty with managing the consistency of styles and interface behavior in many places.

React was the first library that would implement Component-based Architecture. When it came out, it quickly gained popularity because it improved the readability, maintainability, and scalability of front-end applications. Creating more dynamic and interactive applications was significantly easier, and these apps could be easily adapted to the organization’s changing needs. The discussed changes in the approach introduced by React, such as the focus on fragmented, simple, modular component creation, influenced the entire landscape of web programming. They had such a wide impact that they also influenced other popular frameworks, forcing extensive modifications.

Implementation of the MVC pattern in Angular

An image showing a laptop.

Now let’s move on to the purpose of this article, i.e., the architecture used by Angular. I described three popular software architecture approaches, and you probably see some similarities between their assumptions and this framework. However, it is impossible to clearly determine which of these architectures is implemented by Angular. I will try to show you what this means in the following sections.

Let’s start with a little bit of history. When AngularJS was created (in 2010), it quickly became one of the most popular Frontend frameworks. Back then, component-based architecture didn’t exist yet, and the Model-View-Controller architecture was at the peak of its popularity. For this reason, the creators of AngularJS also decided to use this architecture. However, as of Angular 2, a decision was made to move away from MVC due to the appearance of React and its proposed Component-Based Architecture. Although Angular no longer requires the use of the MVC architecture, it’s still possible to implement applications using it. However, this involves manually organizing application elements, such as components or services, in a manner consistent with this architecture’s assumptions. I’ll use examples based on the application I’ve created for the purposes of one of my previous articles: Angular SSR: Your server-side rendering implementation guide.

Model

This is a layer representing data and business logic of Angular-based applications. Information is usually stored in the form of JSON objects. In the case of Angular, the Model layer is represented by services and classes that are responsible for manipulating data, performing operations and communicating with various APIs. An example of such a website is provided below. It performs a simple query to obtain the data required by the application.

import { HttpClient } from '@angular/common/http';
import { inject } from '@angular/core';

export class AppService {
  http = inject(HttpClient);

  simpleGetRequest() {
    return this.http.get('https://jsonplaceholder.typicode.com/todos/1');
  }
}

View

Views are responsible for rendering the user interface (UI). For this purpose, Angular uses HTML templates extended with directives, which allows you to create dynamic pages. Additionally, by linking views to controllers, it is possible to correctly display data from the model and respond to user interactions. An example of such a simple template could be the following code:

<button (click)="decrement()">-</button>
    <span>{{ counterValue }}</span>
<button (click)="increment()">+</button>

Controller

As you already know, controllers in MVC play the role of an intermediary between View and Model. After receiving information from View, they process it and then communicate with Model to receive data with which it can, for example, update the view correctly. In both AngularJS and Angular, Controllers are components and services that handle business logic and interaction with data. An example of a component responsible for interacting with the model and rendering the appropriate view based on user input is presented below.

import { HttpClientModule } from '@angular/common/http';
import { Component, OnInit, PLATFORM_ID, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { tap } from 'rxjs';
import { AppService } from './app.service';


@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, HttpClientModule],
  providers: [AppService],
  templateUrl: './app.component.html',
})
export class AppComponent implements OnInit {
  counterValue = 0;
  appService = inject(AppService);
  ngOnInit(): void {
    this.appService
      .simpleGetRequest()
            .subscribe((resp) => {
        alert(resp);
      });
  }
  decrement() {
    this.counterValue--;
  }
  increment() {
    this.counterValue++;
  }
}

Considerable time has passed since AngularJS’s launch and MVC architecture’s wide adoption, and the approach toward MVC’s implementation changed substantially. However, upon examining both the old and new implementations of this model, it becomes evident that they don’t differ significantly. 

Implementation of the MVVM pattern in Angular

The MVVM pattern discussed earlier is characterized by numerous similarities to the MVC architecture. To use this architecture, it’s necessary to create a connection between View and Model via ViewModel. Of course, Angular allows you to create such a connection using the data-binding mechanism. Let’s look at an example of such an implementation. For this purpose, the app.component.ts file was created, acting as ViewModel and providing the logic responsible for creating a connection that provides information from Model to View.

import { Component, OnInit } from '@angular/core';
import { Item } from '../models/item';
import { ItemService } from '../services/item.service';


@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  componentItems: Item[];


  constructor(private itemService: ItemService) { }


  ngOnInit() {
    this.itemService.getItems().subscribe(items => {
      this.componentItems = items;
    });
  }
}

The above code is responsible for creating a subscription in AppComponent that constantly retrieves information about the list of available items from the ItemService. This means that if the data in Model changes, this change will be passed directly to View, where it will replace the information stored in the componentItems variable. Now, let’s look at the content of the app.component.html file, i.e., our HTML template acting as View.

<h1>List of items</h1>
<ul>
  @for (item of componentItems; track item) {
  <li>
    {{ item.name }}
  </li>
  }


</ul>

So let’s discuss how the individual components of this architecture are implemented by Angular:

  • Model – As in the case of MVC, the Model layer is also represented by data stored in components and services. They are responsible for the application data and the logic that manages this data.
  • View – In this case, Views are represented by HTML templates, similar to MVC. Thanks to data binding, interpolation and directives, it’s possible to associate View with ViewModel, similarly to the association with Controller.
  • ViewModel – This is where the application’s business logic is organized and managed. In the case of Angular, in addition to representing data in a view-friendly way, it allows you to transform data from Model. Various operations such as formatting, filtering, and sorting are used for this purpose. The data-binding mechanism available in Angular enables dynamic and automatic data binding between the ViewModel and View. Thanks to this, any change in data received by ViewModel is immediately reflected in View, increasing the application’s responsiveness and interactivity.

Implementation of the CBA pattern in Angular

When discussing the component-based architecture pattern, I mentioned that React’s emergence and its proposed solutions resonated widely in the world of front-end architecture. This resulted in many changes in other frameworks, including Angular 2. The Angular team adopted React’s proposed approach and opted for component-based architecture.

Anyone who has had the opportunity to work in this framework probably knows that Angular itself doesn’t force developers to create Controllers or ViewModels, i.e. elements characteristic of the previously discussed patterns. Of course, if we decide to use this framework in our project, nothing stops us from creating it ourselves and following the rules of the selected architecture. However, the elements characteristic of Angular are components consisting of, among other things: Classes, HTML Templates and MetaData (Decorators).

It’s possible to use classes to store data (e.g. by creating a service storing information downloaded using HttpClient from an external API), which resembles the Model layer. You can also add classes containing methods and variables that create a data connection between the data and the presentation layer – similar to Controller or ViewModel. We also have an HTML Template which resembles the View layer. All these elements allow the implementation of the mentioned models – however, if I said that Angular is a framework with MVC or MVVM architecture, it wouldn’t be a completely true statement.

Let’s look at what its official documentation says about the architecture of this framework:

“The architecture of an Angular application relies on certain fundamental concepts. The basic building blocks of the Angular framework are Angular components.

Components define views, which are sets of screen elements that Angular can choose among and modify according to your program logic and data

Components use services, which provide background functionality not directly related to views such as fetching data. Such services can be injected into components as dependencies, making your code modular, reusable, and efficient.

Components and services are classes marked with decorators. These decorators provide metadata that tells Angular how to use them.”

If you remember how I defined Component-Based Architecture, you probably realize that the above information presents very similar assumptions. After all, Angular’s characteristic feature is that the component plays the main role in the application. However, what about the implementation of the remaining assumptions of this architectural pattern? Let’s look at the most important features:

  • Components as basic units – Each Angular component represents a precisely defined part of the user interface, separated from other elements. For this reason, it can be described as the smallest component of the application.
  • Code modularization – Angular supports code modularization through the Angular Module. Modules in Angular allow you to logically group components, directives, services and other functions into units, increasing the readability, ease of management and reusability of the code.
  • Transferring data using properties – In Angular, information about variable values ​​is transferred on a top-to-bottom basis, which means data is transferred from parent to child using the @Input directive. This allows you to provide data that influences components’ configuration, appearance, behavior and content.

The emergence of React significantly impacted the development of Angular, stimulating the framework’s refactoring towards a more modular and transparent architecture. It’s quite clear that the changes the team behind Angular made were a strategically thought-out attempt to adapt the platform to new trends in the front-end world – a consistent desire to implement the Component-Based Architecture (CBA) architectural pattern. The result is a significant increase in the Angular application code’s flexibility, scalability and maintainability. 

Summary

An image of a keyboard and mouse.

Angular’s position as the third most popular frontend framework (according to the StateofJS2023 report) is due to its ability to adapt and evolve with the changing needs of developers and the technology industry. Backed by an active community and support from Google, Angular offers comprehensive tools and solutions for developers of modern web applications. The transition to Component-Based Architecture (CBA) marked a turning point that contributed to this platform’s stabilization and further development.

Despite this change, it should be noted that although the CBA architecture is now the basis of this platform, it doesn’t mean that the Model-View-Controller (MVC) or Model-View-ViewModel (MVVM) patterns can’t be implemented. These patterns are no longer directly enforced by the framework, but it gives developers flexibility in choosing their approach (for example, creating component classes that act as Controllers, etc.).

For more information about Angular, React and various (mostly front-end) technologies, check out my other articles on the Pretius blog:

  1. Angular SSR: Your server-side rendering implementation guide
  2. Angular vs React: In-depth comparison of the most popular front-end technologies
  3. Keycloak SSO guide for 2024: Advantages, installation, protips, and the real cost
  4. Liferay tutorial 2024: Installation, initial setup, key functionalities and widgets
  5. Liferay DXP guide: Features, cost, use cases, and possible alternatives
  6. Keycloak-Angular integration: Practical tutorial for connecting your app to a powerful IAM system
  7. Liferay portlet for front-end development – An introduction to different options in 2024

Looking for a software development company?

Work with a team that already helped dozens of market leaders. Book a discovery call to see:

  • How our products work
  • How you can save time & costs
  • How we’re different from another solutions

footer-contact-steps

We keep your data safe: ISO certified

We operate in accordance with the ISO 27001 standard, ensuring the highest level of security for your data.
certified dekra 27001
© 2025 Pretius. All right reserved.