Model-driven apps are the default Dynamics 365 surface. Canvas apps embedded inside model-driven forms are the escape hatch for “we need this to look exactly like this.” Use them deliberately.
What an embedded canvas app actually is
A canvas app rendered in an iframe inside a model-driven form, bound to the parent record’s GUID. The canvas app can read related Dataverse data, call connectors, render arbitrary layouts, and write back to Dataverse. From the user’s perspective it is one form. From the platform’s perspective it is two apps in conversation.
When embedded canvas wins
- Pixel-perfect dashboards inside a form (KPI tiles, gauges, custom layouts the model-driven control library cannot match).
- Connectors not available natively in model-driven (REST connectors, custom connectors to internal APIs).
- Wizard-style data entry where the workflow does not fit the linear model-driven form pattern.
- Embedded chat, image annotation, or other interactive surfaces.
When embedded canvas loses
- Anything that needs to participate in BPFs or business rules. The canvas app is invisible to those systems.
- High-volume entry forms used by hundreds of users daily. The iframe load adds 1-2 seconds per form open.
- Anything that needs to work in offline mode. Canvas apps embedded in model-driven do not honor offline.
Performance is the silent killer
Every embedded canvas app load triggers an iframe initialization, a separate Dataverse connection, and a re-authentication step (cached, but still). On a form with three embedded canvas apps, expect 3-5 seconds of additional load time. Profile before deploying.
The data refresh problem
A canvas app inside a model-driven form does not auto-refresh when the parent form changes. If a user updates a parent field, the embedded canvas reads the old value until it reloads. Solve with App.OnStart re-reading the parent ID and a Refresh() call wired to a parent form event via the canvas SDK.
App.OnStart = Set(parentRec, LookUp(Accounts, accountid = Param("recordid")));
Form_OnSave (parent) -> publish event -> canvas listens -> Refresh(Accounts);
Licensing nuance
Embedded canvas apps consume Power Apps premium licenses if they use premium connectors. Even if the model-driven host is licensed via Dynamics 365, the canvas piece is licensed separately when premium connectors are in play. Verify with your licensing rep before publishing.
Decision rule
- Standard CRUD on Dataverse fields -> Model-driven form.
- Pixel-perfect or connector-heavy -> Embedded canvas.
- High volume -> Model-driven only.
- Offline required -> Model-driven only.
What to do this week
Audit your embedded canvas apps. For each, ask: was this built because model-driven could not do it, or because the developer was more comfortable in canvas? Migrate the latter back to model-driven and recover the load time.