The .kymo Language
A guided tour of the building blocks you'll use to draw diagrams. Every section has a
small snippet you can paste into a file and render with kymo file.kymo.
This is the teaching companion to the DSL Language Specification. Each section links to the spec clause that defines it formally; reach for the spec when you need the exact grammar or an edge case.
A .kymo file is a list of plain-text lines. Comments start with #. Order is mostly free,
but a readable convention is: metadata first (canvas, title), then components and
regions, then edges last.
Components — the boxes
A component (a "leaf") is one node. Write it as a shape/icon/accent triple followed by
a name and subtitle:
id(api) — a unique handle you use later in edges and containers.shape— the outline. Recognised shapes:box,circle,cube,cube-big,cylinder,hex,badge,annotation,aws-tile,aws-tile-hero(plus thebpmn-*shapes used for BPMN). Use a recognised value — an unknown shape stops the render with an error.icon— the glyph drawn inside, named by key (see Icons below). An unknown icon key also errors, so check the spelling if rendering fails.accent— the colour:green,orange,blue, orred."Name" "Subtitle"— two quoted labels. Either may be empty (""). The first is the bold title; the second is a smaller line beneath it.@ …— where to put it (next section). Omit it and the component lands at(0, 0)unless a layout container positions it.
→ Spec: §6.4 Leaf Components
Placing components
Two ways to position a component:
Absolute — an (x, y) pixel coordinate for the component's centre:
Relative to another component — @ <other-id> <side> [gap], where side is top,
right, bottom, or left:
This places child 60 px to the right of orch. The gap is optional.
→ Spec: §6.4, §7 Semantics
Regions — labelled containers
A region groups components inside a bordered, labelled box. There are two kinds: outer
(a heavier administrative boundary) and inner (a lighter logical subgroup). A region is a
line ending in {:
Regions auto-size to enclose their contents — you don't set their width or height. Nest
an inner region inside an outer one and the outer box grows to wrap everything.
Useful region options (any order, each at most once):
Inside a region body you can also list bare ids (components defined elsewhere) to add them to this region without redefining them:
→ Spec: §6.5 Containers
Arranging things automatically
You don't have to place everything by hand. kymo offers three auto-layout tools.
Auto-layout frame — turn a region into a Figma-style stack with horizontal or
vertical, and members flow along that axis:
Anonymous layout tree — a one-line grouping where | lays ids out left-to-right and
, lays them top-to-bottom. Nest with braces (don't mix | and , at the same level):
Grid rows — inside a region, row lines snap members to shared rows. When several
regions sit side by side, equal row indices line up at the same height, so cross-region
edges on the same row run perfectly horizontal (this is the trick behind
samples/data.kymo):
→ Spec: §6.5, §6.10 Layout Tree
Edges — the arrows
An edge connects two component ids, with an optional : "label" and an optional { … }
block of routing hints:
Three arrow styles:
Inside { … }, comma-separated options give you fine control:
src=/dst=— which side the edge leaves from and arrives at:top,right,bottom,left, orcenter, with an optional pixel nudge:src=right(0,-12).via=(x,y)— force the line through waypoints; chain several with;:via=(120,300);(220,300).- routing —
curve,straight,over,under, orelbow(the default orthogonal router). dashed— a dashed line (handy for async / optional flows).small— smaller label text.label_offset=(x,y),label_pos=(x,y),label_at=src|dst|mid— fine label placement.
A fully-decorated edge:
Start simple — bare a --> b works great. Add hints only where the auto-router needs help.
→ Spec: §6.7 Edges
Canvas, title, and subtitle
Optional metadata at the top of the file:
canvas: sets a fixed size. Leave it out and kymo computes the canvas from your content
plus a 30-px margin — usually what you want. title:/subtitle: render a heading block at
the top.
→ Spec: §6.3 Metadata Directives, §7.4 Auto-Canvas
Icons
The icon slot of a component (and a region's icon option) names a glyph by key. kymo
resolves a key in two steps:
- Built-in glyphs — a hand-coded set (e.g.
customer-person,internet-cloud,step-1,key,notebook). - File-backed icons — SVG/PNG files under the repo's top-level
icons/directory, organised by provider (aws/,azure/,gcp/,k8s/,generic/,saas/, …).
For file-backed icons the key is <provider>-<name> — the provider folder joined to the
file's name, with the middle category folder dropped. So icons/aws/compute/lambda.svg
becomes the key aws-lambda, and icons/k8s/compute/pod.svg becomes k8s-pod:
→ Reference implementation: packages/python/src/kymo/icons.py
BPMN processes
To draw a business process, you don't have to place each node. A bpmn { … } block declares
typed nodes and flows, and kymo lays them out left-to-right automatically:
- Node kinds:
start,end,end!(terminate),task, the gatewaysxor/and/or, plusevent,subprocess,note,data,store. Refine a node withtype=…(e.g.task T "Review" type=user). - Flows:
->sequence,~>message (dashed),..>association (dotted). Chain them (A -> B -> C), separate statements with;, and label the last segment with: "…".
Already have a .bpmn file from bpmn.io, Camunda Modeler, or Signavio? Just render it
directly — kymo process.bpmn — and kymo uses the geometry stored in the file. See the
BPMN element mapping (BPMN-MAP-001).
→ Spec: §6.9 BPMN Process Blocks
Next steps
- Cookbook — complete diagrams you can adapt.
- FAQ & Troubleshooting — fixes for common surprises.
- DSL Language Specification — the full normative grammar.