Declart

Declare what to show. The engine decides how it looks.

Declart is a declarative diagram engine. You write a TOML file describing the structure of your diagram, and Declart renders it to SVG. No layout coordinates. No styling choices. Just content.

Quick Start

CLI

# Install
cargo install declart-cli

# Scaffold a starter diagram
declart init flow > diagram.toml

# Render to SVG
declart render diagram.toml

# Render to PNG
declart render diagram.toml --format png

# Watch and auto-rebuild on changes
declart watch diagram.toml

# Validate without rendering
declart validate diagram.toml

Node.js

const declart = require('@iyulab/declart');

const svg = declart.render(`
kind = "flow"
view = "cycle"
title = "PDCA"
[[items]]
label = "Plan"
[[items]]
label = "Do"
`);

Rust (library)

#![allow(unused)]
fn main() {
use declart_core::{parse, render};
use declart_core::render::DEFAULT_THEME;

let diagram = parse(input)?;
let svg = render(&diagram, &DEFAULT_THEME)?;
}

Supported Kinds

KindViews
flowprocess (default), cycle, funnel, swimlane
tierpyramid (default)
hierarchyorg_chart (auto), fishbone (auto)
timeline
matrix
hub_spoke
venn
comparison
state

Design Philosophy

See Principles for the full design rationale. The key idea: declarations express what exists, not how it looks. The engine owns visual decisions.

Interactive Playground

Open the Declart Playground — no installation required

Edit TOML declarations and see your diagrams rendered live in the browser. All 8 diagram kinds are available, with default and monochrome themes.

Note: The playground requires HTTP to load the WASM module. Use mdbook serve docs/ for local testing rather than opening the file directly.

Declart Grammar Principles

These principles govern every declaration file format in Declart, across all diagram kinds and all implementations.

  1. Design exclusion. Declaration files contain no visual information: no colors, coordinates, fonts, sizes, margins, or layout hints. These are the engine's domain.

  2. Semantics only. Fields express meaning, not appearance. emphasis: primary is allowed; color: red is not. The engine decides how emphasis looks.

  3. LLM-predictable. Field names are single English words. Structure is flat or exactly one level deep ([[items]]). A language model must be able to generate a correct declaration without examples.

  4. Minimal and concise. Each kind defines only its required fields. Optional fields are added only when proven necessary across multiple use cases. When in doubt, leave it out.

  5. One representation per diagram. Each kind + view pair has exactly one valid schema. No aliases, structural variants, or flags that change interpretation. Two declarations expressing the same diagram are byte-for-byte identical except for whitespace.

Common Schema Rules

Rules that apply to every Declart declaration file.

Required fields

FieldTypeDescription
kindstringOne of: flow, tier, hierarchy, timeline, matrix, hub_spoke, venn, comparison

Optional fields

FieldTypeDescription
titlestringDisplay title rendered above the diagram. Omit to suppress.
viewstringRendering intent within the kind. Valid values depend on kind. Omit to let the engine select automatically.

Item arrays

  • Items are declared as [[items]] TOML array-of-tables.
  • At least one item is required for flow and tier. The matrix kind uses [[quadrants]]; hierarchy uses [[nodes]]; timeline uses [[events]]; hub_spoke uses [[spokes]]; venn uses [[sets]]; comparison uses [[columns]] and [[rows]].
  • Item order in the file is rendering order.

Forbidden fields

Any field not listed in a kind's spec document is forbidden. Forbidden fields cause a parse error. This includes but is not limited to: color, fill, stroke, font, size, x, y, width, height, style, class.

Emphasis (shared optional item field)

When a kind supports item-level emphasis, it uses this field:

ValueMeaning
primaryMost important item in the diagram
secondarySecondary importance

The engine decides visual representation. Omitting emphasis means default weight.

  • primary: white outline stroke + bold text
  • secondary: lighter color tint

Using Claude or GPT to Generate Declart Diagrams

Declart's TOML format is designed for LLM generation. The structure is explicit and validated — an LLM can produce a well-formed diagram in one shot, and declart validate catches any mistakes before rendering.

