Microsoft Fabric Apps: what actually changes for reporting, and what you still have to be good at

Eight years of Power BI leaves you with a particular reflex. Somebody describes what they want, and before they finish the sentence you are already translating it into what the canvas will allow. A matrix here, a bookmark there, a custom visual if the budget stretches. You get very good at the translation, and you stop noticing that you are doing it.

Fabric Apps removed the translation step, and the first time I built one I realised how much of my job had quietly been negotiation with a rendering engine.

This is what Fabric Apps is, what it costs, what it refuses to do, and the traps nobody warns you about until you have lost a day to one. It is written from a full build: an operational cockpit over a governed semantic model with write-back, stood up end to end on a synthetic dataset.

What is a Microsoft Fabric App?

A Fabric App is a web application that runs as a managed item inside Microsoft Fabric. You define your data model as TypeScript classes with decorators, and Fabric generates the database tables, a GraphQL API, row-level authorisation rules and a type-safe client from them. Your front end is an ordinary web application in whatever framework you like, hosted alongside the backend.

It is built on an SDK called Rayfin, and keeping the two words straight saves a lot of confusion. Rayfin is the backend-as-a-service. The Fabric App is the item that gets deployed into a workspace.

The part that matters for reporting people: Fabric Apps is not an app builder. It is not a Power Apps competitor. There is no drag and drop designer. It is a backend, plus hosting, plus an identity model, and you bring your own way of writing the front end.

Deploy with npx rayfin up and three child items appear under the app in the portal: a managed SQL database with your schema applied, an authentication service on Entra single sign-on, and your built front end served from OneLake. One endpoint exposes all of it, with a path per service. Every piece is a Fabric item you can see, govern and monitor.

That is the actual pitch, and it is worth stating plainly: not that the backend is easy to write, but that it arrives already inside the estate you already run.

Do you need a Power BI Premium licence?

No. You need a Fabric capacity assigned to the workspace, and a tenant administrator has to enable the Fabric Apps workload. There is no Power BI Premium P SKU in the requirement anywhere, and there is no per-viewer licence attached to the app item itself.

Sharing works by item permission rather than by workspace role. To use a deployed app, somebody needs Run and interact on it, which every workspace member gets by default. Edit lets them deploy and change the schema. Reshare lets them grant access, and it needs the admin role on the workspace. That is the whole distribution model, and it behaves like sharing any other Fabric item.

One caveat, because this is the claim people will quote at you. If your app queries a Power BI semantic model, that model keeps its own rules. A data app reads it through the DAX query API, so viewers need Read and Build on the model, and the standard consumption rules for your capacity size still apply to it. The app item is free of per-user licensing. The semantic model behind it is not automatically so. Check it against your own tenant before you promise anyone a number.

Can you even run it where you are?

Ask this before anything else, because it is the question that ends the conversation fastest and almost nobody thinks to ask it.

Fabric Apps is in preview, and preview features do not land everywhere at once. At the time of writing it is not available in UK South or UK West, which for a UK business is not a footnote. It is also missing from North Europe, Germany West Central, Poland Central, Spain Central, Switzerland West, both Canadian regions, Brazil South, Mexico Central, East US 2, South Central US, West US 3, and a long list across Asia Pacific.

West Europe has it. So do France Central, Norway East, Sweden Central, Switzerland North, Italy North and several US regions.

Your capacity lives in one region and you do not move it casually. Check the region availability page against your own tenant before you plan anything, and check it again in a month, because this list is moving.

What does it cost to run?

Everything bills as Fabric capacity units, on the capacity you already have. There is no separate Azure bill and no new subscription.

Three things consume capacity: the SQL database, for compute on every query and mutation plus its storage; the GraphQL API, charged at ten capacity units per hour of request and response processing time; and OneLake operations for serving and updating the static front end.

Three things do not add a charge of their own: the app hosting service, the authentication service, and running a deployment. Those are Microsoft’s published figures, and they are unusually specific for a preview, which I take as a good sign.

