Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Grafatui is a terminal user interface for Prometheus dashboards. It is designed for fast inspection, SSH sessions, local debugging, and environments where opening a browser-based Grafana instance is inconvenient.

Grafatui reads Prometheus directly and can import Grafana dashboard JSON files. It renders supported panels as terminal charts, tables, gauges, stats, and heatmaps while keeping the workflow keyboard-first.

When Grafatui Fits

Use Grafatui when you want:

  • A lightweight Prometheus dashboard in your terminal.
  • A familiar way to inspect exported Grafana dashboards.
  • Fast startup and low resource usage.
  • A dashboard that works well over SSH.
  • SVG or PNG snapshots of the current TUI view.

Grafatui is not a Grafana server replacement. It does not manage users, alerts, annotations, dashboard editing, plugins, or browser-only visualizations.

Installation

Homebrew

Install Grafatui with Homebrew on macOS or Linux:

brew install fedexist/grafatui/grafatui

Installer Script

Install the latest prebuilt release without requiring Rust:

bash -o pipefail -c 'curl --proto =https --tlsv1.2 -LsSf https://raw.githubusercontent.com/fedexist/grafatui/main/install.sh | bash'

With wget:

bash -o pipefail -c 'wget -O- https://raw.githubusercontent.com/fedexist/grafatui/main/install.sh | bash'

The script supports Linux and macOS on x86_64 and ARM64. It installs to $HOME/.local/bin and never invokes sudo. Make sure that directory is on your PATH.

Set GRAFATUI_INSTALL_DIR to choose another destination:

bash -o pipefail -c 'curl --proto =https --tlsv1.2 -LsSf https://raw.githubusercontent.com/fedexist/grafatui/main/install.sh | GRAFATUI_INSTALL_DIR=/custom/bin bash'

Set GRAFATUI_VERSION to install a specific release. The leading v is optional:

bash -o pipefail -c 'curl --proto =https --tlsv1.2 -LsSf https://raw.githubusercontent.com/fedexist/grafatui/main/install.sh | GRAFATUI_VERSION=v0.1.11 bash'

Every release download is verified against its published SHA-256 checksum manifest. Installation stops if the manifest is unavailable or verification fails.

Reviewing downloaded scripts before running them is recommended:

curl --proto '=https' --tlsv1.2 -LsSf -o install.sh https://raw.githubusercontent.com/fedexist/grafatui/main/install.sh
less install.sh
bash install.sh

From Crates.io

Install the latest published release with Cargo:

cargo install grafatui

Grafatui currently requires Rust 1.88 or newer.

From Source

Clone the repository and install the local checkout:

git clone https://github.com/fedexist/grafatui.git
cd grafatui
cargo install --path .

For development, use cargo run instead:

cargo run -- --prometheus-url http://localhost:9090

Prebuilt Binaries

Prebuilt release assets are published on GitHub Releases for common Linux, macOS, and Windows targets.

Shell Completions

Grafatui can generate shell completions for Bash, Zsh, Fish, PowerShell, and Elvish.

# Bash
source <(grafatui completions bash)

# Zsh
source <(grafatui completions zsh)

# Fish
grafatui completions fish | source

Man Page

Generate a man page from the CLI definition:

grafatui man > grafatui.1

Quick Start

Connect to Prometheus

If Prometheus is already running locally:

grafatui --prometheus-url http://localhost:9090

Point Grafatui at another Prometheus server with the same option:

grafatui --prometheus-url http://prometheus.example.com:9090

Import a Grafana Dashboard

Grafatui imports either a Classic JSON dashboard or an exact dashboard.grafana.app/v2 JSON resource that uses a GridLayout:

grafatui --prometheus-url http://localhost:9090 --grafana-json ./dashboard.json

For advanced V2 dashboards that use rows, tabs, auto-grid, repeat, conditional rendering, nested variables, or library panels, use the Classic export fallback: open Export as code → Advanced options, set Model to Classic, then download or copy the JSON. V1 Resource and Resource YAML files are unsupported. See Grafana Dashboard Import for the full format requirements.

Override dashboard variables with repeated --var options:

grafatui --grafana-json ./dash.json --var job=node --var instance=server-01

Run the Demo

The repository includes a Prometheus demo stack and sample dashboards:

git clone https://github.com/fedexist/grafatui.git
cd grafatui
cd examples/demo && docker-compose up -d && sleep 5 && cd ../..
cargo run -- --grafana-json examples/dashboards/prometheus_demo.json --prometheus-url http://localhost:19090

When finished:

cd examples/demo
docker-compose down -v

Useful First Keys

KeyAction
qQuit
rForce refresh
+ / -Zoom out / in
[ / ]Pan left / right
f / EnterFullscreen selected panel
vInspect values
/Search panels

Configuration

Grafatui can be configured with CLI options, a TOML configuration file, or both. CLI options override values from the configuration file.

Common CLI Options