Why Declart works well with LLMs

  • No layout decisions: the LLM only writes content (labels, structure). The engine handles all visual choices.
  • Strict schema: deny_unknown_fields means invalid keys are caught immediately. The LLM cannot silently produce a broken diagram.
  • Explicit kind: the kind field tells the parser exactly what to expect. No ambiguity.
  • Short format: a typical diagram is 5–20 lines of TOML.

Kind and View

Declart v0.16+ uses a two-level structure:

  • kind — the data contract (determines which fields are valid)
  • view — the semantic intent (determines how the engine renders it)
kindviewsNotes
flowprocess (default), cycle, funnelview optional — defaults to process
tierpyramid (default)Ranked levels — view optional
hierarchyorg_chart, fishboneview optional — auto-selected by root count
timelineNo view field
matrixNo view field
hub_spokeNo view field
vennNo view field
comparisonNo view field

Workflow

1. Prompt LLM → TOML output
2. declart validate diagram.toml   # catches errors with clear messages
3. declart render diagram.toml     # produces SVG

If validate fails, paste the error message back to the LLM and ask it to fix the specific field.


Prompt Templates

Tier (Pyramid) — Hierarchies, priority layers

Prompt: "Generate a Declart TOML diagram showing Maslow's hierarchy of needs as a pyramid. Use kind = 'tier', include a title, and list the 5 levels as items from top (apex) to bottom (base)."

kind = "tier"
title = "Maslow's Hierarchy of Needs"

[[items]]
label = "Self-Actualization"

[[items]]
label = "Esteem"

[[items]]
label = "Love & Belonging"

[[items]]
label = "Safety"

[[items]]
label = "Physiological"
emphasis = "primary"

Process — Sequential steps, workflows

Prompt: "Create a Declart TOML diagram for a 4-step CI/CD pipeline. Use kind = 'flow' (process view is the default)."

kind = "flow"
title = "CI/CD Pipeline"

[[items]]
label = "Build"

[[items]]
label = "Test"
emphasis = "primary"

[[items]]
label = "Stage"

[[items]]
label = "Deploy"

Cycle — Closed loops, PDCA, lifecycles

Prompt: "Generate a Declart TOML diagram for the PDCA improvement cycle. Use kind = 'flow' and view = 'cycle'."

kind = "flow"
view = "cycle"
title = "PDCA Cycle"

[[items]]
label = "Plan"

[[items]]
label = "Do"

[[items]]
label = "Check"

[[items]]
label = "Act"

Matrix 2×2 — Prioritization, Eisenhower

Prompt: "Create an Eisenhower Matrix in Declart TOML with x_axis = 'Importance' and y_axis = 'Urgency'."

kind = "matrix"
title = "Eisenhower Matrix"
x_axis = "Importance"
y_axis = "Urgency"

[[quadrants]]
label = "Do First"
position = "top-right"
emphasis = "primary"

[[quadrants]]
label = "Schedule"
position = "top-left"

[[quadrants]]
label = "Delegate"
position = "bottom-right"

[[quadrants]]
label = "Eliminate"
position = "bottom-left"

Note: Use position to explicitly place quadrants. Valid values: top-left, top-right, bottom-left, bottom-right.


Prompt: "Make a Declart hub-and-spoke diagram with 'Cloud Architecture' as the center and 5 services as spokes."

kind = "hub_spoke"
title = "Cloud Architecture"
center = "API Gateway"

[[spokes]]
label = "Auth Service"

[[spokes]]
label = "User DB"

[[spokes]]
label = "Payment"

[[spokes]]
label = "Notifications"

[[spokes]]
label = "Analytics"

Venn — Set intersections, overlapping groups

Prompt: "Generate a 2-set Venn diagram showing the overlap between 'Frontend Skills' and 'Backend Skills'."

kind = "venn"
title = "Full-Stack Skills"

[[sets]]
label = "Frontend"

[[sets]]
label = "Backend"

[[intersections]]
sets = ["Frontend", "Backend"]
label = "TypeScript"

Timeline — Date-anchored events

