There’s a foundational question that every project starts with: accept the freedom to roll your own solutions along with the burdens that go with it, or take the chance to use sensible defaults that allow you to move quickly, but hide a multitude of decisions and set you on a prescriptive path.
Deciding whether or not to use an opinionated framework for your next project will have significant implications, both over the short term of getting the product to market on time and over the long haul. It can affect how easy your application will be to maintain and modify in order to meet changing needs. The answer may not always be clear or easy, but it'll help you learn when to choose the big opinionated framework.
In this article, we'll look at some opinionated versus non-opinionated frameworks and what use cases make sense for taking either path. We’ll also apply this thinking to use cases that are a better fit for an opinionated platform as a service (PaaS) or for a less opinionated infrastructure as a service (IaaS). This will help you make the best choice when building your own apps.
A framework, by definition, makes some assumptions about architecture, best practices, and conventions. This is often helpful to developers and architects as it provides a well-trodden path for future architectural decisions, and it can also help you end up with a codebase that is predictable, consistent, and easy for other developers to understand.
But even when two different frameworks are written in the same language, they can vary dramatically based on how well-trodden that path is. At one extreme, a framework is called "opinionated." This means the framework designers have built a “happy path” that makes development easier and faster for people using their framework — as long as they follow specific assumptions. Choosing an opinionated framework can greatly facilitate development of your application, when your needs match or align to the purpose of the framework. The enforced or strict conventions can also make it easier for new developers to join and start providing value right away.
However, it also sometimes means those assumptions are intentionally difficult to violate. This can mean a number of things in practice, from strict or enforced conventions to a lack of extensibility or perhaps restriction to a single toolset. Ultimately, being opinionated means the framework works best as it was originally intended, and varying from it can sometimes only be done with great pain.
Deciding to use an opinionated framework is as much as business decision as it is a technical one. While you may benefit from ease of startup, the decision to use an opinionated framework may come at a future cost if what you need to extend your application exceeds the framework’s capabilities.
To add depth, let’s look at some specific examples of frontend and backend frameworks. We’ll look at Angular vs React and Django vs Flask, but this line of thinking will also apply to other frameworks like Vue, Ruby on Rails, and more.
For the sake of argument, we’ll consider React an un-opinionated framework, whereas Angular is a strongly opinionated one. Both of these frameworks provide the ability to create full-featured single-page web applications and offer rich component libraries plus large user bases.
For comparison purposes, let’s consider how each framework handles data binding. Angular provides two-way data binding out of the box, where React provides one-way data binding. To dive into this more deeply, Angular assumes an MVVM- or MVC-type architecture and provides two-way linkages between your model (where your data lives) and your view (what is rendered on the page). That means when a user changes something on the page, your model is automatically updated. React, on the other hand, forces you to manage this update yourself.
As a strongly opinionated framework, Angular makes assumptions about how you will be providing data to your components and make state available. It provides all the necessary linkages so that all you have to do is declare a variable and use it in the model, without worrying about how the view is updating. This is called data binding, and it’s something Angular does out of the box.
React, on the other hand, does not provide this because you have to explicitly handle change events in your components. In the case of model changes that are not initiated by the UI, you have to explicitly update the state by calling
setState or by using a state hook, which will then automatically ensure that the view is updated. This can result in more code in each component, or even using other libraries such as Redux to help manage state across components — but it also offers a higher degree of customization. React is also lighter weight than Angular, so if you don’t need all the integrated capabilities of Angular, then React could reduce the data usage and load time for end users, as well as the cognitive burden on developers working on your app.
Angular makes similar assumptions on network connectivity, language choice, and build toolchains, for example. This will save time when you want a fully integrated environment that “just works” without having to consider each component separately.
Ultimately this comes down to a matter of preference. Having a choice made for you can simplify development and send you down a prescriptive path, which can save you a lot of time when rapidly building an application.
All things being equal and assuming you have both Angular- and React-capable developers, if you’re building a rapid application prototype and you don’t want to undergo the headache of setup and initial investment required to build a React application, Angular is a comfortable and easy choice. Using it can help get your application off the ground quickly as fewer decisions have to be made and less code has to be integrated in order to get to a working solution. Build toolsets are also very standardized for Angular, and a large number of create scripts exist for getting projects started quickly.
If on the other hand, you know you’re developing a very customized web/mobile application and you want to have the flexibility to do things in a piecemeal manner in order to create a highly performant and capable web application, React is most certainly a better choice.
Django provides a full-featured experience, including an ORM, admin panel, and a convention-based directory structure for all of your applications. Flask, on the other hand, provides absolute simplicity, a high degree of control, and the ability to follow almost any architectural path you’d like. It’s also lighter weight than Django because it integrates fewer features.
Both frameworks run on WSGI and offer templating out of the box.
You’ll want to use Django over Flask when you’re building a fairly standard web application or service, such as a news site, organizational website, e-commerce website, or perhaps a blog. Django provides a ton of examples, starter apps, and an easy and well-trodden path for you to follow.
If you’re creating a product with very minimal needs, like a small internal API — or if you need to select specific components, such as custom authentication or data layer access — then Flask is a better choice. It lets you pick and choose components at every stage of your product architecture. It’s also a better choice if you’re building something entirely custom and you don’t have a common functional and architectural path to follow. Flask allows you to be more flexible when making decisions and doesn’t force you down a predefined path.
Frameworks can be opinionated. And so can the pieces of your infrastructure. If you ask yourself how opinionated your deployment platform is, the difference between PaaS and IaaS becomes a lot more evident.
PaaS offerings give you a turnkey environment on which to build your apps where network considerations, infrastructure configuration, compute, and storage are all managed for you. In our analogue, PaaS is the opinionated framework, making many of the deployment and runtime architecture assumptions for you. Heroku and Elastic Beanstalk are examples of PaaS platforms. What you gain with PaaS is a cost-effective, easily scalable, managed platform that lets you focus on building and deploying your application.
Conversely, IaaS frameworks are relatively unopinionated, providing a flexible infrastructure that you can easily customize, provision and deploy. Although the datacenter and server infrastructure is managed, you have to specifically consider and address sizing, capacity planning, infrastructure support, service integration, and application architecture. Microsoft Azure, AWS, and GCP all offer IaaS. IaaS is a great choice when flexibility is a necessity or when an application needs:
- A specific OS
- A dedicated, non-shared compute environment
- Resources deployed in a virtual network
- A deployment environment not covered by traditional PaaS offerings
Simply put, use PaaS when you want to build your product quickly without reinventing the wheel, and choose IaaS when you have custom or non-standard needs.
Chances are PaaS will work for the majority of use cases, and will save you from wasting your time managing and troubleshooting layers of your stack that you wish would just work. Heroku is a more established PaaS product that scales with your application and offers a variety of platform options, so that you don’t get trapped by early architectural or language decisions. It uses design patterns like the twelve-factor app to help you build a scalable and maintainable application and avoid making unintentional mistakes. And if you ever hit the limits of the platform, they make it easy to migrate to a less opinionated IaaS, where you’ll have the freedom (and responsibility) to manage more complex parts of your infrastructure.
If you have a clear target and are following a well-trodden development or architectural path, opinionated frameworks can help save you time and money by making applications easier to develop and deploy. An opinionated framework gives you guard rails, tons of starter code, and optimizes your path. But if you know that things will go off path very quickly, then you should consider using a non-opinionated framework out of the gate.
For example, If you want to build a quick UI or you know your UI will use standard components—and you have little to no need to customize or alter the behavior of those components in non-standard ways—then the opinionated framework Angular may be a good choice over React. However, if you need flexibility in your Python web frameworks—or are building a custom product for which Django might not have examples or open source base code—then you may need to consider using the non-opinionated Flask.
Extending the concept of opinionated versus unopinionated to deployment options gives us a handy way to look at PaaS versus IaaS. If you want a turnkey environment, you should consider the opinionated PaaS option like Heroku. For highly customized needs, go with the flexibility of IaaS.