OptionDescriptionDefault
--prometheus-url <URL>Prometheus server URLhttp://localhost:9090
--grafana-json <FILE>Grafana dashboard JSON filenone
--annotations-file <FILE>Read-only external JSONL point-event filenone
--annotations-command <PROGRAM>Read-only executable annotation providernone
--annotations-command-arg <ARG>Argument for --annotations-command; repeat to preserve ordernone
--annotations-command-timeout <DURATION>Maximum command-provider runtime10s
--validateCheck the Grafana dashboard import and exit without starting the TUIfalse
--strictMake --validate fail when diagnostics contain warningsfalse
--format <FORMAT>Output format for --validate: text or jsontext
--range <DURATION>Time range window, such as 5m, 1h, or 24h5m
--step <DURATION>Query step resolution, such as 5s or 30s5s
--var <KEY=VALUE>Override a dashboard variablenone
--theme <NAME>UI themedefault
--threshold-marker <MARKER>Marker for threshold linesdashed
--autogrid-color <COLOR>Color for automatic graph grid lines and labelsdark-gray
--export-dir <DIR>Directory for exports and recordings./grafatui-exports
--export-format <FORMAT>svg, png, or bothsvg
--record-max-frames <COUNT>Maximum changed frames per recording300
--refresh-rate <MS>Data fetch interval in milliseconds1000
--config <FILE>Configuration file pathnone

Run the full help output with:

grafatui --help

Configuration File

Create grafatui.toml in ~/.config/grafatui/, or pass a custom path with --config.

prometheus_url = "http://localhost:9090"
refresh_rate = 1000
time_range = "1h"
step = "5s"
theme = "dracula"
threshold_marker = "dashed"
export_dir = "./grafatui-exports"
export_format = "svg"
record_max_frames = 300
autogrid = true
autogrid_color = "dark-gray"
grafana_json = "~/.config/grafatui/my-dashboard.json"
annotations_file = "./events.jsonl"

[vars]
job = "node"
instance = "server-01"

External Annotation Sources

Select one read-only annotation source: annotations_file or the nested [annotations_command] table. The two TOML forms conflict. The --annotations-file CLI flag conflicts with every command-source CLI flag; CLI source selection still replaces the complete TOML annotation source.

[annotations_command]
program = "./target/debug/examples/git_annotation_provider"
args = ["."]
timeout = "10s"

program is required; args defaults to an empty list and timeout defaults to 10s. The matching CLI source is:

grafatui \
  --annotations-command ./target/debug/examples/git_annotation_provider \
  --annotations-command-arg=. \
  --annotations-command-timeout 10s

--annotations-command-arg and --annotations-command-timeout require --annotations-command; repeat the argument flag to retain argument order. --annotations-file and --annotations-command cannot be combined. A CLI file or command has whole-source precedence over TOML: it replaces the configured file or complete command configuration rather than merging individual fields.

Themes

Built-in themes include:

  • default
  • dracula
  • monokai
  • solarized-dark
  • solarized-light
  • gruvbox
  • tokyo-night
  • catppuccin

Use a theme from the CLI:

grafatui --theme tokyo-night

External Annotations

Grafatui can overlay read-only, external point events from exactly one source: a JSONL file or a command provider. It never edits or writes either source. External annotations are deliberately separate from Grafana dashboard annotations: Grafatui does not implement Grafana annotation queries, APIs, annotations, or annotations.list.

Enable Annotations

Select exactly one source. For a file source, pass the path on the command line:

grafatui \
  --grafana-json ./dashboard.json \
  --annotations-file ./events.jsonl

Or configure the file source in TOML:

annotations_file = "./events.jsonl"

For a command source, configure an executable that accepts the request protocol below. The command receives no shell interpolation:

[annotations_command]
program = "./target/debug/examples/git_annotation_provider"
args = ["."]
timeout = "10s"

Or select it from the command line:

grafatui \
  --grafana-json ./dashboard.json \
  --annotations-command ./target/debug/examples/git_annotation_provider \
  --annotations-command-arg=.

File and command sources are mutually exclusive. A TOML configuration that sets both is rejected even if the CLI selects a source. A CLI file or command replaces the complete TOML annotation source; it never mixes a CLI program, arguments, or timeout with TOML values. Sources are opt-in and read-only; Grafatui does not create, edit, or otherwise write them.

Command Provider Protocol

Grafatui writes exactly one version-1 request line to the command’s standard input, then closes stdin. The request defines the complete refresh window:

{"version":1,"range":{"from":"2026-08-12T10:00:00Z","to":"2026-08-12T10:05:00Z"}}

range.from and range.to are inclusive UTC RFC 3339 bounds. Grafatui defensively applies its visible-range filtering to the events returned.

The provider writes zero or more existing JSONL events to stdout and diagnostics to stderr. Exit 0 with valid bounded JSONL replaces the complete annotation snapshot; an empty successful stdout clears it. A spawn failure, timeout, nonzero exit, invalid UTF-8 or JSONL, or oversized stdout keeps the last valid snapshot and shows a warning.

The default timeout is 10 seconds. Grafatui accepts at most 10 MiB of stdout and captures at most 64 KiB of stderr. Providers inherit Grafatui’s current directory and environment. Put credentials in that environment or use standard credential tooling; never place secrets in dashboard JSON or command arguments.

The included Git provider is a practical starting point:

cargo build --example git_annotation_provider
printf '%s\n' '{"version":1,"range":{"from":"2026-08-12T10:00:00Z","to":"2026-08-12T10:05:00Z"}}' \
  | ./target/debug/examples/git_annotation_provider .

JSONL Event Format and Targeting

The file contains one JSON object per line. Blank lines are ignored. Each event requires time to be an RFC3339 string with an explicit timezone or offset (numeric timestamps are rejected) and non-empty text. tags is an optional array of non-empty strings.

{"time":"2026-07-23T14:30:00Z","text":"Maintenance window","tags":["maintenance"]}
{"time":"2026-07-23T14:30:00Z","text":"Deployed v2.4","tags":["deploy","production"],"panel_titles":["HTTP Request Rate by Status Code"]}

