Can You Use PCF Controls in Canvas Apps? Yes, Here Is How

A technical guide for anyone who has read the component framework documentation twice and still cannot tell whether canvas apps are supported: what the answer is, why the docs read the way they do, and the exact sequence that gets a code component onto a canvas screen.

Yes. PCF controls work in canvas apps, and this is a generally available capability rather than a preview. The documentation reads as model-driven only for one reason: the framework has to be switched on per environment before code components appear in Power Apps Studio, and that toggle is off by default for canvas. Turn on Power Apps component framework for canvas apps in the environment settings, import your component inside a solution, then insert it from Add, Get more components, Code. Bind its properties with Power Fx like any other control. A few APIs, notably the Dataverse Web API, do stay model-driven only.

Two notes before the detail. First, the setting names, menu paths, and API availability below reflect the current Microsoft component framework documentation at the time of writing, and Microsoft revises all three. Where a decision depends on an exact API being available, confirm it on the Available for line of that specific API reference page before you design around it, because availability is published per API rather than per app type. Second, custom PowerApps Component Framework development is one of the things Solzet is hired for, by end clients and by Microsoft partners, so what follows is the sequence we actually run rather than a paraphrase of the quickstart.

The answer in three lines

Yes, and it is not a workaround

The Power Apps component framework supports model-driven apps and canvas apps. Both shapes of component work: field components that sit where a single value would go, and dataset components that take a table of records. React components using the shared platform React and Fluent libraries work in canvas apps too. This is supported product behaviour, not a trick.

The environment toggle is why you think it is not supported

The framework is enabled for model-driven apps by default and switched off for canvas apps by default. A system administrator has to turn on Power Apps component framework for canvas apps in each environment. Until somebody does, there is no Code tab in Power Apps Studio, the feature looks absent, and the reasonable conclusion is that canvas apps are not supported. That single default is responsible for most of the confusion.

The real boundary is per API, not per app type

The question is never whether canvas apps support code components. It is whether the specific API your component calls is available there. The Dataverse Web API and the utility methods are model-driven only. Navigation and the device capabilities work in both. Power Fx events and Power Fx default values are canvas only. Custom authentication inside the component is not supported in canvas, and connectors are the supported route instead.

Why the documentation reads as model-driven only

The confusion is real and it has specific causes. None of them is that canvas apps are unsupported. Working through them is usually faster than searching again, because each one explains a particular contradiction you have already run into.

The feature is off by default for canvas and on by default for model-driven

This is the big one. If nobody has enabled Power Apps component framework for canvas apps in your environment, Power Apps Studio simply does not offer code components. Nothing tells you a setting is missing. You follow a tutorial, the Code tab is not there, and you conclude the capability does not exist for canvas. It does. It is switched off.

The documentation lives under the Dataverse developer content

The component framework reference sits inside the Dataverse and model-driven developer documentation, alongside plugins, the Web API, and form scripting. Everything around it is model-driven, the examples are forms and views and dashboards, so the framing reads as model-driven even where the content is not. Canvas guidance exists, but it is one page inside a section that looks like it belongs to something else.

The API reference answers per API, not per platform

Every API reference page carries an Available for line. Land on the Web API page or the utility page while researching, read model-driven apps, and it is a short step to concluding that the whole framework is model-driven. That is the correct answer for those two APIs and the wrong answer for the framework. There is no single yes or no, which is precisely what makes the docs feel contradictory.

Three different things in this ecosystem are called components

A PCF code component is a pro-code control written in TypeScript. A canvas component is a low-code reusable control built inside Power Apps Studio and shared through a component library. A custom page is a canvas-designed page hosted inside a model-driven app. Search results mix all three freely, and answers about one get read as answers about another.

There are two ways to insert one, and the old one is deprecated

Older guides tell you to use Insert, Custom, Import component and upload a file. Microsoft has marked that path deprecated and says it will be removed. The current route is to import the component inside a solution into Dataverse first, then add it from Add, Get more components, Code. Following an old guide gets you into a path that still half works, which is more disorienting than one that fails cleanly.

A lot of the community answers predate canvas support

Canvas support arrived years after the framework itself, so there is a large layer of forum threads and blog posts written when model-driven really was the only host. Those answers were correct when published, they rank well, and nothing on them says otherwise. If a page is answering this question with a flat no, check when it was written.

Power Pages is a genuinely different answer, which muddies the picture

Code components can be used in Power Pages, but React components using the platform libraries are not supported there. So an honest statement about one host does not carry over to the others, and any summary short enough to be memorable ends up being wrong somewhere. Treat host support as three separate questions rather than one.

