THE DIFF
Open an existing report. File → Save as. The format dropdown at the bottom of the dialog defaults to Power BI Desktop file (.pbix). Change it to Power BI Project (.pbip). Choose a folder. Save.
That's the conversion. No migration wizard, no data loss, no ceremony. Desktop writes the same model and report you already had — just in a different format, one that a text editor can read.
What you get
The folder you saved into now contains this:

The .pbip file is just a pointer — a few lines of JSON that tell Desktop where to find the definition files. Everything meaningful lives inside two subfolders.
definition/ is the model. Inside it: a model.tmdl for top-level settings, a tables/ folder with one file per table, a relationships.tmdl, and a roles/ folder if you have row-level security. Every object in your model is its own file. Nothing is packed together. Nothing is hidden.
report/ is the report layer — visual JSON files, page definitions, the theme. That's a separate conversation.¹
What the files look like
Here is definition/tables/Sales.tmdl — a table file from a real model:
table Sales
lineageTag: 4c2e1a3b-8d5f-4e3a-9c12-1b2d3e4f5a6b
column OrderDate
dataType: dateTime
lineageTag: 8f3d2c1e-4a2b-4c3d-9e1f-2a3b4c5d6e7f
summarizeBy: none
sourceColumn: OrderDate
annotation SummarizationSetBy = Automatic
measure 'Total Revenue' = SUM(Sales[Revenue])
lineageTag: a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d
formatString: "$#,0.##;($#,0.##)"
No XML. No nested tags. Indentation carries the structure — if you've read YAML or Python, the logic is familiar. The table, its columns, and its measures are all in the same file, in the same readable format.
The lineageTag values are GUIDs generated by Desktop — internal tracking IDs used for lineage and natural language queries. Leave them alone. Everything else in the file is readable and editable.
Your DAX expressions are right there, in plain text, without opening Desktop at all. That's what makes this diffable. Change a measure formula, save, and the diff shows exactly one line changed — the formula — with the before and after side by side.
Three lines to Git
With the model in a folder, version control is straightforward:
git init
git add .
git commit -m "Initial PBIP save"
From here, every save in Desktop updates the TMDL files. Every meaningful change — a new measure, a renamed column, a modified relationship — is a potential commit. Who changed what. When. You have a record that does not rely on your memory of what you did last Thursday.
One file stays out of source control: .pbi/localSettings.json. It is machine-specific — local connection overrides, personal preferences — the same category of file as .env. Desktop generates a .gitignore that already excludes it.²
The honest tradeoffs
PBIP is still in preview, and it shows in places. Certain deployment pipeline scenarios behave differently than they do with .pbix files, and the feature set is not yet at parity.³
Desktop will occasionally show a warning on open when it detects that files changed outside the application — which is exactly what Git does. The first time it appears, it is alarming. It is not a problem. It is Desktop telling you it noticed the diff. That is the whole point.
The bigger tradeoff is model hygiene. A model with hardcoded date ranges in a calculated table, or M code that references local file paths, generates noise in your diffs that has nothing to do with meaningful changes. Commit a clean model and the history stays readable. Commit a messy one and you will spend more time parsing Git output than writing DAX.
Where this leaves you
Two files are worth knowing well: model.tmdl for top-level model metadata, and the table files in definition/tables/ for everything else. If something looks wrong and you want to understand it without opening Desktop, those are the files to read.
The format is young. It will change. But the direction is fixed — toward something software teams would recognize as a real development workflow. The developers who get comfortable reading these files now have less catching up to do when the tooling catches up around them.
Next issue: relationships and roles — what they look like in TMDL, where they live in the folder, and what to watch out for when the model gets complicated.
THE DELTA
Direct Lake in OneLake is generally available
Direct Lake on OneLake moved to GA in March 2026. Combined with PBIP, this is the full modern stack: semantic model in version-controlled text files, data in OneLake, queries without import overhead. The setup this issue walks through is the entry point to that architecture.⁴
Visual calculations reached GA — they don't live in TMDL
Visual calculations — running sums, moving averages, percent of parent — are now generally available. Worth knowing for PBIP specifically: they live in the report JSON files, not the model TMDL files. They don't appear in definition/tables/, don't show up in model diffs, and don't travel with the semantic model when it's consumed downstream. If you see a calculation in a report that has no corresponding measure in the TMDL folder, this is probably why.⁵
lineageTags: the GUIDs you will see everywhere
Every table, column, measure, and relationship in TMDL gets a lineageTag — a GUID generated by Desktop for internal lineage tracking and Q&A. They appear in every file, show up in every diff, and look alarming if you haven't seen them before. They are not meaningful to you. Do not edit them. Do not delete them. Treat them like compiler output.
WORTH READING
Power BI Desktop projects overview — The authoritative reference for the PBIP folder structure, what's in preview, and the current known limitations. Worth bookmarking and checking when the feature set changes. (Microsoft Learn)
TMDL language specification — The full syntax reference for every object type in TMDL. Read once to understand the format. Return when you need to know exactly what a property does. (Microsoft Learn)
The PBIP folder is most useful when you understand it before something breaks — not after.
Did you learn something?
Sources
Power BI Desktop projects overview — Microsoft Learn
Power BI Desktop projects Git integration — Microsoft Learn
Power BI Desktop projects — known limitations — Microsoft Learn
Power BI March 2026 update — Direct Lake in OneLake GA — Microsoft Learn
Power BI May 2026 update — Visual calculations GA — Microsoft Learn