Omit panel_titles to target all eligible graph and timeseries panels, as in the first event. When panel_titles is present, it must contain one or more non-blank titles and each title is matched exactly and case-sensitively against eligible graph/timeseries panel titles. null, an empty array, and blank titles are validation errors.

If a title occurs on multiple eligible panels, the event fans out to all of them and Grafatui shows one warning for that duplicate title. A title that is missing, or exists only on a non-graph panel, shows one warning and renders no marker for that title. These titles are Grafatui routing labels, not Grafana panel IDs.

Events are ordered by timestamp. Unknown JSON fields are ignored. Times with fractional seconds are accepted, and the full fractional timestamp is used when projecting an event onto the graph even when the space-limited inline timestamp display shows less precision.

Target, Filter, Inspect, and Reload

This walkthrough uses current UTC timestamps so both events fall in the visible 15-minute range. It uses only POSIX shell tools; no jq is required.

First, start the bundled Prometheus demo stack from the repository root:

cd examples/demo && docker-compose up -d && sleep 5 && cd ../..

Then create the annotation file and run Grafatui:

annotation_demo_file=/tmp/grafatui-annotations-demo.jsonl
annotation_demo_time="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"

printf '{"time":"%s","text":"Maintenance window","tags":["maintenance"]}\n' \
  "$annotation_demo_time" > "$annotation_demo_file"
printf '{"time":"%s","text":"API deployed","tags":["deploy","production"],"panel_titles":["HTTP Request Rate by Status Code"]}\n' \
  "$annotation_demo_time" >> "$annotation_demo_file"

cargo run -- \
  --grafana-json examples/dashboards/prometheus_demo.json \
  --prometheus-url http://localhost:19090 \
  --range 15m \
  --annotations-file "$annotation_demo_file"

Maintenance window appears on every graph/timeseries panel. API deployed appears only on HTTP Request Rate by Status Code. Press t, select deploy with Space, and press Enter; only the targeted deployment remains. Press v, move the cursor to the marker, and press Enter; the selected panel’s cluster list and selected-event detail pane open.

While Grafatui is running, append an event in a second terminal:

annotation_demo_file=/tmp/grafatui-annotations-demo.jsonl
annotation_demo_time="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
printf '{"time":"%s","text":"Rollback started","tags":["rollback","production"],"panel_titles":["HTTP Request Rate by Status Code"]}\n' \
  "$annotation_demo_time" >> "$annotation_demo_file"

The new event is loaded after the normal refresh; Grafatui does not need to restart. With only deploy selected, Rollback started remains hidden. Press t, then c, and press Enter to apply the cleared filter and reveal the rollback marker. Alternatively, select rollback in the filter and apply it.

Tag Filter and Cluster Controls

Press t to open the global annotation tag filter. It is runtime-only: it is not written to the JSONL source or configuration, and applies to every eligible panel. Selected tags use exact, case-sensitive OR matching: an event remains visible when it has any selected tag. With no selected tags, events with and without tags remain visible. The catalogue keeps a selected tag with a zero event count so it can be removed after a reload.

In the tag filter, use Up/Down or j/k to move, Space to toggle the highlighted tag, c to clear the draft, Enter to apply it, or Esc to cancel without changing the applied filter. In inspection mode, Enter opens only the cluster actually rendered by the selected panel at the cursor. In the cluster, use Up/Down or j/k to select an event, PgUp/PgDn to page, and Enter or Esc to close. Mouse input is ignored while either annotation modal is open.

Cluster contents are frozen when the cluster opens: a later reload can replace the live annotation snapshot without moving rows or changing the cluster’s event details.

Automatic Reload, Rendering, and Exports

Grafatui refreshes both source types during each normal refresh, including while markers are hidden. It checks a file source’s metadata and, when it changes, reads, parses, and validates the full candidate file before atomically replacing the snapshot. A zero-byte file is a valid update that clears all events. Command and Prometheus refreshes share the same time range, start together, and redraw together. Annotation loading is independent of Prometheus: annotation failures never fail startup or a Prometheus refresh.

Only graph and timeseries panels receive annotation markers. Press a to toggle marker visibility. Events that project to the same terminal column are shown as one counted marker: for one event, decimal 29 for two through nine events, and + for 10 or more. In inspection mode, moving the cursor onto that column shows the cluster’s timestamp, text, and tags inline; multi-event details report the exact cluster count.

Applied panel targeting and tag filtering affect the markers in SVG/PNG exports and changed-frame recordings. Active inline annotation details are exportable; the tag-filter and cluster modal chrome is not.

Errors and Last Valid Snapshot

If a file is missing, unreadable, or contains a malformed event, Grafatui keeps rendering the last valid snapshot and shows an annotation warning. Command provider failures follow the same rule. A bad update does not replace the previously loaded events, fail startup, or fail the Prometheus refresh.

CI/CD and Provider Integrations

CI workflow → durable deployment/release record → command provider query
            → normalized JSONL point events → Grafatui overlay

GitHub Actions is a useful concrete pattern: let a workflow record deployment, release, or workflow outcomes in an API, object store, database, or shared event log. A local provider receives Grafatui’s requested range and queries that system of record, then emits normalized JSONL point events. Useful tags include repository, workflow, environment, status, commit, and deployment.

Give the provider credentials through its environment or standard credential tooling, never dashboard JSON or command arguments. A shared JSONL file is a reasonable source only when the workflow and Grafatui genuinely share storage; do not commit an ever-growing event log to the application repository. Vendor-specific providers should normally live as user or community plugins. Built-in integrations remain demand-driven.