Adding a code component to a canvas app, step by step

Steps 1 to 5 unblock the environment and produce something shippable. Steps 6 to 10 get it into the app and wired to the rest of the screen. Steps 11 and 12 are the ones that decide whether it survives contact with real users and a second release.

  1. Turn on the component framework for canvas apps in the environment

    Sign in to Power Apps, open Settings, then Admin Center. Select Environments, pick the environment, and open Settings. Expand Product, select Features, turn on Power Apps component framework for canvas apps, and save. You need system administrator privileges. Do this in every environment where makers will build or edit these apps, including development, test, and production, because it is an environment level setting and not a solution component that travels with your import.

  2. Decide whether you need a field component or a dataset component

    A field component replaces a single value: a rating widget, a formatted number entry, a colour picker, a signature pad. A dataset component takes a table of records and renders it: a map, a calendar, a board, a custom grid. This decision drives the manifest, the way the maker binds it in the app, and how much of your code deals with paging and sorting, so make it before you generate the project rather than after.

  3. Generate the project with the Power Platform CLI

    Use pac pcf init with a namespace, a name, and the template that matches the shape you chose, field or dataset. Add the react framework parameter if you want to use the shared platform React and Fluent libraries, which produces a virtual control with a smaller bundle. Standard TypeScript controls and React platform library controls both run in canvas apps, so this is a performance and packaging decision rather than a compatibility one.

  4. Bundle your dependencies instead of loading them at runtime

    A code component should either use the platform React and Fluent libraries or bundle every external library into its own bundle. Do not reach for a script tag or a content delivery network at runtime, and do not use browser web storage such as localStorage or sessionStorage to hold data, because it is neither secure nor reliably available across the clients your app runs on.

  5. Build in release mode and package the component into a solution

    Build the component for production rather than debug. The debug build emits code that the Power Apps solution checker flags, and a development mode bundle is large enough that a big control can trip the web resource size limit on import. Then add the component to a solution project and produce a solution zip, unmanaged for your development environment and managed for anything downstream.

  6. Import the solution into Dataverse and publish

    Import the solution zip into the target environment and publish the customizations. This has to happen before the component can be added to an app, and it is the step that older tutorials skip because they still describe uploading a file straight into the app. Import components only from sources you trust: a code component runs code Microsoft did not write, and inside Power Apps Studio it can reach security tokens, which is why Studio shows a safety warning when you open an app that contains one.

  7. Insert the component into the canvas app

    Open the app in Power Apps Studio. On the left pane select Add, then Get more components. Open the Code tab, select your component, and choose Import. It now appears under Code components on the insert pane, and you add it to a screen like any other control. Ignore the older Insert, Custom, Import component path. Microsoft has deprecated it and will remove it.

  8. Bind the input properties with Power Fx

    Input properties appear in the properties pane and take Power Fx expressions, so they can reference variables, collections, connector calls, theme values, and other controls on the screen. There is no Dataverse column to bind to in a canvas app, so properties declared as bound and properties declared as input both behave as values you set with a formula. If a property you expect is missing from the default Properties tab after a re-import, look on the Advanced tab, and bump the manifest version to bring it back to the default tab.

  9. Bind the dataset through the Items property

    For a dataset component, the primary dataset is exposed in canvas as the Items property, and you point it at any tabular source: a Dataverse table, a collection you built on screen, a SharePoint list, a connector result. If the manifest declares more than one dataset, the additional ones appear with an Items suffix on the dataset name. Column level bindings declared as a property set are configured by the maker on the Advanced tab.

  10. Get values back out with an output property and OnChange

    Declare an output property in the manifest, return it from getOutputs, and call notifyOutputChanged when it changes. In a canvas app that raises the OnChange event on the control, and the value is readable from a formula anywhere on the screen as the control name followed by the property name. This is how a code component talks to the rest of the app: a label, a button, or a Patch call reads the output and reacts, exactly as it would with a standard control.

  11. Make it size and behave like a canvas control

    Canvas screens resize, so call trackContainerResize in init and handle the resize case in updateView rather than measuring once and hoping. Use a Power Fx default value in the manifest where the control should size itself relative to its parent or pick up theme values. If the component benefits from a larger canvas, the full screen mode on the context API is available, and updateView tells you when the app enters and leaves it.

  12. Test on every client the app actually ships to, then version it

    Play the app in the browser and in the Power Apps mobile player, and test the screen at the sizes your users have, because a control that looks correct in Studio at desktop width is not proof of anything. Then version deliberately: every change needs the manifest version bumped, or the platform serves the old bundle. Publish the updated solution first, and remember that Power Apps Studio only offers the component update when the app is closed and reopened, so a maker who never closes the app will keep testing yesterday code.

