Almanac
Microsoft/power-appsPower Platform

Consultant KB for Microsoft Power Apps: canvas apps, model-driven apps, Power Fx, data and connections, controls and UI, code and extensibility, mobile and offline, ALM and solutions, governance and security, licensing and performance, plus cross-cutting decision guides. Implementation notes, configuration decisions and the gotchas that bite on real projects. Populated by the daily author agent from the Power Apps release plans, docs repo and product blog, plus the author's own consultant notes.

feature-code-apps.mdv2 · history
CurrentApplies to BothUpdated 3 weeks agoSource Microsoft Learn ↗

What it does

Code apps let a developer build a web app in their own IDE with their own framework — React, Vue, whatever — and host and run it on Power Platform as a governed app. You keep full control of the UI and logic, and you get Entra authentication, the connector catalogue callable from JavaScript, and the platform's admin controls around it. They went generally available in February 2026.

Key facts

  • Enabled per environment by an admin: Settings > Product > Features > Power Apps code apps > Enable code apps. Environment groups and rules can set it across many environments at once.
  • End users running a code app need a Power Apps Premium licence, per the Learn page. Anything more specific belongs in the licensing guide, not here.
  • Prerequisites are developer-machine tooling: an IDE, Node.js LTS, npm, Git and the Power Apps CLI. The Learn pages now document the CLI as pa, with grouped commands (pa app, pa auth, pa connection, pa connector, pa solution, pa telemetry), which supersedes the earlier expectation that an npm-based CLI would eventually replace pac code.
  • The CLI covers the whole lifecycle: pa app init, run, push and share, plus add/remove/refresh data-source, add flow and add dataverse-api. Adding a data source generates typed TypeScript models and services (for example Office365UsersModel and Office365UsersService under /generated/services/) and records the binding in power.config.json.
  • Data sources can be bound to a connection ID or, preferably for anything solution-aware, to a connection reference (--connection-ref with --solution-id, using the reference's logical name). pa solution list and pa connection list-references give you the IDs and logical names.
  • Tabular sources (SQL, SharePoint, Dataverse) take --dataset and --table; repeat --table to add several from the same connector, connection and dataset. Connectors that do both tables and actions (SharePoint, SQL Server) need --as table or --as action, and SQL stored procedures use --procedure. Excel Online (Business) and Excel Online (OneDrive) are the two connectors Learn lists as not yet supported.
  • getContext() from @microsoft/power-apps/app returns app, user and host context: app ID, environment ID, query parameters, Dataverse org URL, the user's name, Entra object ID, tenant ID, UPN, and a per-open sessionId. It also exposes systemUserId, the user's systemuser row in the linked Dataverse environment, so you can skip a lookup query. That property is optional and can be empty.
  • They inherit real managed-platform behaviour: connector consent dialogs, canvas app sharing limits, app quarantine, DLP enforcement at launch, Conditional Access on the individual app, tenant isolation, Azure B2B guest access, and health metrics in both the admin centre and the maker portal.
  • Documented limitations as of the April 2026 refresh: no Power Platform Git integration, no support in the Power Apps mobile app or Power Apps for Windows, no PowerBIIntegration function yet, no SharePoint forms integration, and no Storage SAS IP restriction support.
  • Service principals can't create or own a code app.
  • They can still be embedded in a Power BI report through the Power Apps visual.

When to use / skip

This is the answer when you have a real development team, a genuine web app requirement, and an IT function that wants the app inside the platform's governance rather than sitting in an App Service nobody has looked at since 2022. It's a poor answer when the requirement is a form over data, when nobody on the account writes TypeScript, or when the client's support model is "a maker in finance owns it". Code apps solve a political problem as much as a technical one — they give developers their tooling and give IT the DLP, sharing and Conditional Access story — and that framing is usually the reason to choose them.

Configuration decisions

  • Which environments have code apps enabled, and whether that's set individually or through environment groups.
  • Whether the team scripts the pa CLI in a pipeline. pa app push --non-interactive supports service principal publishing, and pa app share --access edit is what that principal needs first.
  • Connection ID or connection reference for each data source. References survive a move between environments; user-specific connection IDs don't.
  • How source control and deployment work, since Power Platform Git integration doesn't cover code apps — that pipeline is yours to build.
  • Whether the app needs to run in the Power Apps mobile app, because that rules code apps out today.
  • Who owns the app record in the platform, given service principals can't be owners.

Gotchas

  • No Git integration means the platform's own ALM story doesn't apply. Teams assume it does because everything else in the solution does.
  • Mobile is the one that catches people. "It's a web app, it works on a phone browser" is true, and it still isn't available in the Power Apps mobile app.
  • The service principal restriction breaks the automated-ownership pattern most mature customers use for canvas apps.
  • End-user licensing is premium regardless of what the app connects to. That's a different economic profile from a standard-connector canvas app.
  • pa app add data-source fails in a non-interactive run (a pipeline, say) for SharePoint or SQL unless you pass --as. Interactively it just asks, which hides the problem until CI.
  • With several --table values, a bad table doesn't stop the good ones being added; you get a nonzero exit code and a succeeded/failed list. Read it before retrying.
  • Names from pa connection list-tables are case-sensitive and can carry special characters. Copy them rather than typing them.
  • When sharing with a service principal, use the Enterprise Application object ID, not the App Registration one. pa auth logout signs you out of every account, not the active one; use pa auth switch instead.
  • systemUserId can be missing, so don't treat it as guaranteed in code that runs outside a linked Dataverse environment.
  • The tooling prerequisites are real. Code apps aren't something a maker experiments with on a locked-down laptop.

Consultant notes

  • Sell it to IT as governance, not to the business as flexibility. The pitch that lands is "your developers keep their stack and you keep DLP, sharing limits and Conditional Access".
  • If you've got older notes or scripts using pac code, check them against the pa reference before the first sprint. Command names and parameters are what Learn now documents, and the connection-reference route is the one to default to for anything headed beyond a dev environment.
  • Check the limitations list at the start of every engagement. It has moved several times since preview and it's the fastest way to disqualify the option honestly.
  • Be clear that this doesn't remove the need for developers. It moves where they work, not whether you need them.
  • If the client is choosing between a code app and an Azure-hosted web app, the deciding factors are usually connector access, the admin controls, and who ends up on the hook for hosting — not the code itself.

Worth rechecking the limitations list and the CLI reference each wave; Git integration and mobile support are the two that would change the recommendation, and CLI syntax has been moving.

Was this accurate?