User Guide

How to use Power Platform QA — from your first upload to building your own analyzer.

1. What is PPQA?

PPQA (Power Platform QA) is a code-quality tool for Microsoft Power Platform Canvas Apps. You hand it a solution export, and it tells you what is inside, what is broken, and what is dead weight, by reading every Power Fx formula on every control on every screen.

The result is an analysis report: a structured list of findings (unused controls, dead variables, stale references, unreachable screens and so on), each one linked back to the exact file, control, and property where the problem lives.

For makers

Find dead controls and stale references before users do.

For reviewers

Walk through someone else's app with a tree view and an issues panel.

For team leads

Track each app's health over time and enforce house rules with custom checks.

How it works at a glance

Solution .zip / .msapp from Power Apps Web app Upload & explore Pick analyzers, run Analyzer (Node.js) Parse YAML Build reference graph Report Findings linked to controls

2. Core concepts

Three sets of concepts will let you read the rest of this guide comfortably: the solution hierarchy, the analyzer model, and the report.

2.1 Solution hierarchy

A Power Platform solution is a packaged container of one or more apps. PPQA reads the solution and rebuilds the same hierarchy Power Apps Studio shows you:

Solution (.zip) App (Canvas App) Screens Components Controls (with properties) Each property holds a Power Fx formula
  • Solution — the file you upload (.zip or .msapp).
  • App — one Canvas App. A solution can contain several.
  • Screen — a top-level page inside an app.
  • Component — a reusable control definition (header bars, navs, etc.).
  • Control — a button, label, gallery, form, etc. living on a screen or inside a component.
  • Property — a value on a control, very often a Power Fx formula (OnSelect, Visible, Items, …).

2.2 Analyzers, categories, test sets

An analyzer is a single rule that knows how to look for one specific kind of problem (for example "find variables that are written but never read"). PPQA ships with built-in analyzers and lets you add your own.

Category: Dead UI Unused control Unused component Category: Dead state Write-only variable Write-only collection Category: Dead references Stale control reference Unreachable screen Test set: "Pre-release sweep" — picks any analyzers from any category
  • Analyzer — one check, with one config, can be toggled on/off.
  • Category — a label that groups analyzers in the UI (Dead UI, Dead state, …). Categories are visual only; they don't affect what runs.
  • Test set — a named bundle of analyzers you want to run together. When you start an analysis you pick one or more test sets, and PPQA deduplicates and runs the union.

2.3 Reports & issues

Each analysis run produces one report. A report is attached to a specific solution and is timestamped, so you can run the same checks again next week and watch the issue count go down (or up).

A report contains issues. Every issue points at a specific control, property, or formula, and carries a severity, an explanation, and (where possible) a suggested fix. In the explorer these issues show up as small coloured dots that propagate upward through the tree, so you can drill from the file node down to the exact line of Power Fx that triggered it.

3. The basic workflow

1. Upload .zip / .msapp 2. Pick test set or single analyzer 3. Analyze Node.js runs 4. Review Tree + issues 5. Fix & re-run in Power Apps
  1. Export your app from Power Apps as a managed or unmanaged solution .zip (or grab the raw .msapp).
  2. Upload it on the Upload page — drag-and-drop or click to browse.
  3. Click Analyze on the solutions list and choose what to run: a single analyzer, one or more test sets, or all of them.
  4. Open the report — or jump straight into the Solution Explorer and let the issue dots guide you to each problem.
  5. Fix it in Power Apps Studio, re-export, re-upload, re-analyze, and watch the issue count fall.

4. App tour

4.1 Home

The home page is your launch pad. Three large cards take you to the three main areas of the app: Solutions, Reports, and Settings. The User Guide link in the top-right of the navbar is always visible — that's how you got here.

The PPQA home page with Solutions, Reports and Settings cards.
Home page — pick where to go next.

4.2 Solutions

The Solutions page lists every solution file you have uploaded. For each one you get four actions:

ButtonWhat it does
CodeOpens the three-pane Solution Explorer (tree, code, issues).
ReportJumps to the report tab inside the explorer (only shown when at least one analysis has been run).
AnalyzeOpens the run picker so you can choose a test set or single analyzer and start a new run.
DeleteRemoves the solution and all its reports.
Solutions page showing a table of uploaded solutions with Code, Analyze and Delete actions.
Solutions list — one row per uploaded file.

4.3 Upload

Drop a Power Platform solution .zip or a raw .msapp file into the upload zone, or click it to open a file picker. The file is stored on the server under a timestamped name so multiple uploads of the same solution don't overwrite each other.

Upload page with a large dotted drop zone.
Upload page — drag-and-drop or click to browse.
Tip Both managed and unmanaged solution exports work. Unmanaged is usually faster to iterate on because you keep your customisations editable in Power Apps Studio.

4.4 Solution explorer

The explorer is where you spend most of your time. It's a three-pane layout modelled after Power Apps Studio:

Explorer App / Screens / Components Search · Filter · Hide-empty Issue dots propagate up Code viewer Code / Render / Raw / Report tabs Find-in-file (case + regex) Jump-to-line from issues Issues panel Filtered to selection Severity + explanation Click to jump in code
Solution explorer with the explorer tree on the left, the Code/Render/Raw/Report tabs in the centre, and the Issues panel on the right.
Solution Explorer — explorer tree, code viewer, issues panel.

Explorer (left)

  • Search box — filters the tree by label while keeping ancestors visible for context.
  • Eye toggle — hide or show properties that have no formula.
  • Reload — rebuild the tree (useful if you re-uploaded the solution in another tab).
  • Expand/Collapse all — toggle the full tree.
  • Star — expand only the branches that contain issues.
  • ↑ / ↓ — jump between issues across the whole tree.
  • Filter by control type — show only Galleries, Buttons, etc.
  • Issue dots — coloured dots next to a node mean "there is at least one issue under here". Follow the dots downward to find the offending property.

Code viewer (centre)

  • Code tab — the Power Fx for the selected property, syntax-highlighted.
  • Render tab — for screen/component nodes, a basic visual preview of the layout.
  • Raw tab — the underlying YAML, for the Power Apps internals nerds.
  • Report tab — the latest analysis report, rendered inline with filter chips for selecting which analyzer's findings to view.
  • Find — opens a find-in-file bar with case-sensitive and regex options.

Issues panel (right)

Whatever you click in the explorer, the issues panel narrows down to issues that affect that node and everything below it. From an issue you can click straight to the offending line in the code viewer.

4.5 Reports

The Reports page lists every analysis run, newest first, across every solution. It's the easiest place to compare runs over time: each row shows the solution name, the run status, the total controls, the issue count, and the run timestamp.

Reports list table: each row shows a solution name, status, controls counted, issues found, and the date.
Reports list — one row per analysis run.

4.6 Report detail

Click any report to see the full breakdown: a summary card, then each analyzer's findings as a sortable, filterable table. Each finding links back to the control in the solution explorer (use the View Code button at the top to jump there). The Report link button copies a shareable URL to the clipboard.

Detailed analysis report for a Canvas App with a summary card, severity counts, and per-analyzer finding tables.
Report detail — one section per analyzer that found something.

4.7 Settings

Settings is where you tune what runs and how. There are four sub-pages:

Analyzers