What differs between canvas and model-driven

The useful question is not whether canvas apps are supported but what changes once you are there. Availability is published per API, so check the Available for line on the specific reference page before you design around any of these.

CapabilityCanvas appsModel-driven apps
Field components and dataset componentsBoth supported. The primary dataset binds through the Items property.Both supported. Field components sit on a column, dataset components on a view or subgrid.
React components using the platform React and Fluent librariesSupported. Same solution, smaller bundle, shared library instance.Supported, including on custom pages.
Dataverse Web API from inside the componentNot available. Pass data in through properties, or use connectors and Power Fx on the app side.Available. The component can read and write Dataverse directly.
Utility methodsNot available.Available.
Navigation methodsAvailable.Available.
Device capabilities such as camera, barcode, and locationAvailable.Available.
Power Fx events raised from the componentAvailable. Makers wire them up with Power Fx.Not the same mechanism. Events are handled in JavaScript.
Power Fx default values in the manifestAvailable, and useful for responsive sizing, sample data, and theme values.Static default values only.
Custom authentication inside the componentNot supported. Use connectors to authenticate and fetch.Handled through the platform rather than by the component.
Browser web storage such as localStorage and sessionStorageShould not be used.Should not be used.
Simple lookup property type in the manifestNot available as a property type.Available.
On-premises environmentsNot supported by the framework at all.Not supported by the framework at all.

Binding properties in a canvas app

This is the part that surprises developers who have only built model-driven controls. The component is the same. The way data reaches it is not.

Bound and input mean the same thing here

In a model-driven app, a bound property attaches the component to a specific column on the form and writes back to it. A canvas app has no form and no column, so the distinction collapses: both bound and input properties surface as control properties that a maker sets with a Power Fx expression. If you have only built model-driven controls, this is the mental model to change first. Data goes in as a formula and comes back out as an output property, in both directions explicitly.

Any Power Fx expression is a legal binding

Because the binding is a formula, an input property can be a variable, a lookup into a collection, a value from a connector, a property of another control on the screen, or a literal. That is a genuinely larger surface than a model-driven binding, and it is what makes code components worth the effort in canvas: the app owns the data plumbing and the component only has to render and interact.

The dataset is Items, and it does not have to be Dataverse

A dataset component in a canvas app takes its records from the Items property, which accepts any tabular source the app can reach. A collection built on screen, a SharePoint list, or a Dataverse table all work. Column level bindings that you declared in the manifest as a property set appear for the maker on the Advanced tab, which is where they choose which column feeds which role in your component.

Outputs are the only way back, so design them deliberately

Return the value from getOutputs and call notifyOutputChanged when it genuinely changes, not on every render. The canvas app reads it as the control name followed by the property name and can act on the OnChange event. A component that exposes one well chosen output, for example the selected record identifier or the current filtered count, is far easier to build a screen around than one that exposes fifteen.

The Advanced tab is where missing properties hide

When a component is re-imported, its properties can remain on the Advanced tab rather than appearing on the default Properties tab. The fix is a manifest version update. This is worth knowing before you spend an afternoon convinced the property never got declared, and it is a specific case of the general rule on this platform: if a change is not showing up, the version did not move.

Using it alongside standard canvas controls

A code component is not an alternative to building a canvas app properly. It is the piece you reach for when standard controls have run out, and it should be surrounded by them.

It is one control on the screen, not a takeover

A code component sits next to galleries, forms, buttons, and labels and participates in the same screen. A gallery can select a record, a variable can carry that selection into the component through an input property, the component can raise a change, and a standard label can display the result. The strongest canvas screens we build use exactly one code component for the part that standard controls cannot do, and standard controls for everything else.

Good candidates are rendering and interaction problems

Charts and visualisations beyond what the built-in ones do, maps with clustering and legends, calendars and schedulers, drag and drop boards, signature capture, rich text editing, and specialised data entry that would otherwise be a screen full of awkward workarounds. These are places where the platform is asking you to fight it and a component ends the fight.

Bad candidates are things a gallery already does

If a gallery with a template, a couple of formulas, and conditional formatting gets there, build that instead. A code component is code that somebody has to own, version, and rebuild when a library goes end of life. We tell clients this before quoting, because a component that exists to avoid learning a Power Fx pattern is a maintenance cost with no ceiling.

