Skip to content

PCF Controls

Peter McDonald edited this page Aug 14, 2026 · 3 revisions

PCF Controls

Scaffold, build, test and deploy a Power Apps component framework control — including debugging the deployed control on a live form with hot reload, so you edit your code and watch the real form update.

Before you start

You need Why
pac (Power Platform CLI) and Node.js Scaffolding, building and pushing go through pac and the project's local npm tooling (Requirements)
A connected environment For Push, Add to Solution and live-form debugging
Microsoft Edge Only for Debug on live form — the extension drives it to reach the deployed control

1. Create the control

Initialise Project → PCF Control, or + Add Component → PCF Control in an existing repo. Two questions decide the scaffold, and they map straight onto pac pcf init:

Question Options What it means
Template Field / Dataset A field control binds to one column; a dataset control binds to a grid or view
Framework None / React Plain DOM rendering, or React (pac pcf init --framework react)

The result is a standard pac pcf init layout: ControlManifest.Input.xml sits inside a <Constructor>/ folder, and the project root (with package.json and the .pcfproj) is its parent. The commands work from either folder.

2. The card's buttons

Button What it does
Push to {environment} Builds and pushes the control straight into the environment — the quickest loop while developing
Local Build Builds the bundle only; no environment involved
Run harness (hot reload) The PCF test harness in a browser, rebuilding as you edit — no Dataverse needed
Debug on live form (hot) Serves your local bundle to the deployed control on a real form (below)
Refresh Types Regenerates the typings for your manifest's properties after you edit the manifest
Add to Solution Adds the control to your solution so it ships with it
Add service-layer structure (overflow) Adds a service/state scaffold plus snippets, so logic does not accumulate in the control class
Stop live-form debug (overflow) Ends the live-form session and stops its watcher

3. Test it: harness or live form

Run harness (hot reload) renders your control in a browser with mock data and rebuilds on save. Nothing is deployed. Use it for layout, rendering and property behaviour.

Debug on live form (hot) runs your control on a real form with real data, while serving the bundle from your machine — save a file and the form picks up the change. Use it for anything the harness cannot reproduce: form context, related records, security, interaction with other controls.

To use it:

  1. Push the control and add it to a form (once).
  2. Click Debug on live form (hot) and pick the record to open.
  3. Edit your code and save; the form reloads your build.
  4. Click Stop live-form debug when finished — this also stops the file watcher.

It works the same way as the web-resource hot reload, and Web Resources shows what that looks like side by side — your editor on the left, the live form running your local build on the right. The only difference is which bundle is intercepted: cc_<Namespace>.<Constructor>/bundle.js for a control, the library for a web resource.

4. Ship it

  1. Add to Solution — the control becomes part of your solution.
  2. Export/import that solution as usual, or keep a Solutions component in the same repo and pack/deploy from there.

Troubleshooting

"Couldn't find a ControlManifest.Input.xml" — the command ran outside a PCF component. Scaffold one, or select the PCF card in the panel first.

Types do not match the manifest — run Refresh Types after editing ControlManifest.Input.xml.

The live form does not pick up my changes — check that Stop live-form debug has not already been run, that the control really is on the form you are looking at, and that you are looking at the browser the extension launched (it uses its own Edge profile).

A build fails with "'webpack' is not recognized" — the toolchain is a project-local dependency, not a global one. Let the component finish its install/restore (the extension runs it when scaffolding).

See also

Clone this wiki locally