PCF Controls March 20, 2026 8 min read

Building Your First PCF Control:
A Complete 2026 Guide

Everything you need to go from zero to a production-ready PowerApps Component Framework control — TypeScript setup, component lifecycle, testing, and AppSource deployment.

PCF Control development setup in VS Code with TypeScript

What is PCF and Why Should You Care?

PowerApps Component Framework (PCF) lets you build reusable UI components that plug directly into model-driven Power Apps and Dynamics 365. Instead of being stuck with out-of-the-box fields and grids, you can build anything — a rich text editor, a signature pad, an interactive Kanban board — and deploy it as a first-class citizen in D365 forms.

As of 2026, PCF controls are one of the most in-demand skills in the Power Platform ecosystem. Companies that invest in a PCF control library reduce their D365 customization costs significantly and improve user adoption.

Prerequisites: Node.js 18+, npm/yarn, VS Code, and Power Platform CLI installed. A D365 / Power Apps environment with System Customizer or System Administrator role.

1. Set Up Your Dev Environment

Install the Power Platform CLI if you haven't already:

npm install -g @microsoft/powerplatform-cli

Then create your PCF project scaffold:

pac pcf init --namespace LG Autonomous --name MyFirstControl --template field
cd MyFirstControl
npm install

Project Structure

After pac pcf init, you'll have:

PCF project folder structure in VS Code Explorer panel
Folder structure generated by pac pcf init — opened in VS Code Explorer

2. Understanding the Component Lifecycle

PCF controls follow a specific lifecycle that you need to understand to avoid bugs:

  1. init() — Called once. Create your DOM elements, subscribe to events. Don't read property values here — use updateView for that.
  2. updateView() — Called every time bound property values change, or when the container size changes. This is your main "render" method.
  3. getOutputs() — Called when the framework needs your output property values (after notifyOutputChanged).
  4. destroy() — Clean up event listeners, timers, etc.

3. Building a Simple Rating Control

Let's build a 5-star rating field control. Here's the ControlManifest.Input.xml:

<property name="value"
  display-name-key="Rating"
  description-key="Rating_Desc"
  of-type="Whole.None"
  usage="bound"
  required="true" />

And the TypeScript implementation:

export class StarRating
  implements ComponentFramework.StandardControl<IInputs, IOutputs> {

  private _container: HTMLDivElement;
  private _value: number = 0;
  private _onChange: () => void;

  public init(
    context: ComponentFramework.Context<IInputs>,
    notifyOutputChanged: () => void,
  ): void {
    this._onChange = notifyOutputChanged;
    this._container = document.createElement('div');
    this._container.className = 'star-rating';
    this._renderStars();
  }

  public updateView(context: ComponentFramework.Context<IInputs>): void {
    this._value = context.parameters.value.raw ?? 0;
    this._renderStars();
  }

  private _renderStars(): void {
    this._container.innerHTML = '';
    for (let i = 1; i <= 5; i++) {
      const star = document.createElement('span');
      star.textContent = i <= this._value ? '★' : '☆';
      star.className = i <= this._value ? 'star filled' : 'star';
      star.addEventListener('click', () => {
        this._value = i;
        this._onChange();
      });
      this._container.appendChild(star);
    }
  }

  public getOutputs(): IOutputs {
    return { value: this._value };
  }

  public destroy(): void { /* no timers to clear */ }
}

4. Testing in the PCF Harness

Run the local test harness — no D365 environment needed:

npm start watch

This opens a browser with your component rendered in a test harness where you can pass mock data and see live output.

PCF test harness running in browser showing the star rating control
The PCF test harness — live preview of your control without needing a D365 environment

5. Packaging & Deploying to D365

# Build production bundle
npm run build

# Package into a solution
pac solution init --publisher-name LG Autonomous --publisher-prefix nxp
pac solution add-reference --path .

# Deploy to your environment
pac pcf push --publisher-prefix nxp
Tip: Always push to a dev environment first, not production. Use Power Platform ALM pipelines to promote tested solutions.

What's Next?

From here, you can explore React-based PCF controls (much more powerful for complex UIs), virtual controls, dataset controls for grids, and publishing to AppSource. Check out our other article on PCF + React 18 for the next step.

LG
LG Autonomous
Building production PCF controls, Power Platform solutions, and D365 customizations at lgautonomous.com. Get in touch at contact@lgautonomous.com for custom development or product demos.