Anything needing the Dataverse Web API belongs on the app side

This is the one hard architectural constraint. If your design has the component reading related records or writing back to Dataverse itself, that design does not survive contact with a canvas app. Move the data access into the app with Power Fx and connectors, pass the result in through properties, and take the result back out through outputs. It is a better separation anyway, and it is the version that works in both hosts.

Write the component so it does not care which host it is in

One codebase can serve model-driven forms and canvas screens. Keep the rendering and interaction logic host agnostic, isolate anything that touches an API with restricted availability behind a small adapter, and let the app supply the data. That is how you avoid maintaining two forks of the same control, and it is how we build components for clients who start in one host and end up in both.

If the component you need pulls in a third party JavaScript library, the bundling and lifecycle detail is covered in our guide to integrating third party libraries in a PCF control, and the controls we have already published are on our PCF controls page, free to download.

How Solzet builds components for canvas apps

Custom PCF development is a core part of our Dynamics 365 Customer Engagement and Power Platform delivery, so this is what the work looks like when we do it.

PCF is a core practice, not a side skill

Custom PowerApps Component Framework development is one of the specific things Solzet is hired for, by end clients and by Microsoft partners who need TypeScript and React depth on a Power Platform project. Our published control library is on this site, free to download, and it is the same team and the same standards behind the components we build to order.

We agree the host before we agree the specification

Model-driven form, canvas screen, custom page, or more than one of them, decided up front. It changes which APIs are available, how the maker binds the control, and how much of the data access lives in the component rather than in the app. Discovering this after the control is written is a rewrite, and it is one of the more common reasons a component we are asked to rescue does not work where somebody expected it to.

We build one codebase for both hosts where that is sensible

TypeScript and React with Fluent for visual consistency, the rendering logic kept independent of the host, and anything with restricted availability isolated so it can be supplied by the app instead. Where a client needs the same control on a form and on a canvas screen, that is one component and one maintenance burden rather than two.

We deliver it as a solution with the lifecycle already handled

Managed solution ready to import, versioning that actually moves when the code changes, production builds rather than debug builds, plus source code and documentation so your team can maintain it after we hand over. The version discipline matters more than it sounds: most reports of a code component not updating are a version that did not change.

We work white label for Microsoft partners

A significant share of our PCF work is subcontracted by other Microsoft partners under their brand, under NDA, using their tooling and their repositories. That is a normal engagement shape for us rather than an exception, and it is often how a partner covers a TypeScript gap on one project without hiring for it permanently.

We stay inside Customer Engagement and the Power Platform

Solzet delivers Dynamics 365 Customer Engagement and the Power Platform: Sales, Customer Service, Field Service, and Customer Insights on Dataverse, plus Power Apps, Power Automate, and PCF. We are a specialist rather than a generalist, and we say so rather than claiming the whole Microsoft stack.

Certified engineers in one time zone

We deliver from a single hub in Yerevan, Armenia, at GMT+4, which overlaps Western European hours and reaches into the US morning. Our engineers hold Microsoft certifications including PL-200, PL-400, and PL-600 for the Power Platform.

More detail is on our PCF controls development page, and if you are weighing a specialist team against a freelancer for this kind of work, we compare the two honestly in hiring PCF developers.

Frequently Asked Questions

Can you use PCF controls in Power Apps canvas apps, or is it model-driven only?

You can use them in canvas apps. The Power Apps component framework supports model-driven apps and canvas apps, and both field components and dataset components work in both. The reason so many answers say model-driven only is that the framework is enabled for model-driven apps by default and switched off for canvas apps by default, so a maker who has not had it turned on in their environment sees no sign of the feature at all. A system administrator turns on Power Apps component framework for canvas apps in the environment settings, and the capability appears. The genuine differences are at the API level rather than the platform level: the Dataverse Web API and the utility methods are model-driven only, while navigation, device capabilities, and Power Fx events work in canvas.

Why can I not see the Code tab in Power Apps Studio?

Almost always because the component framework has not been enabled for canvas apps in that environment. A system administrator signs in to Power Apps, opens Settings then Admin Center, selects Environments, chooses the environment, opens Settings, expands Product, selects Features, turns on Power Apps component framework for canvas apps, and saves. Two follow-ups catch people out. It is an environment level setting, so it has to be done separately in development, test, and production rather than travelling with your solution. And the component itself has to be imported into that environment inside a solution and published before it appears in the Code tab, because the Code tab lists what is available in Dataverse rather than letting you upload a file.