Current Limits and Roadmap

This feature supports one external file or command source, point events, panel-title routing, and one global runtime-only tag filter. It has no stable event IDs, no per-panel tag filters, no multiple sources, and no editing. It does not add Grafana annotation-query/API compatibility. Range events, stable event IDs, and per-panel tag filters remain deferred. --validate validates Grafana dashboard imports only; it does not validate annotations.

Grafana Dashboard Import

Grafatui imports supported Grafana dashboard JSON files and renders supported panels in the terminal.

FormatStatusRequirements
Classic JSON✅ SupportedNon-resource object with fields such as title, panels, and templating
V2 Resource JSON🔶 PartialJSON only, exact apiVersion: dashboard.grafana.app/v2, and spec.layout.kind: GridLayout
V1 Resource JSON❌ UnsupportedThe dashboard.grafana.app/v1 resource envelope is not accepted
Resource YAML❌ Unsupported--grafana-json accepts JSON only

The supported V2 subset maps inline Panel elements, Prometheus PanelQuery queries, top-level variables, timeSettings.autoRefresh, supported field configuration, and fixed-grid positions to the same Grafatui behavior as Classic JSON.

V2 layouts other than GridLayout (including Rows, Tabs, and Auto-grid) are fatal import errors. Repeated grid items are also rejected rather than silently changing the dashboard.

Export From Grafana

  1. Open the dashboard in Grafana.
  2. In the toolbar, open Export and select Export as code.
  3. Expand Advanced options.
  4. Set Model to Classic.
  5. Download the file, or copy the JSON into a local .json file.
  6. Run Grafatui with --grafana-json.
grafatui --prometheus-url http://localhost:9090 --grafana-json ./node-exporter.json

Grafana 13 defaults to the V2 Resource model. Its fixed-grid JSON resources can be imported directly. For advanced V2 dashboards, use this Classic export path as the fallback. Grafana documents the available models and export controls in Export a dashboard as code.

Supported Panel Types

Grafatui currently supports:

  • graph
  • timeseries
  • stat
  • gauge
  • bargauge
  • table
  • heatmap

Row panels are traversed so nested panels can be imported, but row headers and collapsed row behavior are not rendered.

Variables

Grafatui reads dashboard variables from templating.list and expands $var and ${var} in PromQL expressions.

Defaults come from the dashboard JSON. Override them from the CLI:

grafatui --grafana-json ./dash.json --var job=node --var instance=server-01

Prometheus query variables such as label_values(up, instance) and query_result(...) are resolved before panel queries run.

Import Diagnostics

Grafatui prints import warnings before starting the TUI when a dashboard uses important Grafana features that are skipped or ignored. Diagnostics include unsupported panel types, value mappings, reduce options, unresolved variables, unsupported V2 datasources, and unsupported variable modifiers such as ${var:regex}. V2 diagnostics retain their spec.* source paths.

Run a non-interactive check with:

grafatui --validate --grafana-json ./dash.json

Warnings do not make validation fail. A dashboard that can be parsed and imported exits successfully even if diagnostics are printed.

Use --strict to make warnings fail validation, or --format json to emit a machine-readable summary. Fatal V2 layout and repeat errors fail validation in all modes; --strict additionally fails when import diagnostics are present:

grafatui --validate --strict --grafana-json ./dash.json
grafatui --validate --format json --grafana-json ./dash.json

Hidden Targets

Grafatui honors targets[].hide by skipping hidden targets during import. Panels with a mix of hidden and visible targets render only the visible target queries.

Query Modes

Grafatui honors targets[].instant from Grafana dashboard JSON. Targets marked as instant use the Prometheus instant query endpoint, while range targets use query_range.

If a target does not specify instant, Gauge, Bar Gauge, and Table panels default to instant queries. Graph, Timeseries, Stat, and Heatmap panels default to range queries.

Field Configuration

Grafatui applies selected fieldConfig.defaults values where they map cleanly to terminal rendering:

  • min and max set explicit Graph y-axis bounds and Gauge limits.
  • thresholds render graph threshold lines and drive dynamic coloring for Stat, Gauge, and Bar Gauge panels.
  • unit, decimals, and noValue affect supported panel values, axes, legends, and exports.
  • custom.axisGridShow controls per-panel graph guide lines.

Built-In PromQL Variables

Grafatui expands the following Grafana-style variables:

  • $__interval
  • $__interval_ms
  • $__range
  • $__range_s
  • $__range_ms
  • $__rate_interval
  • $__rate_interval_ms

Compatibility Details

See the Grafana compatibility matrix for field-by-field support details.

Exporting and Recording

Grafatui can export the current dashboard view as SVG, PNG, or both. It can also record changed dashboard states into a timestamped frame bundle.

Export a Snapshot

Press e to export the current visible dashboard.

Output files are written under --export-dir:

grafatui --export-dir ./grafatui-exports --export-format both

Supported formats:

  • svg
  • png
  • both

Record Changed Frames

Press Ctrl+E to start recording. Press Ctrl+E again, or quit with q, to finalize the bundle.

Grafatui records only changed rendered states:

grafatui-recording-<timestamp>/
  frame-000001.svg
  frame-000002.svg
  manifest.json

If --export-format png or both is selected, matching PNG files are written too.

When external annotations are visible, their panel targeting and applied tag filter affect the markers written to SVG/PNG exports and changed-frame recordings. Any active inline annotation details remain exportable. Annotation modal chrome is omitted from exports and recordings, and draft-only tag-filter edits do not create recording frames; a frame can change after the filter is applied or cleared.

