Help us improve
Share bugs, ideas, or general feedback.
From grafana-skills
Refactors Grafana Jsonnet dashboards to eliminate duplication and align with available unified libraries while preserving behavior. Use when dashboards contain duplicated code, inconsistent patterns, legacy panel types, or need standardization with existing conventions. Produces single self-contained files without dashboard-specific libraries.
npx claudepluginhub haomingz/skills --plugin finance-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/grafana-skills:grafana-jsonnet-refactorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Eliminate duplication and align existing Jsonnet dashboards with available unified libraries. Preserve behavior while modernizing legacy panels and standardizing patterns.
Guides technical evaluation of code review feedback: read fully, restate for understanding, verify against codebase, respond with reasoning or pushback before implementing.
Share bugs, ideas, or general feedback.
Eliminate duplication and align existing Jsonnet dashboards with available unified libraries. Preserve behavior while modernizing legacy panels and standardizing patterns.
Not suitable for: Initial JSON to Jsonnet conversion (use grafana-json-to-jsonnet), content optimization (use grafana-dashboard-optimize), or Python report migration (use grafana-report-to-dashboard).
Copy this checklist and track your progress:
Refactor Progress:
- [ ] Step 1: Read refactor-checklist.md and align with conventions
- [ ] Step 2: Audit dashboard (panels, variables, datasources, patterns)
- [ ] Step 3: Choose refactor mode (direct/wrapper/hybrid)
- [ ] Step 4: Normalize config and shared selectors
- [ ] Step 5: Replace panels with unified constructors
- [ ] Step 6: Organize file structure (imports → config → variables/helpers → panels → rows → dashboard)
- [ ] Step 7: Compile and verify in Grafana
Step 1: Read refactor-checklist.md
Load references/refactor-checklist.md to understand local conventions and standards.
If the dashboard belongs to a specific repo or stack, review the local Jsonnet defaults and docs in the working directory (datasource config, time range, variables, panel types).
Step 2: Audit the dashboard
List all panels, variables, datasources, and identify repeated patterns. Note which panels use local helpers vs unified libraries, and whether annotations or dashboard metadata (__inputs, __requires, schemaVersion, graphTooltip, version) are present.
Step 3: Choose refactor mode
Select approach based on dashboard size:
Step 4: Normalize config and shared selectors
Extract common configuration (datasource, pluginVersion, timezone, and time range when present) into a config object.
Step 5: Replace panels with unified constructors
Replace local helpers with panels.*Panel() constructors. Apply standards.* for units/thresholds and themes.* for timeseries styling. Add id and gridPos via panels.withIdAndPatches(...) or + { id, gridPos }.
For styling and table/override patterns, load references/visual-style-guides.md.
Step 6: Organize file structure
Structure the file: imports → config → constants → variables → selectors/helpers → panel wrappers → panels → rows → annotations → dashboard. Keep all panel definitions as local variables in the single file.
Step 7: Compile and verify
Run the repo's build/compile script if available. Fix any errors. Verify panel count and layout match the original dashboard in Grafana.
jsonnetfmt / jsonnet fmt on generated Jsonnet files.standards.*.prom.* helpers where applicable.__inputs / __requires and manual import lines preserved when present.gridPos.y aligns to row gridPos.y, and rows include panels).schemaVersion, graphTooltip, version) preserved when present.local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';
local helpers = import '../lib/helpers.libsonnet';
local layouts = import '../lib/layouts.libsonnet';
local panels = import '../lib/panels.libsonnet';
local prom = import '../lib/prometheus.libsonnet';
local standards = import '../lib/standards.libsonnet';
local themes = import '../lib/themes.libsonnet';
// Provisioning mode (real UID). For manual import, switch to ${DS_*}.
local DATASOURCE_UID = '<prometheus-uid>';
// local DATASOURCE_UID = '${DS_PROMETHEUS}';
local config = {
datasource: { type: 'prometheus', uid: DATASOURCE_UID },
pluginVersion: '12.3.0',
};
local qpsStat = panels.statPanel(
title='QPS',
targets=[prom.instantTarget('sum(rate(http_requests_total[1m]))', '')],
datasource=config.datasource,
unit=standards.units.qps,
pluginVersion=config.pluginVersion
);
g.dashboard.new('Dashboard')
+ g.dashboard.withPanels([qpsStat])
references/visual-style-guides.mdreferences/full-refactor-playbook.mdreferences/refactor-checklist.mdreferences/examples.md