Do I need a different codebase for canvas apps and model-driven apps?

No. One component, one manifest, one bundle, and it runs in both if you have written it that way. What has to change is the design. In a model-driven app a component can call the Dataverse Web API and read related data itself. In a canvas app it cannot, so the app supplies the data through input properties and receives results through output properties. If you keep rendering and interaction logic independent of the host and isolate anything with restricted availability, one codebase serves both. If you scatter Web API calls through the component, it works on a form and fails on a canvas screen, which is exactly the situation that produces the belief that canvas apps are not supported.

Can a PCF control in a canvas app call the Dataverse Web API?

No. Dataverse dependent APIs including the Web API are not available to code components in canvas apps. This is the single most important limitation to design around, and it is probably the origin of most of the model-driven only folklore, because a developer who tries it sees the API missing and generalises. The supported approach is to do the data work in the app: use Power Fx and connectors to fetch, filter, and write, pass what the component needs in through properties, and take user selections back out through output properties. Custom authentication inside the component is not supported in canvas either, and connectors are the answer there too.

How do I get a value out of a code component and into my canvas app?

Declare an output property in the manifest, return its current value from getOutputs, and call notifyOutputChanged when the value genuinely changes. In a canvas app that raises the control OnChange event, and the value is readable in any Power Fx formula on the screen as the control name followed by the property name. So a component that lets a user select a record can expose the selected identifier as an output, a label can display it, and a button can Patch with it. Call notifyOutputChanged when something has actually changed rather than on every render, because it drives app side recalculation.

How do I bind a dataset component in a canvas app?

The primary dataset declared in your manifest is exposed to the maker as the Items property, and it accepts any tabular source the app can reach: a Dataverse table, a collection built on screen, a SharePoint list, or a connector result. If the manifest declares more than one dataset, the additional ones appear under their own names with an Items suffix. Column level bindings declared as a property set show up on the Advanced tab of the control properties, which is where the maker maps their columns onto the roles your component expects. Inside the component you read records and columns from the dataset parameter the same way you would in a model-driven app.

Can I use React and Fluent in a canvas app code component?

Yes, and you can use the shared platform libraries rather than packaging your own copies. Create the project with the react framework option, which produces a component whose manifest declares platform library references and a control type of virtual. The React and Fluent libraries are then provided by the platform at runtime, so your bundle is smaller, loading is faster, and the visual result aligns with the Power Apps design system. These components work in canvas apps and in model-driven apps including custom pages. The one host where platform library React components are not supported is Power Pages.

Does adding a code component make my canvas app premium?

It depends on what the component connects to rather than on the fact that it is a code component. Components that reach external services or data directly from the browser rather than through connectors are classified as premium, and a component should declare those domains in the external service usage node of its manifest. An app using such a component becomes premium and its users need Power Apps licences. A component that does not connect to external services, used in an app that otherwise uses standard features, keeps the app standard. Separately, code components in model-driven apps connected to Dataverse require Power Apps licences for end users. Licensing changes, so confirm the current position on the Power Apps pricing page before committing to a plan.

How do I update a code component that is already used in a canvas app?

Change the version in the component manifest. Every change needs a version bump, or Dataverse continues to serve the previous bundle and it looks as though your fix did nothing. Rebuild, repackage, import the updated solution, and publish all customizations. Then reopen the app: Power Apps Studio only prompts to update code components when the app is closed and reopened, and deleting the control from the screen and adding it back does not force an update. A maker who has kept the app open all afternoon will keep seeing the old behaviour and will report the fix as not working.

What is the difference between a code component and a canvas component?

A code component, sometimes called a PCF control, is written in TypeScript by a developer, packaged into a solution, and imported into Dataverse. It can do anything a web technology can do, and it is how you get a map, a chart library, a scheduler, or a signature pad into an app. A canvas component is a low-code reusable control built inside Power Apps Studio out of standard controls and Power Fx, and shared through a component library. Both are useful and they solve different problems. The naming overlap is one of the reasons search results on this topic contradict each other, so it is worth being explicit about which one a given article means before trusting its conclusion.

Tell us what the standard controls will not do

Send us the screen, the data behind it, and which hosts it has to run in. You will get a straight answer on whether a code component is the right tool, what it can and cannot do in a canvas app, and what building it involves. Solzet is a Dynamics 365 Customer Engagement and Power Platform consultancy in Yerevan, Armenia, working with clients and Microsoft partners across Europe and the US.