Prompt: "Create a Declart timeline of 5 product launch milestones in 2024, using ISO dates."

kind = "timeline"
title = "Product Launch 2024"

[[events]]
date = "2024-01-15"
label = "Alpha"

[[events]]
date = "2024-03-01"
label = "Beta"

[[events]]
date = "2024-06-01"
label = "RC1"

[[events]]
date = "2024-09-15"
label = "GA"

[[events]]
date = "2024-12-01"
label = "v2 Plan"

Rule: dates accept YYYY, YYYY-MM, or YYYY-MM-DD. Partial forms are placed at the start of that year/month. Declart sorts events automatically.


Fishbone / Ishikawa — Root cause analysis

Prompt: "Generate a Declart fishbone diagram where the effect is 'Slow API Response' with 4 cause categories and sub-causes. Use kind = 'hierarchy' and view = 'fishbone'. Each cause category is a root node; sub-causes have parent = the category label."

kind = "hierarchy"
view = "fishbone"
title = "Slow API Response"

[[nodes]]
label = "Database"

[[nodes]]
label = "Missing indexes"
parent = "Database"

[[nodes]]
label = "N+1 queries"
parent = "Database"

[[nodes]]
label = "Network"

[[nodes]]
label = "High latency"
parent = "Network"

[[nodes]]
label = "Code"

[[nodes]]
label = "Blocking I/O"
parent = "Code"

[[nodes]]
label = "Infrastructure"

Structure: Root nodes (no parent) become cause categories on the spine. Child nodes become sub-causes. The effect field is rendered as the spine-end effect label; if effect is omitted, title is used as fallback.

Limit: 2–20 root nodes (cause categories). Recommend 8 or fewer for readability.


Org Chart — Hierarchical trees

Prompt: "Create a Declart org chart for a small engineering team with a CTO at the top. Use kind = 'hierarchy'. With a single root node, the engine automatically renders as an org chart."

kind = "hierarchy"
title = "Engineering Team"

[[nodes]]
label = "CTO"

[[nodes]]
label = "Frontend Lead"
parent = "CTO"

[[nodes]]
label = "Backend Lead"
parent = "CTO"

[[nodes]]
label = "FE Developer"
parent = "Frontend Lead"

[[nodes]]
label = "BE Developer"
parent = "Backend Lead"

Rule: exactly one root node (no parent). parent references another node's id (preferred) or label. For stable references that survive label renames, add id = "stable-key" to each node and use that in parent. To explicitly select the view: view = "org_chart".


Funnel — Conversion funnels, sales pipelines

Prompt: "Generate a Declart funnel for a 5-stage sales pipeline. Use kind = 'flow' and view = 'funnel'."

kind = "flow"
view = "funnel"
title = "Sales Pipeline"

[[items]]
label = "Leads"

[[items]]
label = "Qualified"

[[items]]
label = "Proposal"

[[items]]
label = "Negotiation"

[[items]]
label = "Closed Won"
emphasis = "primary"

Limit: 2–10 stages.


Comparison — Feature matrices, trade-off tables

Prompt: "Generate a Declart comparison table for three JavaScript frameworks across four criteria."

kind = "comparison"
title = "JavaScript Framework Comparison"

[[columns]]
label = "Performance"

[[columns]]
label = "Ecosystem"

[[rows]]
label = "React"
Performance = "★★★★"
Ecosystem = "★★★★★"

[[rows]]
label = "Vue"
Performance = "★★★★"
Ecosystem = "★★★"

[[rows]]
label = "Svelte"
Performance = "★★★★★"

Limits: 1–10 rows, 1–8 columns. Declare [[columns]] first for column order. Cell values are inline in each row, keyed by column label. Missing cells are rendered empty. Column label must not be "label" (reserved). Use TOML quoted keys ("My Column" = "val") if a column name contains spaces.


Tips for LLMs

