A maker is given two weeks to ship an app for the operations team to track equipment maintenance. Canvas app feels flexible but every CRUD operation is hand-wired; model-driven app feels rigid but the CRUD comes free. For 80 percent of internal CRM-style apps, model-driven is the right answer and the perceived rigidity is actually a feature that prevents UX drift.
What Model-Driven Apps Are
Component-based apps built on Dataverse tables. Standard UI metaphors: site map to entity to list to form. Dynamics 365 modules are essentially model-driven apps. The framework owns the rendering and the responsive behavior; the maker owns the schema, the layout, and the business logic.
Model-driven components:
- Site map: navigation
- Entity views: lists
- Forms: record editing
- Dashboards: aggregated views
- Charts: visualizations
- Business process flows: stage progression
The components compose; you do not redesign the navigation for each app, you reuse the framework navigation.
Site Map
The navigation structure: areas, groups, subareas. Role-based filtering hides what users should not see. Keep depth shallow — users hate deep menus. The shallow rule is two levels visible at any time; anything deeper, push to a search-based discovery.
Three-level site map:
Area: Operations
Group: Equipment
Subarea: Equipment List
Subarea: Maintenance Schedule
Group: Reports
Subarea: Uptime Dashboard
Role-based filtering ships with the app module. A maintenance technician sees Equipment; a supervisor sees Equipment plus Reports.
Forms
Main forms, quick view forms, card forms. Business Process Flows overlay on main forms to guide stage progression. Keep forms focused; use tabs for grouping. The main form is the most viewed surface; iterate on it like a product.
Form design principles:
- Top section: identity (name, owner, status)
- Tab 1: primary edit fields
- Tab 2: related records (sub-grids)
- Tab 3: history and audit
- Hide rather than show by default; reveal on demand
The hide-by-default discipline keeps the form scannable.
Views
Saved queries on a table. Default views, system views, personal views. Advanced Find creates complex views without code. The default view is the one the user sees most often; tune the columns and filter to match the most common use case, not the edge case.
<fetch>
<entity name="equipment">
<attribute name="name" />
<attribute name="location" />
<attribute name="last_maintenance" />
<attribute name="next_maintenance" />
<filter>
<condition attribute="statecode" operator="eq" value="0" />
</filter>
<order attribute="next_maintenance" />
</entity>
</fetch>
Sort by next_maintenance ascending so the equipment due soon appears first.
When to Use Model-Driven
CRUD-heavy applications with clear entity relationships. Standard UI is acceptable. For custom UX, canvas apps; for hybrid, use model-driven with embedded canvas. The decision filter is whether the user needs to see and edit records most of the time. If yes, model-driven. If the experience is more workflow-driven or wizard-style, canvas.
Model-driven fits:
- Internal data management apps
- CRM and case-tracking style apps
- Any app where the entity relationship diagram matches the workflow
Canvas fits:
- Mobile-first task apps
- Wizard-style onboarding
- Highly custom UX with brand requirements
App Modules and Persona Slimming
A model-driven app is an App Module that exposes a subset of entities, dashboards, and views to a specific persona. A field tech app and a dispatcher app can share the same Dataverse environment but expose entirely different surfaces. Build app modules per persona, not one app for everyone.
Performance Considerations
Forms with many sub-grids and Quick Views load slower. Audit the form network tab; if the load fires more than four parallel requests, consolidate. Sub-grids should default to small page sizes (10 to 25 rows) to keep the initial paint fast.
What to do this week
Build the site map for your top persona, slim down the default view to six columns, and audit the most-used main form for sub-grid count. Ship one persona-specific app module instead of asking that persona to use the catch-all app.