The main settings page. Every analyzer is a card grouped by category. Each card has a toggle (enable/disable for runs), a config button (per-analyzer thresholds and column choices), a View Code button (read or edit the analyzer's JavaScript), and for custom analyzers a Delete button. You can drag a card between categories to re-organise.

Settings → Analyzers tab showing analyzer cards grouped by category, each with a toggle and Config / View Code buttons.
Settings › Analyzers — toggle, configure or view code.

Categories

Manage the labels analyzers are grouped under. The Uncategorized category is fixed; everything else is yours to rename, reorder or delete.

Categories settings page showing a list of categories with name and description fields.
Settings › Categories — rename, reorder, delete.

Test sets

A test set is a named bundle of analyzers you want to run as a unit. You might have "Quick check" with two cheap analyzers, and "Pre-release sweep" with everything turned on. When the run picker offers test sets, you can tick more than one and PPQA deduplicates the combined list.

Test sets settings page listing each test set with its analyzer count.
Settings › Test Sets — reusable analyzer bundles.

AI keys

On the second tab of the Analyzers page you can enter API keys for the AI providers used by the analyzer generator. Keys are written into the project's .env file. The provider you designate as default is pre-selected on the Create New Analyzer page.

AI Keys tab on the Settings → Analyzers page showing per-provider API key inputs and model selectors.
Settings › AI Keys — one key per AI provider.

5. Built-in analyzers

PPQA ships with eight static-analysis checks split across three categories. Each one runs from the same shared reference graph built once per analysis, so adding more checks does not multiply the run time.

#AnalyzerCategoryWhat it finds
1Unused controlDead UIA control that nothing references and that has no behaviour of its own.
2Unused componentDead UIA component declared in the solution but never dropped onto a screen.
3Write-only variableDead stateA variable assigned with Set() but never read.
4Write-only collectionDead stateA collection populated with Collect/ClearCollect but never read.
5Stale control referenceDead refsA formula referencing a control that no longer exists (renamed/deleted).
6Stale screen referenceDead refsA Navigate(…) pointing at a screen that doesn't exist.
7Unused named formulaDead refsAn App.Formulas entry no other formula references.
8Unreachable screenDead refsA screen the user can never navigate to from the start screen.

Each finding carries a confidence grade (high, medium, low) which lets you filter out the noise on first read. The full detection logic for every check is documented in docs/analysis-checks-overview.md.

6. Build your own analyzer

The feature that sets PPQA apart: you can describe a check in plain English and have an AI generate the analyzer code for you. The generated analyzer is a normal JavaScript file you can read, edit, and re-run.

  1. Go to Settings › Analyzers and click + Create New Analyzer.
  2. Pick an AI provider and model (configured under the AI Keys tab).
  3. Describe what the analyzer should look for in plain English. Reference the data model and prompt-writing helpers linked from that page.
  4. Generate, review the code, and save. The new analyzer shows up as a card in the chosen category and is ready to be added to a test set.
Create New Analyzer page with provider, model, and a plain-English description field.
Create New Analyzer — describe the rule, generate the code.

Per-analyzer configuration (thresholds, output columns, severity labels) lives behind the cog icon on each analyzer card.

Per-analyzer configuration page showing input fields for thresholds and a list of output columns to enable or hide.
Per-analyzer configuration — tune thresholds and report columns.
Heads-up Custom analyzers are real Node.js code running on your server. Read what the AI generated before saving anything you didn't write yourself, the same way you would for any pull request.

7. Troubleshooting

The analysis is stuck on "running"

The analyzer runs as a background Node process. Check the Status column in the Reports list — if it stays at running for more than a few minutes on a normal solution, look at the server log. For a CLI-style retry, you can run node ppqa.js path/to/solution.zip from the project root and inspect the terminal output directly.

"No issues" after a run, but I expected some

  • Make sure the analyzers you expect to fire are actually enabled on the Settings page.
  • If you used a test set, check that it includes those analyzers.
  • Some checks (e.g. unreachable screens) depend on App.StartScreen — if your app doesn't define one, the first screen is treated as the start.

The explorer says "Loading..." forever

Open your browser's DevTools network tab and refresh: the explorer calls /api/solutions/<id>/files and renders once that responds. A 500 there usually means a corrupt .msapp — try re-exporting from Power Apps Studio.

I'm asked to sign in

Most pages of the app are open. Only the Environments flow (pulling solutions directly from a Power Platform tenant via the Dataverse API) requires a Microsoft sign-in. Use the upload flow instead if you don't want to sign in.


Need more depth? See the project README and docs/analysis-checks-overview.md for the full detection logic of every built-in check.