RuleDetail
kind is requiredAlways include it as the first field
view is optionalOmit to use the default; include to declare intent explicitly
No unknown fieldsDon't add color, style, or other keys not in the spec
emphasis valuesOnly "primary" or "secondary"
Flow viewskind = "flow" + view: process (default), cycle, funnel
Tier viewskind = "tier" + view: pyramid (default and only)
Hierarchy nodeslabel must be unique; parent references id (preferred) or label of another node
Hierarchy idAdd id = "key" to nodes for stable parent references that survive label renames
Hierarchy auto-select1 root → org_chart; 2+ roots → fishbone (or set view explicitly)
Fishbone effectRendered as the spine-end effect label; falls back to title if omitted
Matrix quadrantsAlways exactly 4 [[quadrants]] entries
Timeline datesISO 8601: YYYY, YYYY-MM, or YYYY-MM-DD
Venn setsOnly 2 or 3 sets supported
Comparison cellsColumn label in each row must match an existing [[columns]] label

Validating LLM Output

declart validate diagram.toml

Error messages include field names and hints:

invalid value `(missing)` for field `position`
  = hint: When any quadrant has position, all must specify it.
          Valid: top-left, top-right, bottom-left, bottom-right

Paste the error back to the LLM to get a corrected TOML.

Flow

A flow diagram represents an ordered list of labeled items. The view field determines how the flow is interpreted and rendered.

Fields

FieldRequiredTypeDescription
kindyes"flow"Must be exactly "flow"
viewnostringRendering intent. Default: process
titlenostringTitle rendered above the diagram
itemsyesarray of ItemAt least one item required

Item fields

FieldRequiredTypeDescription
labelyesstringText displayed in the item
emphasisnostring"primary" or "secondary". See schema.

View values

valueMeaningMin itemsMax items
processLinear left-to-right steps (default)1
cycleClosed loop — last item connects to first2
funnelTapering stages (conversion/filtering)210
swimlaneSteps grouped into horizontal actor lanes, top→down2

When view is omitted, the engine uses process.

For ranked/layered visuals (pyramid), use kind = "tier" instead.

Swimlane item fields

When view = "swimlane", each item gains one additional required field:

FieldRequiredTypeDescription
actoryesstringLane owner of this step

actor is ignored by all other views. At least 2 distinct actor values are required.

Swimlane example

주문 처리 프로세스 고객 시스템 결제 게이트웨이 주문 요청 재고 확인 결제 처리 주문 확정 확인 수신

Example

PDCA Plan Do Check Act

Tier

A tier diagram represents a ranked set of labeled items — levels differentiated by importance, abstraction, or priority. The view field determines how the tiers are rendered.

Fields

FieldRequiredTypeDescription
kindyes"tier"Must be exactly "tier"
viewnostringRendering intent. Default: pyramid
titlenostringTitle rendered above the diagram
itemsyesarray of ItemAt least one item required

Item fields

FieldRequiredTypeDescription
labelyesstringText displayed in the tier level
emphasisnostring"primary" or "secondary". See schema.

View values

valueMeaningMin itemsMax items
pyramidStacked layers from apex (first) to base (last)1

When view is omitted, the engine uses pyramid.

Example

Maslow's Hierarchy of Needs Self-Actualization Esteem Love & Belonging Safety Physiological

Hierarchy

A hierarchy diagram represents a tree of labeled nodes connected by parent-child relationships. The view field determines how the tree is rendered.

Fields

FieldRequiredTypeDescription
kindyes"hierarchy"Must be exactly "hierarchy"
viewnostringRendering intent. Auto-selected if omitted.
titlenostringChart title (rendered above the diagram)
effectnostringFishbone view only: spine-end effect label. Falls back to title if omitted.
nodesyesarray of NodeAt least one node required

Node fields

FieldRequiredTypeDescription
labelyesstringDisplay text
idnostringStable identifier for parent references. If set, other nodes reference this node by id, not label.
parentnostringid (preferred) or label of the parent node; omit for root nodes

View values

valueMeaningAuto-selected when
org_chartTop-down tree; exactly one root requiredexactly 1 root node
fishboneCause-and-effect diagram2+ root nodes

Auto-selection: When view is omitted, the engine selects org_chart for exactly one root node, fishbone for two or more root nodes. The CLI emits a warning when view is auto-selected; add an explicit view to suppress it.