Recording Limits

Limit the number of changed frames in one recording:

grafatui --record-max-frames 300

When the frame cap is reached, Grafatui stops writing new frames and records completed_reason = "capped" when finalized.

Manifest

Each recording writes a manifest.json file with metadata for downstream tooling:

{
  "version": 1,
  "format": "svg",
  "changed_only": true,
  "frame_count": 2,
  "max_frames": 300,
  "completed_reason": "stopped",
  "viewport": { "width": 100, "height": 40 },
  "frames": [
    {
      "index": 1,
      "elapsed_ms": 0,
      "files": ["frame-000001.svg"]
    }
  ]
}

Keyboard and Mouse

Grafatui is designed for keyboard-first dashboard inspection.

Keyboard Controls

KeyAction
qQuit
rForce refresh
+ / -Zoom out / in
[ / ]Pan left / right in time
0Reset to live mode
Up / Down or k / jSelect previous or next panel
PgUp / PgDnScroll vertically, or select panels in fullscreen
Home / EndJump to top or bottom
yToggle Y-axis mode
gToggle autogrid guide lines
aToggle external annotation markers
tOpen the global annotation tag filter
1 through 9Toggle series visibility
f / EnterToggle fullscreen mode
vToggle value inspection mode
Enter in inspect modeOpen the selected panel’s annotation cluster at the cursor
eExport current view
Ctrl+EStart or stop changed-frame recording
/Search panels
Left / RightMove cursor in inspect mode
?Toggle debug info

Mouse Support

ActionBehavior
ClickSelect a panel, or move the cursor in fullscreen inspect mode
DragMove the cursor in fullscreen inspect mode
ScrollScroll the dashboard vertically

In normal mode, clicking selects panels. Press v or f to use cursor-focused interactions.

Annotation Modals

The global tag filter opens with t. Use Up/Down or k/j to move, Space to toggle the highlighted tag, c to clear the draft, Enter to apply it, or Esc to discard it. In an annotation cluster, use Up/Down or k/j to select an event, PgUp/PgDn to page, and Enter or Esc to close it. Mouse input is ignored while either annotation modal is open.

Examples

The repository includes example Grafana dashboards and a local demo environment.

Demo Stack

Start Prometheus, node-exporter, and mock vLLM metrics:

cd examples/demo
docker-compose up -d

Run Grafatui from the repository root:

cargo run -- --grafana-json examples/dashboards/prometheus_demo.json --prometheus-url http://localhost:19090

Stop the demo:

cd examples/demo
docker-compose down -v

Included Dashboards

  • examples/dashboards/prometheus_demo.json: recommended first demo for the bundled Prometheus stack.

  • examples/dashboards/all_visualizations.json: compact dashboard showing the supported visualization types, including timeseries bars, area fill, point mode, and hidden-axis examples.

  • examples/dashboards/instant_queries.json: demonstrates explicit instant targets and the default instant behavior for summary panels.

  • examples/dashboards/thresholds_demo.json: demonstrates thresholds, field bounds, and threshold marker rendering.

  • examples/dashboards/grafana_v2_compatibility.json: exact Grafana V2 resource with a GridLayout, a dynamic Prometheus job variable, refresh settings, and two supported panels. Run it with:

    cargo run -- --grafana-json examples/dashboards/grafana_v2_compatibility.json --prometheus-url http://localhost:19090
    
  • examples/demo/vllm/grafana.json: vLLM-oriented dashboard for the mock demo services.

More Detail

See the repository example docs:

Grafana Dashboard JSON Compatibility

This document provides a comprehensive feature-parity table between the Grafana dashboard JSON models and what Grafatui currently supports.

Snapshot: Grafatui v0.1.11. The roadmap prioritizes Grafana parity first, then user-visible product value. See the roadmap for milestone slices built from this compatibility ladder.

Legend:

  • Supported — Fully implemented and working
  • 🔶 Partial — Partially implemented or with limitations
  • Not Implemented — Recognized but not yet functional
  • Not Applicable — Cannot be implemented in a TUI context (e.g., browser-only features)

Dashboard Schema Models

Grafatui imports the non-resource Classic JSON model and a fixed-grid subset of the V2 Resource JSON model. In Grafana 13, use Export as code → Advanced options → Model: Classic as the fallback for advanced V2 dashboards. See the dashboard import guide for detailed steps.

ModelStatusNotes
Classic JSON✅ SupportedAccepted by --grafana-json; the remaining tables describe support for its fields
V1 Resource JSON❌ Not ImplementedThe Kubernetes-style dashboard.grafana.app/v1 resource envelope is not accepted
V2 Resource JSON🔶 PartialJSON-only exact dashboard.grafana.app/v2 resources with GridLayout are supported
Resource YAML❌ Not Implemented--grafana-json accepts JSON only

V2 Resource JSON Subset

V2 field or behaviorStatusNotes
Exact apiVersion: dashboard.grafana.app/v2✅ SupportedOther resource versions are rejected
spec.layout.kind: GridLayout✅ SupportedGridLayoutItem coordinates map to Grafatui’s fixed 24-column grid
Inline Panel elements✅ SupportedSupported panel visualization groups map through the Classic-equivalent importer
Prometheus PanelQuery queries✅ SupportedNon-Prometheus datasources emit import diagnostics and are skipped
Top-level spec.variables🔶 PartialSupported variable kinds map to Grafatui variables; unsupported kinds emit diagnostics
spec.timeSettings.autoRefresh✅ SupportedUsed as the dashboard refresh interval
vizConfig.spec.fieldConfig🔶 PartialThe supported Classic-equivalent field configuration subset applies
Rows, Tabs, and Auto-grid layouts❌ Not ImplementedRejected as fatal import errors
Repeated grid items❌ Not ImplementedRejected as fatal import errors
Conditional rendering, nested variables, and library panels❌ Not ImplementedDeferred V2 features

