More vesta examples.
Copy a command, compare the source data, then check the simulated board before publishing.
Simple inputs
Start with plain text or a small JSON object when you want the board to read like a status line.
Plain text wraps across as many rows as it needs and centers itself. Good for announcements, reminders, and message-of-the-day boards.
"the quick brown fox jumps over the lazy dog near the riverbank"Labels sit left, values flush right, one pair per row. Good for operational data where the label matters as much as the value.
{
"status": "online",
"uptime": "14d 3h",
"temp": "72F",
"version": "2.4.1"
}Dense layouts
Use columns and tables when the goal is comparison: weather, scores, rankings, inventory, or any short list.
Two key/value pairs per row instead of one, which doubles how many fields fit before the board runs out of rows.
No --template needed: --columns 2 on a JSON object makes the default auto template pick the kv layout for you.
{
"now": "62F",
"rain_pct": 0,
"high": "66F",
"low": "48F"
}The header line becomes the top row and each following line becomes a board row. CSV is auto-detected, so no --template flag is needed.
name,score,rank
alice,98,1
bob,87,2
carol,76,3
dave,61,4--align left (or --align right) spreads the columns across the full width instead of centering them as one block.
Alignment then differs by type: text sits flush under its header, numbers sit at the far edge of their column. That is why TIER lines up with TOP, while SCORE sits well to the left of 98.
[
{"name": "alice", "tier": "top", "score": 98, "rank": 1},
{"name": "bob", "tier": "mid", "score": 87, "rank": 2},
{"name": "carol", "tier": "mid", "score": 76, "rank": 3},
{"name": "dave", "tier": "low", "score": 61, "rank": 4}
]Headers
Titles, subtitles, and separators cost rows, but they can make repeating dashboards easier to scan.
A title row with colored bookend tiles, plus a subtitle beneath it. Costs two of the six rows, but turns a dense snapshot into a board people recognize at a glance.
This example passes a literal subtitle so the preview stays fixed. Use --subtitle time for the current time, or add --24h to render it as 17:00 rather than 5:00P.
{
"temp": "68F",
"hum_pct": 42,
"co2": "820",
"noise": "38db",
"doors": "shut",
"light": "on",
"heat": "off",
"fans": "on"
}--separator rainbow fills the row below the title block with cycling color tiles. Useful when a board needs a strong section break or a persistent visual identity.
{
"status": "online",
"uptime": "14d 3h",
"temp": "72F",
"version": "2.4.1"
}--rainbow-offset phase-shifts where the color cycle starts (0-5). Same data and separator as above, just rotated. Useful for keeping repeating boards visually distinct.
{
"status": "online",
"uptime": "14d 3h",
"temp": "72F",
"version": "2.4.1"
}Color and Note
Color carries the signal on these boards rather than decoration, and the Note profile has the least room to spare.
Fields named with change, delta, or diff get a color tile automatically: green if positive, red if negative, white at zero.
No _style is involved here, and --explain confirms it by marking every row auto.
{
"requests_delta": 128,
"errors_diff": -12,
"latency_change": 0
}── color indicators ────────────────────
REQUESTS DELTA 128 ██ auto
ERRORS DIFF -12 ██ auto
LATENCY CHANGE 0 ██ auto"signed" colors a field by its sign even when the name has no change/delta/diff in it. BUDGET is negative so it goes red; SAVINGS is positive so it goes green.
"none" does the reverse. SPEND DELTA would auto-color red on its own, but "none" drops the tile and leaves the number untouched.
{
"budget_pct": -8.4,
"savings_pct": 3.1,
"spend_delta": -1200,
"_style": {
"budget_pct": "signed",
"savings_pct": "signed",
"spend_delta": "none"
}
}── color indicators ────────────────────
BUDGET -8.4% ██ signed (positive → green, negative → red, zero → white) → bad
SAVINGS 3.1% ██ signed (positive → green, negative → red, zero → white) → good
── numeric formatting ───────────────────
budget_pct → BUDGET -8.4 → -8.4% _pct suffix, label stripped, percent format
savings_pct → SAVINGS 3.1 → 3.1% _pct suffix, label stripped, percent format
spend_delta -1200 → -1.2K auto compactionThe Note profile is 3 rows of 15 cells, so every column counts. Keep it to a label, a value, and only the color signal you actually need.
A fourth field has nowhere to go. vesta drops it and names it in a warning on stderr, so an extra metric never disappears unnoticed from a scripted board.
Both tiles come from narrow ranges rather than a 0-100 scale. --explain shows uptime graded across 95-100 and errors across 0-5, with each zone boundary computed from those bounds. RPS has no _style, so it gets no tile and no indicator line at all.
{
"uptime_pct": 99.97,
"error_pct": 0.13,
"rps": 1847,
"_style": {
"uptime_pct": {"good": 100, "bad": 95},
"error_pct": {"good": 0, "bad": 5}
}
}── color indicators ────────────────────
UPTIME 99.97% ██ range good=100 bad=95 ██≥98.75 · ██97.5–98.75 · ██96.25–97.5 · ██≤96.25
ERROR 0.13% ██ range good=0 bad=5 ██≤1.25 · ██1.25–2.5 · ██2.5–3.75 · ██≥3.75
── numeric formatting ───────────────────
uptime_pct → UPTIME 99.97 → 99.97% _pct suffix, label stripped, percent format
error_pct → ERROR 0.13 → 0.13% _pct suffix, label stripped, percent format
rps 1847 → 1.8K auto compactionA _style range object grades a value across four colors instead of picking one, sliding green to yellow to orange to red as it moves from the good end toward the bad end.
good and bad name the ends of that scale, not tones, so direction is inferred rather than fixed. The first three fields read good: 0, bad: 100 because less is better. CACHE HIT flips to good: 100, bad: 0, which is why 93% lands green while DISK at 94% lands red.
{
"mem_pct": 38,
"cpu_pct": 61,
"disk_pct": 94,
"cache_hit_pct": 93,
"_style": {
"mem_pct": {"good": 0, "bad": 100},
"cpu_pct": {"good": 0, "bad": 100},
"disk_pct": {"good": 0, "bad": 100},
"cache_hit_pct": {"good": 100, "bad": 0}
}
}── color indicators ────────────────────
MEM 38% ██ range good=0 bad=100 ██≤25 · ██25–50 · ██50–75 · ██≥75
CPU 61% ██ range good=0 bad=100 ██≤25 · ██25–50 · ██50–75 · ██≥75
DISK 94% ██ range good=0 bad=100 ██≤25 · ██25–50 · ██50–75 · ██≥75
CACHE HIT 93% ██ range good=100 bad=0 ██≥75 · ██50–75 · ██25–50 · ██≤25
── numeric formatting ───────────────────
mem_pct → MEM 38 → 38% _pct suffix, label stripped, percent format
cpu_pct → CPU 61 → 61% _pct suffix, label stripped, percent format
disk_pct → DISK 94 → 94% _pct suffix, label stripped, percent format
cache_hit_pct → CACHE HIT 93 → 93% _pct suffix, label stripped, percent format{red}, {green}, and the rest place a tile exactly where you write them in the text. Handy when a message needs explicit tiles instead of semantic styling.
{red}{orange}{yellow}{green}
{blue}{violet}{white}{black}{filled}
{colors!}Beyond render
Every example above uses vesta render, which formats and previews without touching your board. The other three commands read from and write to a real one, and take the same formatting flags.
Prints the regular preview plus notes about suffix formatting and color tile decisions. Use this when a value or color does not look the way you expected.
Fetches the current board from the Vestaboard Cloud API. Useful before changing a live board or when you want to confirm what is currently displayed. Needs your Cloud read/write key via --token or $VESTABOARD_TOKEN.
Sends a finished layout through the Vestaboard Cloud API. This is the normal publish path for most scripts and automations. Uses the same $VESTABOARD_TOKEN as read-cloud.
Sends a finished layout to your own Vestaboard Local API endpoint. Use this only when your script can reach the board on your local network. Takes a separate key, $VESTABOARD_LOCAL_API_KEY, not the Cloud token.
Writes the exact Vestaboard character array instead of a preview. Useful for archiving, debugging API payloads, or handing the rendered output to another tool.