View-specific constraints

org_chart: exactly one root node required.
fishbone: 2–20 root nodes (cause categories); effect (or title if effect is omitted) is rendered as the effect label at the right end of the spine. Recommend 8 or fewer root nodes — 9+ cause categories on the same side of the spine may overlap.

Example — org_chart view (auto-selected)

Engineering Division VP Engineering Backend Team Frontend Team

Example — fishbone view

High Latency Server CPU saturation Network Bandwidth

Example — org_chart with stable id references

Engineering Team VP Engineering Backend Team Frontend Team

Timeline

A timeline diagram. Events are placed along a horizontal axis at positions proportional to their dates. Used for project histories, product roadmaps, and chronological narratives.

Fields

FieldRequiredTypeDescription
kindyes"timeline"Must be exactly "timeline"
titlenostringTitle rendered above the diagram
eventsyesarray of EventAt least two events required

Event fields

FieldRequiredTypeDescription
dateyesstringDate as YYYY, YYYY-MM, or YYYY-MM-DD. Partial forms are placed at the start of that year/month.
labelyesstringText displayed above or below the event marker

Rendering rules

  • Events are sorted by date and placed along a horizontal axis.
  • The horizontal position of each event is proportional to its date within the overall date range.
  • Event labels alternate above and below the axis to reduce overlap.
  • The date string is displayed below each event marker.
  • At least two events are required to establish a time range.

Example

Product Launch History Alpha 2024-01-15 Beta 2024-04-01 Launch 2024-07-20 v2.0 2024-12-01

Matrix 2×2

A two-by-two matrix diagram. Used for prioritization, strategy frameworks, and categorization with two independent axes.

Fields

FieldRequiredTypeDescription
kindyes"matrix"Must be exactly "matrix"
titlenostringTitle rendered above the diagram
x_axisyesstringLabel for the horizontal axis
y_axisyesstringLabel for the vertical axis
quadrantsyesarray of 4Exactly 4 quadrants, in reading order

Quadrant fields

FieldRequiredTypeDescription
labelyesstringText displayed in the quadrant
emphasisnostring"primary" or "secondary". See schema.
positionnostringExplicit cell: "top-left", "top-right", "bottom-left", "bottom-right"

Quadrant order

Without position (default): Quadrants are declared in reading order (left-to-right, top-to-bottom):

  1. Top-left (high Y, low X)
  2. Top-right (high Y, high X)
  3. Bottom-left (low Y, low X)
  4. Bottom-right (low Y, high X)

With position: All four quadrants must each declare a distinct position. Order in the file does not matter. When any quadrant has position, all four must specify it.

Rendering rules

  • The diagram is a 2×2 grid divided by a horizontal and vertical axis line.
  • Each quadrant occupies one cell of the grid and displays its label centered.
  • x_axis is rendered below the horizontal center line.
  • y_axis is rendered to the left of the vertical center line, rotated 90°.
  • Exactly 4 quadrants are required; more or fewer is a parse error.

Example

Eisenhower Matrix Do First Schedule Delegate Eliminate Importance Low High Urgency Low High

Hub-and-Spoke

A hub-and-spoke diagram. A central node radiates connections to surrounding spoke nodes. Used for showing a central concept with related elements, or a hub with connected services.

Fields

FieldRequiredTypeDescription
kindyes"hub_spoke"Must be exactly "hub_spoke"
titlenostringTitle rendered above the diagram
centeryesstringLabel for the central hub node
spokesyesarray of SpokeAt least two spokes required

Spoke fields

FieldRequiredTypeDescription
labelyesstringText displayed in the spoke node
emphasisnostring"primary" or "secondary". See schema.

Rendering rules

  • The center node is rendered at the center of the diagram.
  • Spoke nodes are arranged evenly around the center in a circle.
  • Lines connect the center node to each spoke node.
  • The center node is visually distinguished from spoke nodes (larger, different color).
  • Spoke nodes use the base color; the center uses the apex color.

Example

