ripbi
Static analysis, linting, and tree-shaking for Power BI semantic models and DAX.
Docs: bgarcevic.github.io/ripbi.
I created ripbi because I liked Measure Killer, but I was looking for an agent-friendly, free, fast tool to scan semantic models and the connected reports to identify potentially unused semantic model objects. I tested it on a shared semantic model with 14 connected reports, and it's 99% faster than Measure Killer, reducing processing time from almost 4 minutes to a couple of seconds.
It works without opening the reports or semantic models, so it can run as part of a CI pipeline. It's also cross-platform, with no dependency on Power BI Desktop or similar.
It currently works only on local PBIP projects — a TMDL semantic model plus
PBIR reports; .pbix and .pbit files are not supported yet. I plan to
implement guided automated cleanup, a UI, and tenant scanning.
Install
macOS and Linux:
|
Windows (PowerShell):
irm https://raw.githubusercontent.com/bgarcevic/ripbi/main/install.ps1 | iex
Both scripts verify the download against the release's sha256 checksums and
install the binary into ~/.local/bin as both ripbi and its short alias
rib — the two names are the same tool, so rib scan works anywhere
ripbi scan does. Or cargo install ripbi.
Pin a version:
| RIPBI_VERSION=v0.2.1
$env:RIPBI_VERSION = 'v0.2.1'; irm https://raw.githubusercontent.com/bgarcevic/ripbi/main/install.ps1 | iex
Both scripts are plain shell and PowerShell. Download them first if you would rather read before running:
irm https://raw.githubusercontent.com/bgarcevic/ripbi/main/install.ps1 -OutFile install.ps1
powershell -ExecutionPolicy Bypass -File .\install.ps1 # the flag is only needed if your policy blocks script files
From a clone of this repository:
Updating
Installed with one of the scripts above? ripbi update downloads the latest
release, verifies its sha256 checksum, and replaces ripbi and rib in place:
Exit codes: 0 updated or up to date, 1 update available (only from
--check), 2 error (network, checksum, unsupported platform).
Every command checks for a new release at most once a day and prints a dim
one-line notice when one is available. That check is a plain GET of the
public release metadata — no data is sent — and RIPBI_NO_UPDATE_CHECK=1
disables it. It is also skipped automatically when stderr is not a terminal
(pipes, CI logs), when CI is set, or under -q.
Cargo-installed copies are never self-replaced: ripbi update prints the
cargo install ripbi --force command instead. A source build found under a
target/ directory prints the install-script and cargo install --path
alternatives.
On Windows a running executable cannot be deleted, so a completed update may
leave ripbi.exe.old (or rib.exe.old) beside the new binary. It is safe to
delete, and the next update removes it.
Quickstart
Clone the repository to get the sample projects, then scan one:
Output from the committed AdventureWorks sample (trimmed):
130 objects, 74 reachable from 51 roots, 56 unused
Measures (11)
'Sales'[Average Sales per Order]
← nothing references it
Columns (28)
'Customer'[City]
← only used by hierarchy 'Customer'[Geography] — hierarchy level (also unused)
…
The summary line counts the model's objects, how many the reports reach, and how many are unused. Each finding says why it is dead: nothing references it, or its only consumer is itself unused.
ripbi scan discovers the project itself: pass a .pbip file, a project
folder, a .SemanticModel, or a .Report, or nothing to scan the current
directory.
To scan one named model against every report bound to it, pass --model; each
--report folder is searched recursively for reports bound to that model:
Exit codes:
| Code | Meaning |
|---|---|
0 |
Nothing unused |
1 |
Unused objects found |
2 |
Error (bad path, ingestion failure, …) |
Output
The full output contract (human, --summary, --plain, --json, and
ripbi.toml configuration) is documented in the user guide's
scan chapter.
Contributing
Dev setup, workflow, and where things live are documented in CONTRIBUTING.md. The short version — CI is the definition of done, and this is what CI runs:
RUSTDOCFLAGS="-D warnings"
License
Dual-licensed under MIT or Apache-2.0.
The samples/ are Microsoft's own sample projects (MIT) and are not covered by
ripbi's license.