Grafana V2 Resource YAML remains unsupported. Use a Classic export for any advanced V2 dashboard outside this fixed-grid subset.


Dashboard-Level Properties

JSON FieldStatusNotes
title✅ SupportedDisplayed in the title bar
uid❌ Not ImplementedNot used (not needed for local JSON import)
id❌ Not ImplementedNot used
version❌ Not ImplementedNot used
tags❌ Not ImplementedIgnored
timezone❌ Not ImplementedAll timestamps displayed in UTC
editable⛔ Not ApplicableGrafatui is read-only
style⛔ Not ApplicableTUI has its own theme system
schemaVersion❌ Not ImplementedNot validated
refresh✅ SupportedUsed as the default data refresh interval; overridden by config or --refresh-rate
time❌ Not ImplementedUses --range CLI option instead
time.from / time.to❌ Not ImplementedUses --range CLI option instead
fiscalYearStartMonth⛔ Not Applicable
liveNow❌ Not ImplementedUses 0 key to reset to live instead
weekStart⛔ Not Applicable

Panels

Panel Types

Panel TypeStatusNotes
graph (legacy)✅ SupportedRendered as a line chart (Braille markers)
timeseries✅ SupportedMapped to graph renderer
stat✅ SupportedBig value + sparkline
gauge✅ SupportedHorizontal gauge bar
bargauge✅ SupportedVertical bar chart
table✅ SupportedTwo-column table (Series, Value)
heatmap✅ SupportedCharacter-based block heatmap
row🔶 PartialRow panels are traversed for nested panels, but row headers/collapse are not rendered
text❌ Not ImplementedSkipped during import
dashlist❌ Not ImplementedSkipped during import
alertlist❌ Not ImplementedSkipped during import
news⛔ Not Applicable
annolist❌ Not Implemented
barchart❌ Not ImplementedSkipped (distinct from bargauge)
candlestick❌ Not Implemented
canvas⛔ Not ApplicableInteractive canvas not feasible in TUI
datagrid❌ Not Implemented
debug⛔ Not Applicable
geomap⛔ Not ApplicableMap visualization not feasible in TUI
histogram❌ Not Implemented
logs❌ Not Implemented
nodeGraph⛔ Not Applicable
piechart❌ Not Implemented
state-timeline❌ Not Implemented
status-history❌ Not Implemented
trend❌ Not Implemented
xychart❌ Not Implemented

Graph & Timeseries Parity

FeatureJSON FieldBehaviorGrafanaGrafatui
Draw stylesfieldConfig.defaults.custom.drawStyleLine, points, and bars map to terminal graph styles🟡
Point displayfieldConfig.defaults.custom.showPointsalways overlays visible point markers; never suppresses area/line point markers🟡🔶
Area fillfieldConfig.defaults.custom.fillOpacityNonzero fill opacity renders terminal/SVG area fill behind the line🟡🔶
StackingfieldConfig.defaults.custom.stackingParsed and retained; non-off modes render non-stacked in this slice🟡🔶
Axis placementfieldConfig.defaults.custom.axisPlacementhidden suppresses y-axis labels; left/right map to the terminal y-axis🟡🔶
Axis gridfieldConfig.defaults.custom.axisGridShowControls per-panel autogrid guide lines🟡
Threshold stylefieldConfig.defaults.custom.thresholdsStyleDashed/line style is parsed for graph threshold rendering🟡🔶

Panel Common Fields

JSON FieldStatusNotes
title✅ SupportedDisplayed as the panel border title
type✅ SupportedUsed to select the renderer
gridPos✅ Supported24-column grid layout fully supported
gridPos.x✅ Supported
gridPos.y✅ Supported
gridPos.w✅ Supported
gridPos.h✅ Supported
id❌ Not ImplementedNot used
description❌ Not ImplementedNot displayed
transparent⛔ Not ApplicableTUI panels always have borders
links⛔ Not ApplicableNo browser navigation
repeat❌ Not ImplementedTemplate repeat not supported
repeatDirection❌ Not Implemented
maxPerRow❌ Not Implemented
collapsed (row)❌ Not ImplementedRows are always expanded
panels (nested in row)✅ SupportedNested panels are extracted recursively

Targets (Queries)

JSON FieldStatusNotes
targets (array)✅ SupportedMultiple targets per panel supported
targets[].expr✅ SupportedPromQL expression
targets[].legendFormat✅ Supported{{label}} syntax for legend formatting
targets[].refId❌ Not ImplementedNot used
targets[].datasource❌ Not ImplementedOnly Prometheus datasource is supported
targets[].interval❌ Not ImplementedUses global --step instead
targets[].intervalFactor❌ Not Implemented
targets[].instant✅ SupportedUses Prometheus instant query when true; Gauge, BarGauge, and Table default to instant
targets[].format❌ Not ImplementedAlways treated as time_series
targets[].hide✅ SupportedHidden targets are skipped during import
targets[].exemplar❌ Not Implemented
targets[].editorMode⛔ Not ApplicableUI-only setting