For a small internal app the practical answer is that the app is not what moves your capacity meter. The semantic model queries behind it are.

How is it actually built?

The most important design decision in a data application is one people get wrong constantly, and it is not Fabric-specific. A data app does two things that pull in opposite directions.

Analytics has to be governed. The measures the whole organisation has agreed on must not drift, so they live in the semantic model and the app asks for them by name over DAX. The app never reimplements the arithmetic. Its numbers agree with every report over the same model, permanently, because it is the same measure.

Operational state has to be instant. Somebody changes a status and the screen has to move on the next frame, not on the next refresh. A Direct Lake model reframes on refresh, so it structurally cannot do read after write. That state goes to the managed SQL database, reached over GraphQL.

Get this backwards in either direction and you get one of two failures. Put operational state in the model and the interface feels broken, because a click does nothing visible. Put analytics in the operational store and every number drifts away from the governed truth within a quarter, and that one is very hard to walk back once four screens depend on it.

What about security?

This surprised me most, and it is the strongest argument for the platform.

The app authenticates as the signed-in viewer, using their existing Fabric session and Entra single sign-on. There is no service principal. There is no middle-tier broker. There is no client secret, app key or connection string anywhere in the shipped bundle. First sign-in provisions the user automatically, so there is no sign-up flow to build either. Row-level authorisation is declared on the data model itself and filters on the signed-in user’s claims.

You also cannot turn it off. Fabric refuses to deploy an app with authentication disabled, which is the right default and removes a whole category of accident.

The trade-off is real and you should say it out loud before anyone signs anything: this pattern requires every viewer to have access to the underlying model. If your requirement is the opposite, viewers who must not have model access with the app reading under an application identity, this is the wrong pattern and you want a service principal and an external broker.

Two things worth adding on top, because a data app should be able to prove it cannot leak what it reads:

  • A content security policy restricting outbound connections to Fabric, Power BI and Microsoft login origins. A request to anywhere else does not leave the browser.
  • A build-time guard that fails the build if any non-Fabric external URL appears anywhere in the source. Wired into the prebuild step, so you cannot ship past it without deliberately editing an allowlist. Fail closed, in the build, where it is cheap.

And one thing that is easy to miss: your static front end is served from a public URL. The data behind it is not, but the JavaScript is. Keep secrets and sensitive configuration out of the bundle. That is ordinary web hygiene, and people forget it when the word “Fabric” is in the sentence.

What it will not do

Every one of these is documented, none of them are defects, and four of the six are decisions you cannot cheaply reverse once the model is written. Read them before you scope anything.

The two that catch people hardest:

You cannot point it at an existing database. Fabric Apps manages the schema from your TypeScript models, and the app code is the source of truth. You do not adopt a database that already has a schema. Worse, if somebody changes the deployed schema through the portal or SSMS, the next deployment fails, and renaming a column, changing a type or dropping one is not supported at all. Adding a column is. Keep every schema change in code and this never bites you.

There is no custom SQL. All data access goes through the generated GraphQL API. No stored procedures, no hand-written queries, no clever recursive CTE. If your application needs one, this is the wrong backend, and you should find that out in week one rather than week six.

Two smaller ones with real modelling consequences: every entity takes a single UUID field named id, so composite primary keys are out, and many-to-many is not supported, so you model the join yourself as an explicit entity with two navigation decorators. Both are fine once you know. Both are painful to discover after you have written twenty entities.

Five traps that cost real time

None of these are in a getting started guide, and every one reads like a broken platform until you know the cause. They are written as symptom then fix, so you can match the failure you are staring at.

There is a pattern behind all five, and it is worth internalising before you start: the platform is asynchronous and opinionated, and it fails quietly rather than loudly. Assume every write needs a confirmation read. Never trust a number you did not derive from the source you shipped.

Two more that did not fit and cost just as much:

Direct Lake on SQL forbids calculated columns. Do the computation upstream in your gold build, or express it as a measure. Our model has zero calculated columns by design rather than by accident.

