Skip to content
Data
Skill

/power-bi-custom-visuals

Vibe-code Power BI custom visuals end-to-end: scaffold a TypeScript project, iterate on src/visual.ts and capabilities.json, validate with the Power BI Visuals SDK toolchain, package to .pbiviz, and import into a PBIR report. Invoke this skill whenever the user mentions "custom

From plugin
pbi-cli
43813 skills
Install
$ npx -y skills add MinaSaad1/pbi-cli --skill power-bi-custom-visuals --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/power-bi-custom-visuals

Context preview

The summary Claude sees to decide when to auto-load this skill.

Vibe-code Power BI custom visuals end-to-end: scaffold a TypeScript project, iterate on src/visual.ts and capabilities.json, validate with the Power BI Visuals SDK toolchain, package to .pbiviz, and import into a PBIR report. Invoke this skill whenever the user mentions "custom

SKILL.md

power-bi-custom-visuals.SKILL.md
name: Power BI Custom Visuals
description: >
  Vibe-code Power BI custom visuals end-to-end: scaffold a TypeScript project,
  iterate on src/visual.ts and capabilities.json, validate with the Power BI
  Visuals SDK toolchain, package to .pbiviz, and import into a PBIR report.
  Invoke this skill whenever the user mentions "custom visual", "pbiviz",
  "powerbi-visuals-tools", "IVisual", "build a chart Power BI doesn't have",
  "developer visual", or wants a custom-built visual that the built-in
  Power BI library can't render. NOT for: changing colors / themes
  (use Power BI Themes), adding built-in visuals like bar/line/card/table
  (use Power BI Visuals), or modifying the data model.
tools: pbi-cli, Bash

Power BI Custom Visuals Skill

Build new Power BI custom visuals from natural language using the `powerbi-visuals-tools` SDK. Iteration is agent-driven on TypeScript compile errors; visual correctness is checked once at the end with the user.

This skill produces a `.pbiviz` package and embeds it into a PBIR report via `pbi visual import-custom`. The TypeScript project lives **next to** the `.pbip` folder, never inside it.

Prerequisites

The skill needs **Node.js** on PATH and the `powerbi-visuals-tools` npm package. Both are installed on first run with the user's consent; never silently.

Pinned versions (override via env vars if needed):

  • `powerbi-visuals-tools@^5.6.0` (env: `PBIVIZ_VERSION`)
  • `powerbi-visuals-api@^5.11.0` (pinned in scaffolded `package.json`)

The skill's edit patterns and AGENTS.md crib were written against these versions. Bump deliberately.

First-run prerequisite check

# 1. Probe Node
node --version || true

If `node` is missing, **ask the user**:

> Node.js isn't installed. Custom visual development needs it. Install > now? (yes/no) > > - Windows: `winget install OpenJS.NodeJS.LTS` > - macOS: `brew install node` > - Linux: use your package manager or nvm

If user says yes, run the install command appropriate for their OS and re-probe. If user says no, stop the skill with a clear message.

`pbiviz` itself runs through `npx --yes powerbi-visuals-tools@^5.6.0`, so there's no global install of the CLI itself. The first `npx` invocation will fetch and cache it locally.

Discovery: existing project vs fresh scaffold

The skill's first action is always **discover**, not scaffold.

1. Locate the user's PBIR project (the `.pbip` folder or its `.Report` sibling). 2. Look for sibling directories matching `*-visual/` containing a `pbiviz.json`. 3. Branch:

  • **None found** → fresh scaffold flow (see "Plan-then-code" below).
  • **One found** → load it; jump to edit-validate-package-import loop.
  • **Multiple found** → ask the user which one; do not guess.

This means re-invoking the skill on day 2 picks up where day 1 left off.

Plan-then-code (fresh scaffolds only)

For fresh scaffolds, before touching any code:

1. Read the user's natural-language spec. 2. Output a **5-line plan** stating:

  • Data roles needed (and which is `Grouping` vs `Measure`).
  • Primary render approach (DOM, SVG, D3, canvas, charting lib).
  • Formatting properties to expose in the right pane.
  • npm dependencies beyond the scaffold defaults (justify each one;

see "npm dependency policy" below). 3. **Wait for explicit user OK** before generating code.

The plan exists to foreclose the most expensive failure mode: getting the data role declarations wrong in `capabilities.json` and discovering it 15 turns later. Skipping the plan is **not** an optimization.

For sustained-authoring edits to an **existing** project, skip the plan step and iterate directly.

Scaffold

Working directory: parent of the user's PBIR project (sibling, never inside `.Report` or `.pbip`).

**Naming constraint:** `pbiviz new` rejects names containing anything other than letters and digits. No hyphens, no underscores, no dots. If the user's spec name has those (e.g. "my-gauge-visual"), strip them before scaffolding (e.g. `mygaugevisual`). The friendly displayName in `pbiviz.json` can still carry spaces and punctuation.

# Inside <project-parent>/
npx --yes powerbi-visuals-tools@^5.6.0 new <visualname>
cd <visualname>

Auto-strip the circle-card demo

`pbiviz new` produces a working "circle card" demo. Strip it before handing off to iteration:

1. Open `src/visual.ts`. The constructor and `update()` method contain demo-specific code (creates an `<svg>` with a `<circle>` and `<text>` that displays a number). 2. Replace the `update()` body with a **single comment** like `// TODO: build per spec` and remove the SVG/circle helpers. 3. Open `capabilities.json`. Replace the demo's `dataRoles` (typically `category` and `measure` for the circle demo) with the data roles you planned. Empty the `objects` block; add formatting properties per plan. 4. Open `style/visual.less`. Empty it. 5. Bump `apiVersion` in `pbiviz.json` and `powerbi-visuals-api` in `package.json` to the pinned version above (only if the scaffold doesn't already match).

Fill required `pbiviz.json` metadata

`pbiviz package` strict-validates four fields and **fails to build** if any are missing. The scaffold leaves them blank, so populate them before any package step or you'll waste iteration turns chasing a "not specified" error that has nothing to do with the code:

| Field | Source | |-----------------------|------------------------------------------------| | `visual.description` | One-line summary derived from the user's spec | | `visual.supportUrl` | `"https://example.com"` placeholder (real URL needed for AppSource publish) | | `author.name` | `git config user.name` (run it; fall back to `"pbi-cli user"` if empty) | | `author.email` | `git config user.email` (run it; fall back to `"noreply@example.com"` if empty) |

Do this immediately after auto-stripping the circle-card demo, **on

Read more
Ships withpbi-cli

Power BI CLI - semantic models (.NET TOM) and PBIR reports for token-efficient AI agent usage, built for Claude Code

Get the whole plugin

Other skills on pbi-cli.