PromQL Special Variables

VariableStatusNotes
$__rate_interval✅ SupportedComputed as max(step × 4, 60s)
$__rate_interval_ms✅ SupportedMillisecond form of $__rate_interval
$__interval✅ SupportedComputed from the current range and panel resolution, bounded by --step
$__interval_ms✅ SupportedMillisecond form of $__interval
$__range✅ SupportedCurrent dashboard time range
$__range_s✅ SupportedCurrent dashboard time range in seconds
$__range_ms✅ SupportedCurrent dashboard time range in milliseconds

Templating (Variables)

JSON FieldStatusNotes
templating.list✅ SupportedVariables extracted from dashboard
templating.list[].name✅ SupportedUsed as $var or ${var} in queries
templating.list[].current.value✅ SupportedUsed as default value
templating.list[].current.text🔶 PartialUsed as fallback if value is missing
templating.list[].allValue✅ SupportedUsed when value is $__all, falls back to .*
templating.list[].type🔶 Partialquery variables are resolved for Prometheus
templating.list[].query🔶 PartialSupports Prometheus label_values(...) and query_result(...)
templating.list[].definition🔶 PartialUsed as a fallback query expression for dynamic query variables
templating.list[].datasource❌ Not Implemented
templating.list[].regex🔶 PartialApplied to dynamic query variable results
templating.list[].sort❌ Not Implemented
templating.list[].multi❌ Not ImplementedMulti-value selection not supported
templating.list[].includeAll❌ Not Implemented
templating.list[].refresh🔶 PartialDynamic variables refresh before panel queries
templating.list[].options❌ Not ImplementedNo dropdown/picker UI
templating.list[].hide❌ Not Implemented
CLI --var KEY=VALUE override✅ SupportedOverrides dashboard defaults from command line
Config file vars override✅ SupportedOverrides via TOML config

Variable Substitution

PatternStatusNotes
$varname✅ SupportedSimple substitution
${varname}✅ SupportedBraced substitution
${varname:regex}❌ Not ImplementedFormat modifiers not supported
${varname:pipe}❌ Not Implemented
${varname:csv}❌ Not Implemented
${varname:json}❌ Not Implemented
${varname:queryparam}❌ Not Implemented
$__all✅ SupportedReplaced with allValue or .*

Field Configuration (fieldConfig)

fieldConfig is partially implemented. Thresholds, explicit min/max bounds, selected display formatting fields, threshold style, and per-panel autogrid settings are parsed; value mappings, display names, and field overrides remain major gaps.

JSON FieldStatusNotes
fieldConfig🔶 PartialParsed for supported defaults/custom fields below
fieldConfig.defaults🔶 PartialParsed for min/max, thresholds, and selected custom fields
fieldConfig.defaults.unit🔶 PartialCommon units such as bytes, bits, seconds, milliseconds, percent, percentunit, ops, request rate, and byte rate are formatted; unknown units fall back to Grafatui’s compact SI formatter
fieldConfig.defaults.min✅ SupportedUsed for Graph y-axis lower bounds, percentage thresholds, and Gauge limits
fieldConfig.defaults.max✅ SupportedUsed for Graph y-axis upper bounds, gauge scaling, and threshold boundaries
fieldConfig.defaults.decimals✅ SupportedControls numeric precision in panel values, graph axes, legends, and exports
fieldConfig.defaults.color❌ Not ImplementedUses theme palette instead
fieldConfig.defaults.mappings❌ Not ImplementedValue mappings not supported; import diagnostics warn when mappings are ignored
fieldConfig.defaults.noValue🔶 PartialUsed for null Stat/Table values and exports; empty panels still show Grafatui’s No data state
fieldConfig.defaults.displayName❌ Not Implemented
fieldConfig.defaults.custom🔶 PartialUsed for graph draw style, fill/points, axis placement, stacking metadata, threshold style, and axis grid visibility
fieldConfig.defaults.custom.lineWidth❌ Not ImplementedTUI limitation
fieldConfig.defaults.custom.fillOpacity🔶 PartialNonzero values enable terminal/SVG area fill; exact browser opacity is approximated
fieldConfig.defaults.custom.pointSize⛔ Not ApplicableTUI points use fixed terminal-cell markers
fieldConfig.defaults.custom.axisLabel❌ Not Implemented
fieldConfig.defaults.custom.axisGridShow✅ SupportedControls per-panel autogrid guide lines for graph/time-series panels
fieldConfig.defaults.custom.thresholdsStyle🔶 Partialmode is parsed for threshold rendering; glyph style is also controlled by Grafatui’s marker setting
fieldConfig.defaults.custom.scaleDistribution❌ Not ImplementedAlways linear
fieldConfig.overrides❌ Not Implemented

Thresholds