Cloud Architecture Auth Service User Service Order Service Payment Service Notification API Gateway

Venn

A Venn diagram. Two or three overlapping circles represent sets. Intersection regions may be labeled. Used for showing set relationships, similarities, and differences.

Fields

FieldRequiredTypeDescription
kindyes"venn"Must be exactly "venn"
titlenostringTitle rendered above the diagram
setsyesarray of Set2 or 3 sets required
intersectionsnoarray of IntersectionLabeled regions in the overlap areas

Set fields

FieldRequiredTypeDescription
labelyesstringName of the set

Intersection fields

FieldRequiredTypeDescription
setsyesarray of stringSet labels identifying which overlap region this labels
labelyesstringText displayed in the overlap region

Rendering rules

  • Circles are arranged to overlap: two sets side-by-side; three sets in a triangle.
  • Each circle is rendered with partial opacity so overlaps are visible.
  • Set labels appear near the outer edge of each circle (non-overlapping region).
  • Intersection labels appear in the center of the overlap region.
  • Exactly 2 or 3 sets are required; other counts are a parse error.

Example

Skills Overlap Design Engineering UX Engineering

Comparison Table Kind — Specification

Purpose

Presents a matrix of items (rows) evaluated against criteria (columns). Each cell value is declared inline within the row entry.

TOML Schema

kind = "comparison"
title = <string>?         # optional diagram title

[[columns]]
label = <string>          # evaluation criterion (required, unique)

[[rows]]
label = <string>          # item being compared (required, unique)
<ColumnLabel> = <string>  # cell value for that column (optional, omit = empty cell)

Constraints

ConstraintRule
Rows1–10
Columns1–8
Column labelMust not be "label" (reserved for the row identifier)
Cell keys in rowsMust match a declared columns[].label; unknown keys are an error
Missing cellsTreated as empty (allowed)

Rendering Specification

  • Canvas: 800px wide, height = title_area + 45px column header + rows × 50px + 20px padding
  • Row header column: 180px wide, apex-tinted background
  • Column header row: 45px tall, apex color background, bold white/dark text
  • Data cells: 50px tall, equal width distributing remaining canvas; alternating even/odd row backgrounds
  • Grid borders: 1px lines using apex-background interpolated color
  • Text: Noto Sans, 13px; truncated with if wider than available cell width

Example

JavaScript Framework Comparison Performance Ecosystem React Vue ★★★★★ ★★★★ ★★★ ★★★★

Example Files

  • valid/basic.toml — 2 rows × 2 columns, inline cells
  • valid/no_title.toml — title omitted
  • valid/empty_cells.toml — no cells defined (sparse table)
  • valid/basic.json — JSON format
  • invalid/no_rows.toml — missing rows → error
  • invalid/no_columns.toml — missing columns → error
  • invalid/invalid_cell_ref.toml — row uses undeclared column key → error
  • invalid/too_many_columns.toml — 9 columns exceeds limit → error

State

A state diagram represents a system's lifecycle as a set of named states and directed transitions between them.

Fields

FieldRequiredTypeDescription
kindyes"state"Must be exactly "state"
titlenostringRendered above the diagram
statesyesarray of StateAt least 2 states required
transitionsnoarray of TransitionMay be empty (unconnected states)

State fields

FieldRequiredTypeDescription
labelyesstringDisplay text. Must be unique unless id is set.
idnostringStable identifier for from/to references. Falls back to label if omitted.
rolenostring"initial" or "terminal". At most one "initial"; multiple "terminal" allowed.

Transition fields

FieldRequiredTypeDescription
fromyesstringid (preferred) or label of source state
toyesstringid (preferred) or label of target state
triggernostringEvent or condition causing this transition
typenostring"normal" (default) or "exception" — semantic type

Self-loop transitions (from = to) are valid. Transition without trigger is valid (unconditional).

Cross-reference resolution

If a state has an id, use id in from/to. If it has no id, use label. Unknown references → validation error. Duplicate labels without id → validation error.

Example

주문 처리 상태 주문 접수 결제 완료 결제 실패 대기 처리 중 완료 취소됨