Node Types
The scene graph supports 28 node types from Figma's Kiwi schema. Each node is identified by a GUID (sessionID:localID) and has a parent reference via parentIndex. The OpenPencil engine's NodeType union currently uses 17 of these types.
Type Table
28 Figma schema types + 1 synthetic engine type. Types marked ✅ are in the engine's NodeType union (17 total).
| Type | ID | Description | Engine |
|---|---|---|---|
| DOCUMENT | 1 | Root node, one per file | — |
| CANVAS | 2 | Page | ✅ |
| GROUP | 3 | Group container | ✅ |
| FRAME | 4 | Primary container (artboard), supports auto-layout | ✅ |
| BOOLEAN_OPERATION | 5 | Union/subtract/intersect/exclude result | |
| VECTOR | 6 | Freeform vector path | ✅ |
| STAR | 7 | Star shape | ✅ |
| LINE | 8 | Line | ✅ |
| ELLIPSE | 9 | Ellipse/circle, supports arc data | ✅ |
| RECTANGLE | 10 | Rectangle | ✅ |
| REGULAR_POLYGON | 11 | Regular polygon (3–12 sides, engine uses POLYGON) | ✅ |
| ROUNDED_RECTANGLE | 12 | Rectangle with smooth corners | ✅ |
| TEXT | 13 | Text with rich formatting | ✅ |
| SLICE | 14 | Export region | |
| SYMBOL | 15 | Component (main, engine uses COMPONENT) | ✅ |
| INSTANCE | 16 | Component instance | ✅ |
| STICKY | 17 | FigJam sticky note | |
| SHAPE_WITH_TEXT | 18 | FigJam shape | ✅ |
| CONNECTOR | 19 | Connector line between nodes | ✅ |
| CODE_BLOCK | 20 | FigJam code block | |
| WIDGET | 21 | Plugin widget | |
| STAMP | 22 | FigJam stamp | |
| MEDIA | 23 | Video/GIF | |
| HIGHLIGHT | 24 | FigJam highlight | |
| SECTION | 25 | Canvas section (organizational, top-level only) | ✅ |
| SECTION_OVERLAY | 26 | Section overlay | |
| WASHI_TAPE | 27 | FigJam washi tape | |
| VARIABLE | 28 | Variable definition node | |
| COMPONENT_SET | — | Variant group container (synthetic, mapped from SYMBOL) | ✅ |
Engine NodeType Union (17 types)
The engine's NodeType uses simplified names. Some differ from the Kiwi schema:
COMPONENT→ KiwiSYMBOL(ID 15)COMPONENT_SET→ variant group container (no dedicated Kiwi ID, mapped from SYMBOL with variants)POLYGON→ KiwiREGULAR_POLYGON(ID 11)
type NodeType =
| 'CANVAS' | 'FRAME' | 'RECTANGLE' | 'ROUNDED_RECTANGLE'
| 'ELLIPSE' | 'TEXT' | 'LINE' | 'STAR' | 'POLYGON'
| 'VECTOR' | 'GROUP' | 'SECTION'
| 'COMPONENT' | 'COMPONENT_SET' | 'INSTANCE'
| 'CONNECTOR' | 'SHAPE_WITH_TEXT'Node Hierarchy
Document
├── Canvas (Page 1)
│ ├── Section (top-level only, title pill, auto-adopts siblings)
│ │ ├── Frame
│ │ │ └── ...children
│ │ └── Rectangle
│ ├── Frame
│ │ ├── Rectangle
│ │ ├── Text
│ │ └── Frame (nested)
│ │ ├── Ellipse
│ │ └── Instance (→ references Component)
│ ├── Component
│ │ └── ...children
│ ├── Group
│ │ └── ...children
│ └── BooleanOperation
│ └── ...operand shapes
└── Canvas (Page 2)
└── ...Core Properties
Every node carries these fields (subset of NodeChange):
Identity & Tree
guid— unique identifier (sessionID:localID)type— node type enumname— display namephase— CREATED or REMOVEDparentIndex— parent GUID + position string for z-ordering
Transform
size— width/height vectortransform— 2×3 affine matrixrotation— degrees
Appearance
fillPaints[]— fill colors/gradients/imagesstrokePaints[]— stroke colorseffects[]— shadows, blursopacity— 0–1blendMode— NORMAL, MULTIPLY, SCREEN, etc.
Stroke
strokeWeight— stroke thicknessstrokeAlign— inside / center / outsidestrokeCap— butt / round / squarestrokeJoin— miter / bevel / rounddashPattern[]— dash/gap lengths
Corners
cornerRadius— uniform radiuscornerSmoothing— squircle amount (0–1)- Per-corner radii when
rectangleCornerRadiiIndependentis true
Visibility
visible— show/hidelocked— prevent editing
Type-Specific Properties
Text
fontSize, fontName, lineHeight, letterSpacing, textAlignHorizontal, textAlignVertical, textAutoResize, textData (characters, style overrides, baselines, glyphs)
Vector
vectorData (vectorNetworkBlob, normalizedSize), fillGeometry[], strokeGeometry[], handleMirroring, arcData
Layout (Frame)
stackMode, stackSpacing, stackPadding, stackJustify, stackCounterAlign, stackPrimarySizing, stackCounterSizing, stackChildPrimaryGrow, stackChildAlignSelf
Component
symbolData, componentKey, componentPropDefs[], symbolDescription
Instance
overriddenSymbolID, symbolData.symbolOverrides[], componentPropRefs[], componentPropAssignments[]
Paint
interface Fill {
type: 'SOLID' | 'GRADIENT_LINEAR' | 'GRADIENT_RADIAL' |
'GRADIENT_ANGULAR' | 'GRADIENT_DIAMOND' | 'IMAGE'
color: Color // {r, g, b, a} 0–1 floats
opacity: number // 0–1
visible: boolean
blendMode?: BlendMode
gradientStops?: GradientStop[] // for gradients
gradientTransform?: GradientTransform // 2×3 matrix
imageHash?: string // for image fills
imageScaleMode?: 'FILL' | 'FIT' | 'CROP' | 'TILE'
imageTransform?: GradientTransform
}Effect
interface Effect {
type: 'DROP_SHADOW' | 'INNER_SHADOW' | 'LAYER_BLUR' |
'BACKGROUND_BLUR' | 'FOREGROUND_BLUR'
color: Color
offset: { x: number; y: number }
radius: number
spread: number
visible: boolean
}Stroke
interface Stroke {
color: Color
weight: number
opacity: number
visible: boolean
align: 'INSIDE' | 'CENTER' | 'OUTSIDE'
cap?: 'NONE' | 'ROUND' | 'SQUARE' | 'ARROW_LINES' | 'ARROW_EQUILATERAL'
join?: 'MITER' | 'BEVEL' | 'ROUND'
dashPattern?: number[]
}