JSON FieldStatusNotes
fieldConfig.defaults.thresholds✅ SupportedApplied to Graph limit lines and dynamic coloring for Stat, Gauge & BarGauge
fieldConfig.defaults.thresholds.mode✅ Supported(absolute / percentage)
fieldConfig.defaults.thresholds.steps✅ Supported
fieldConfig.defaults.thresholds.steps[].value✅ SupportedEvaluated mathematically against metric values
fieldConfig.defaults.thresholds.steps[].color✅ SupportedMaps keywords (e.g., green) and hex codes (e.g., #FF0000)

Panel Options (options)

Panel-specific options are not parsed yet. Grafatui currently applies its own compact TUI defaults for legends, stat sparklines, gauges, and inspect-mode tooltips.

JSON FieldStatusNotes
options❌ Not ImplementedPanel-specific options object is ignored
options.legend❌ Not ImplementedGrafatui uses its own compact legend
options.legend.displayMode❌ Not ImplementedAlways shows inline legend
options.legend.placement❌ Not ImplementedAlways bottom
options.legend.calcs❌ Not ImplementedNo calculated legend values (min/max/avg)
options.tooltip❌ Not ImplementedInspect mode serves as tooltip substitute
options.tooltip.mode❌ Not Implemented
options.orientation❌ Not Implemented
options.reduceOptions❌ Not ImplementedStat/Gauge always use last value; import diagnostics warn when reduce options are ignored
options.reduceOptions.calcs❌ Not Implemented
options.reduceOptions.fields❌ Not Implemented
options.textMode❌ Not Implemented
options.colorMode❌ Not Implemented
options.graphMode❌ Not ImplementedStat always shows sparkline

Annotations

JSON FieldStatusNotes
annotations❌ Not ImplementedExternal file/command providers do not implement this Grafana field.
annotations.list❌ Not ImplementedExternal file/command providers do not implement this Grafana field.

Grafatui external file/command JSONL events are a separate, opt-in read-only source. panel_titles is Grafatui’s external-source routing field: it matches eligible graph/timeseries panel titles exactly, not Grafana panel IDs. It does not imply compatibility with Grafana annotation queries, APIs, annotations, or annotations.list.


JSON FieldStatusNotes
options.dataLinks⛔ Not ApplicableNo browser navigation in TUI
transformations❌ Not Implemented
transformations[].id❌ Not Implemented(e.g., organize, merge, reduce)

Alert Rules

JSON FieldStatusNotes
alert❌ Not ImplementedPanel-level alerts
alert.conditions❌ Not Implemented
alert.notifications❌ Not Implemented

Datasource Configuration

FeatureStatusNotes
Prometheus (query_range)✅ SupportedPrimary and only supported datasource
Prometheus (query instant)✅ SupportedUsed for dynamic template variables and instant panel targets
Prometheus labels API✅ SupportedUsed for dynamic variable label_values(...)
Mixed datasource❌ Not Implemented
InfluxDB❌ Not Implemented
Loki❌ Not Implemented
Elasticsearch❌ Not Implemented
Other datasources❌ Not Implemented

Summary Statistics

CategorySupportedPartialNot ImplementedNot Applicable
Dashboard Properties10104
Panel Types71145
Panel Common Fields8062
Targets / Queries3081
PromQL Variables7000
Templating6660
Variable Substitution3050
Field Config46102
Thresholds5000
Panel Options00140
Annotations0020
Data Links / Transforms0021
Alert Rules0030
Datasources3050
Total47138515

Most Requested Missing Features

Based on user feedback, the following missing features are most commonly expected:

  1. Value mappings (fieldConfig.defaults.mappings) — Map numeric values to text labels
  2. Broader unit formatting (fieldConfig.defaults.unit) — Extend the current common-unit subset to more Grafana unit families
  3. Reduce options (options.reduceOptions) — Use min/max/mean/total instead of always using the latest value
  4. Import diagnostics — Warn clearly about skipped panel types and ignored high-impact fields
  5. Additional panel typestext, piechart, histogram, logs

What Grafatui Does Instead

Grafatui provides several TUI-native capabilities that don’t map directly to Grafana JSON features:

Grafatui FeatureDescription
8 color themesdefault, dracula, monokai, solarized-dark, solarized-light, gruvbox, tokyo-night, catppuccin
Keyboard navigationVim-style (j/k), arrow keys, page up/down
Panel search/ opens a fuzzy-search popup
Fullscreen modef to focus on a single panel
Inspect modev enables cursor-based point-in-time inspection
Y-axis toggley switches between auto-scale and zero-based
Series toggling19 to show/hide individual series
Autogrid toggleg toggles automatic guide lines
Mouse supportClick to select, scroll to navigate, drag cursor in fullscreen
Smart cachingRequest deduplication and caching for identical queries
Client-side downsamplingMax-pooling to ~200 points to preserve peaks
SVG/PNG export and recordingsSave dashboard snapshots or changed-frame recording bundles
TOML configurationPersistent config file for all CLI options

This document was reviewed against the Grafatui source code at v0.1.11. If you notice any inaccuracies, please open an issue or PR.

Troubleshooting

Prometheus Connection Refused

Check that Prometheus is running and reachable:

curl http://localhost:9090/-/healthy

If you are using the demo stack, the Prometheus port is 19090:

curl http://localhost:19090/-/healthy

No Data Appears

Prometheus may need a few scrape intervals before data is available. Wait 10 to 15 seconds and force a refresh with r.

Also confirm that the dashboard queries match labels in your Prometheus server:

grafatui --prometheus-url http://localhost:9090 --grafana-json ./dashboard.json --var job=prometheus

Dashboard Variables Do Not Match

Override variables explicitly with --var:

grafatui --grafana-json ./dashboard.json --var instance=localhost:9090

If a Grafana dashboard uses multi-select formatting modifiers such as ${var:csv} or ${var:regex}, check the compatibility matrix. Not every Grafana interpolation mode is implemented.

Demo Port Conflict

The demo Prometheus service uses host port 19090. If that port is already in use, edit examples/demo/docker-compose.yml and run Grafatui with the updated URL.

Export Directory Problems

Set an explicit export directory:

grafatui --export-dir ./grafatui-exports

Make sure the directory is writable by your current user.