Ever since Microsoft introduced Code Apps, I've been hearing the same question over and over again.
Interestingly, this question doesn't primarily come from seasoned Power Platform architects. More often, it comes from customers and professionals who are relatively new to the platform. And honestly, it's easy to understand why.
Over the last few years, Microsoft and the other players in the AI landscape have invested heavily in showcasing the potential of AI-assisted development. Conference keynotes, launch events, blog posts, demos, and social media are filled with examples of applications generated from prompts, interfaces created in minutes, and developers becoming dramatically more productive thanks to AI.
The message is powerful:
"If AI can generate most of the application for me, and Code Apps give me unlimited flexibility, why would I ever choose a Model-Driven App?"
After spending a significant amount of time working with Code Apps over the last several months, I believe this conclusion is based on a dangerous oversimplification.
Not because Code Apps aren't powerful, they absolutely are.
The problem is that most comparisons focus exclusively on what Code Apps allow you to build, while completely ignoring everything that Model-Driven Apps already provide out of the box, and the costs of rebuilding those, consistently, from scratch.
Please note, from a seasoned architect: that list is much longer than many people realize.
π€ The Problem with Requirements Discussions
One thing I've learned after years of building business applications is that customers rarely describe all of their requirements.
Or better: they describe their business requirements, but not necessarily their platform requirements.
When a customer talks about a new system, they typically focus on processes. They explain how opportunities are managed, how inspections are performed, how tickets are processed, how contracts are approved, or how projects are tracked.
What they almost never do is list all the platform capabilities they want use every single day. Nobody writes requirements like:
- Users must be able to create custom views.
- Users must be able to save the filters they applied on views.
- Users must be able to share views with colleagues.
- Records must be directly linkable through URLs.
- Lookup fields must behave consistently throughout the application.
These capabilities are considered obvious, they're part of the furniture. And yet, the moment they disappear, users immediately notice their absence. This is exactly what often happens when organizations start discussing the migration of an existing Model-Driven App into a fully custom Code App.
πͺ The Custom View Example
Let's take one of the most underrated capabilities of the entire platform: personal views.
If you've worked on a Dynamics 365 or Model-Driven App project for any significant amount of time, you've probably seen users build their own way of working around views. Some create a handful of personal views, others create dozens. Over time, those views become an integral part of their daily routine. They save particular filters, reorder columns, focus on specific subsets of data and, quite often, share those views with colleagues so that entire teams can work from the same perspective.
What makes this interesting is that customers almost never ask for this capability during requirements gathering sessions. They don't because they rarely think of it as a feature. And even, sometimes, when you tell them about that possibility, they seem frightened about the "perceived complexity" of that feature in the hands of a basic user.
The challenge appears when you start imagining what it would take to provide the same experience in a custom Code App.
At first glance it sounds straightforward. After all, we're only talking about filtering and displaying data, right? But as soon as you start digging deeper, you realize that you're not implementing a single screen. You're implementing an entire framework that allows users to define views, persist them, update them, secure them, share them and access them consistently throughout the application.
More importantly, this capability isn't valuable because it exists in one page. Its value comes from the fact that it exists everywhere. Every entity, every list, every search experience and every future area of the application automatically benefits from the same behavior.
This is why I think people often underestimate the true cost of replacing Model-Driven functionality. The conversation usually starts with the assumption that a specific feature can be rebuilt. And that's true. Almost everything can be rebuilt. The question is not whether it can be done. The real question is how much time, design effort, testing effort and long-term maintenance is required before the custom implementation reaches the same level of maturity as the platform feature it is replacing.
π The Lookup Capability We Take For Granted
Another capability that often goes unnoticed is the way Model-Driven Apps handle lookups.
In a Model-Driven App, you define the configuration once. You decide:
- Which view is displayed.
- Which columns can be searched.
- Whether Quick Create should be available.
- Which behaviors should be applied.
From that moment on, every form that references that table automatically inherits the same behavior. The result is remarkable consistency throughout the entire application.
In fact, most of the time you don't even stop to think about it. You create a relationship between two tables, add the lookup to a form, and everything simply works. The search experience, the lookup dialog, the available columns, the Quick Create behavior, the filtering logic: all of it is already there, consistently implemented across the application. You spend exactly zero time designing or developing that experience because the platform has already done the heavy lifting for you.
Now let's be honest: there are situations where this can feel restrictive. A common objection is:
"What if I want different lookup behaviors depending on the form?"
And that's a fair question.
But I think a more important question is:
How often do you actually need that level of customization?
If 80% of your scenarios work perfectly well with standardized behavior, then the platform is already doing an impressive amount of work for you.
And when you truly need something special, you can always extend the experience through PCF controls, Generative Pages, or plain old HTML Web resources.
The alternative is rebuilding every lookup experience manually: every form, every search dialog, every filter, every Quick Create experience, every future enhancement.
And perhaps most importantly, you're now responsible for ensuring that all of those implementations remain consistent over time. That's not always easy, especially when multiple developers are involved or when AI-generated code is produced through many separate iterations.
π€ AI Generates Features. It Doesn't Automatically Generate Consistency.
This is a point that I think deserves more attention.
A lot of the enthusiasm around Code Apps comes from the incredible productivity gains enabled by AI. And, once again, that enthusiasm is justified.
AI can help generate pages, forms, grids, business logic. What AI does not automatically provide is a coherent platform architecture.
It doesn't guarantee that five developers working on five different features will implement the same behavior, that a lookup will behave consistently throughout the application, that security patterns remain aligned everywhere.
Model-Driven Apps provide many of these guarantees by design, and that's a value proposition that is often ignored during migration discussions.
π URL Addressability: Another Hidden Gem
Here's another capability that many organizations don't appreciate until they lose it: in a Model-Driven App, virtually everything is addressable through a URL. Records, views, custom pages.
Want to send a customer record to a colleague, or to include a deep link in an email or a Teams conversation? Copy the link.
Want to open two records on two different browser tabs and compare them? CTRL + Click on the record link and it works, smoothly.
This sounds simple, but it dramatically improves collaboration and navigation.
Achieving equivalent behavior in Code Apps is, as of today, β practically impossible β because of the way the application is hosted and executed within the Power Apps ecosystem. This topic deserves an article of its own... stay tuned.
ππ»ββ‘οΈ Microsoft Has Been Closing the Gap for Years
There's another aspect of this discussion that I think is often overlooked, and it's the assumption that Model-Driven Apps have somehow remained unchanged while the rest of the Power Platform ecosystem evolved around them.
In my experience, many of the arguments that are commonly used against Model-Driven Apps today are based on limitations that certainly existed a few years ago, but that have gradually become less relevant as Microsoft continued investing in the platform.
If your mental picture of a Model-Driven App is the one you had five or six years ago, then I can understand why Code Apps may look like the obvious answer. Back then, the gap between what you could achieve through standard platform capabilities and what required custom development was much wider. Today, however, the situation is very different.
Over the years Microsoft has continuously expanded the extensibility model of the platform. PCF controls gave developers the ability to replace standard experiences with fully custom components whenever necessary. Custom Pages introduced the possibility of creating tailored user experiences while remaining inside the Model-Driven application shell. More recently, Generative Pages have pushed that flexibility even further, enabling entirely new interaction patterns that only a last year would have required to write complex HTML Web Resources.
And all of those features benefits of the same AI-driven development techniques you will leverage when creating Code Apps.
What makes this evolution particularly interesting is that organizations are no longer forced to choose between a highly standardized application and a fully custom one. In many scenarios, it is now possible to keep all the platform capabilities that make Model-Driven Apps so productive, while selectively customizing the parts of the experience that genuinely need a different approach.
This is why I believe the discussion should not be framed as a binary choice between flexibility and productivity. Increasingly, the most successful solutions are those that leverage both: they take advantage of the enormous amount of functionality provided by the platform and reserve custom development for the areas where it actually creates business value.
βοΈ So, Should You Migrate a Model-Driven App to a Code App?
The answer is, as always, "it depends".
There are absolutely scenarios where migrating makes sense. For example:
- When the application requires a highly specialized user experience.
- When visual interactions are central to the business process.
- When branding and customer-facing design are strategic requirements.
- When the application behaves more like a digital product than a traditional business application.
- When the amount of custom functionality needed would continuously fight against the Model-Driven paradigm.
In those cases, the additional flexibility may justify the additional effort.
However, if your application is primarily data-centric, process-oriented, and heavily reliant on platform capabilities, then you should carefully evaluate what you're giving up.
Because migrating is not simply a matter of rebuilding forms.
You're replacing years of Microsoft engineering with custom implementations.
Some of those implementations might be easy.
Many of them are not.
π― Conclusion
If there's one thing I'd like readers to take away from this article, it's that the discussion around Code Apps and Model-Driven Apps is often framed in the wrong way.
Too often the conversation starts with a question like "Can a Code App do this?" or "Can we rebuild that feature?" And in most cases the answer is yes. Modern development frameworks are incredibly powerful, AI is making developers more productive than ever, and there are very few things that cannot be recreated with enough time and effort.
But I don't think that's the question organizations should be asking.
The real question is whether rebuilding those capabilities from scratch actually creates value for the business.
Throughout this article I've intentionally focused on features that many people barely notice anymore: personal views, lookup management, URL addressability, and all the other platform services that quietly support users every day. These capabilities rarely appear in requirement documents, rarely become the focus of executive presentations, and rarely generate excitement during demos. Yet they are often deeply embedded in the way people work. But I could have mentioned dozens of features following the same pattern... the article simply would have become too boring to read βΊοΈ.
When teams compare a Code App to a Model-Driven App, they naturally focus on the things they wish they could do. They focus on the limitations. They focus on the areas where additional flexibility would be useful.
What they don't always consider is the amount of functionality they're already receiving from the platform today.
And that's an important distinction.
Because moving from a Model-Driven App to a Code App is not simply a technology decision. In many cases, it's a decision to transfer responsibilities from the platform to the development team. Responsibilities that Microsoft has already spent years refining, testing and maintaining.
There are scenarios where a Code App is clearly the better option. There are business processes that require a highly specialized user experience, applications that behave more like digital products than enterprise systems, and situations where the flexibility of a custom application genuinely outweighs the benefits of the platform.
What I'm arguing is something much simpler: Model-Driven Apps are not obsolete. They are not a legacy approach waiting to be replaced. They remain an extremely powerful option, particularly when the business problem you're solving is fundamentally data-centric and process-oriented.
And perhaps most importantly, they have continued to evolve. The Model-Driven Apps we have today are far more extensible than the ones we had five years ago, which means the gap between standardization and customization is becoming smaller every year.
So before deciding to migrate, I would encourage you to take a step back and ask a different question.
Not:
Can we rebuild this in a Code App?
But rather:
Are we replacing platform limitations, or are we replacing platform capabilities?
Because the answer to that question will usually tell you whether the migration is a strategic investment... or simply an expensive exercise in rebuilding functionality that your users were already getting for free.
Top comments (0)