Resist modelling the org chart of your data. The natural shape of most operational data is a hierarchy, and modelling it literally gives you dimension-to-dimension joins, ambiguous filter paths and a relationship you have to deactivate to break a cycle. Denormalising keys down onto the facts is not a compromise, it is the point of a star schema. We finished with twenty-four relationships, every one of them one-to-many and active, and no cycles.

What this actually needs from you

Dimensional modelling, DAX, front end craft including design, platform mechanics, and a security position you can defend. Five things, and the value comes from one person holding all of them rather than from a team holding one each.

This is where I want to be blunt, because the marketing around AI-assisted development implies otherwise.

An agent will write you a working Fabric App. It will not tell you that your snowflake needs to be a star, that a pre-aggregated row hiding in your fact table is why the total is exactly double, or that the reason your model will not deploy is a microsecond timestamp. Those cost hours to find and seconds to fix once you know, and knowing is the job.

The combination in that picture is genuinely uncommon. It is a data person who can write a front end, or a front end person who understands dimensional modelling. Neither is easy to hire, and AI has not changed that. What it changed is how much one person holding that combination can ship, which is a different and much more interesting fact.

When is Fabric Apps the wrong answer?

If you need complex multi-step transactions or stored procedures, this is not the shape for it. If you need an identity provider that is not Entra single sign-on, that is not available after deployment. If your viewers cannot be given access to the underlying model, the whole identity model works against you. If your capacity is in a region that does not have it yet, the question is closed until it does. And if what you actually want is people exploring numbers freely, build a report, because that is what the report canvas is superb at.

There is also no environment management out of the box. Separate development, staging and production means separate workspaces you wire up and keep in step yourself, and rollback means checking out the previous commit and deploying again. Both are workable. Neither is free.

And it is still in preview. That is fine for an internal tool and for a build you can redo. Weigh it more carefully for something a contract depends on.

The short version

Fabric Apps takes the two hardest parts of shipping an internal data application, the backend and the identity model, and makes them a configuration decision. What is left is the modelling, the measures, the interface design, and the judgement about what should be on the screen at all.

Those were always the interesting parts. It is a good trade, as long as you check the region first.

Frequently asked

What is the difference between Fabric Apps and Rayfin? Rayfin is the backend-as-a-service SDK: you define data models in TypeScript and it generates the database, the GraphQL API and the authorisation rules. The Fabric App is the item deployed into a Fabric workspace, and it can include your hosted front end. Running inside Fabric is what gives you the compliance, governance and security model without rebuilding it.

Do viewers need a Power BI Pro licence to open a Fabric App? Not for the app item itself. They need the Run and interact permission on it, and the workspace needs a Fabric capacity. If the app queries a semantic model, that model’s own access rules and your capacity size still determine what is required to consume it, so verify against your own tenant rather than assuming.

Can Fabric Apps use my existing database? No. Fabric Apps manages the database schema from your TypeScript data models, and the app code is the source of truth. You cannot point it at a database that already has a schema of its own.

Can I write custom SQL against it? No. All data access goes through the generated GraphQL API. There is no stored procedure support and no hand-written query path. You can connect to the underlying SQL database directly with the connection string if you need to export data.

Is Fabric Apps a replacement for Power BI reports? No, and treating it as one will cost you. Reports remain the right answer for self-service exploration and for governed distribution to a large audience. Fabric Apps is for the cases needing a tailored interface, faster iteration, or behaviour a report page cannot produce.

Can I use Fabric Apps without an AI coding agent? Yes. Everything is plain TypeScript and a CLI, designed to be readable and hand-written. It is efficient for agents because it is opinionated, so there is little for an agent to explore, but nothing requires one.

Can I put a Fabric App on a custom domain? Not through Fabric today. Deploy the backend to Fabric and host the front end on Azure if you need a custom domain, a CDN or traffic management. For internal distribution the built-in hosting needs nothing outside Fabric.

Sources

Scroll to Top