JSON-based format for Grasshopper definitions
Version: 1.0
Status: Draft
Last Updated: 2026-01-12
GhJSON is a JSON-based format for representing Grasshopper definitions. It provides a human-readable, portable way to serialize and deserialize Grasshopper documents, enabling:
GhJSON files use the .ghjson extension.
GhJSON files MUST be encoded in UTF-8 without BOM.
A GhJSON document is a JSON object with the following top-level structure:
{
"schemaVersion": "1.0",
"metadata": { ... },
"components": [ ... ],
"connections": [ ... ],
"groups": [ ... ]
}
| Property | Type | Required | Description |
|---|---|---|---|
schemaVersion |
string | No | GhJSON schema version (default: “1.0”) |
metadata |
object | No | Document metadata |
components |
array | Yes | List of components |
connections |
array | No | List of connections |
groups |
array | No | List of groups |
The metadata object contains information about the document:
{
"metadata": {
"description": "A parametric tower generator",
"author": "Jane Smith",
"version": "2",
"created": "2026-01-10T14:30:00Z",
"modified": "2026-01-11T09:15:00Z",
"rhinoVersion": "8.24",
"grasshopperVersion": "1.0.0007",
"dependencies": ["Kangaroo2", "LunchBox"],
"componentCount": 45,
"connectionCount": 12,
"groupCount": 3
}
}
| Property | Type | Description |
|---|---|---|
description |
string | Description of the definition |
author |
string | Author name |
version |
string | Definition version |
created |
string | ISO 8601 creation timestamp |
modified |
string | ISO 8601 modification timestamp |
rhinoVersion |
string | Target Rhino version |
grasshopperVersion |
string | Target Grasshopper version |
dependencies |
string[] | Required plugin dependencies |
componentCount |
integer | Total component count |
connectionCount |
integer | Total connection count |
groupCount |
integer | Total group count |
Components are the core elements of a GhJSON document. Each component represents a Grasshopper component or parameter on the canvas.
{
"name": "Addition",
"library": "Maths",
"nickName": "Add",
"componentGuid": "a0d62394-a118-422d-abb3-6af115c75b25",
"instanceGuid": "12345678-1234-1234-1234-123456789abc",
"id": 1,
"pivot": "100,200",
"properties": {
"NickName": "Custom Name"
},
"inputSettings": [ ... ],
"outputSettings": [ ... ],
"componentState": { ... }
}
| Property | Type | Required | Description |
|---|---|---|---|
name |
string | Conditional | Display name of the component |
library |
string | No | Component library/category |
nickName |
string | No | Custom nickname |
componentGuid |
uuid | No | Component type GUID |
instanceGuid |
uuid | No | Instance GUID |
id |
integer | Conditional | Integer ID for references (required when referenced by connections/groups) |
pivot |
string | No | Canvas position (compact string format: “X,Y”) |
properties |
object | No | Simple key-value properties |
inputSettings |
array | No | Input parameter settings |
outputSettings |
array | No | Output parameter settings |
componentState |
object | No | UI-specific state |
warnings |
string[] | No | Warning messages |
errors |
string[] | No | Error messages |
The pivot property uses a compact string format:
"pivot": "100.5,200.25"
Components can be identified with any of these combinations (schema uses anyOf):
name with compact integer idname plus instanceGuidcomponentGuid plus idcomponentGuid plus instanceGuidYou MAY include both componentGuid and name together. For reliable instantiation, include componentGuid and an id when the component will be referenced by connections or groups.
The id property provides a compact integer reference for use in connections and groups. IDs:
Connections represent the wires between component parameters.
{
"connections": [
{
"from": { "id": 1, "paramIndex": 0 },
"to": { "id": 2, "paramIndex": 0 }
}
]
}
| Property | Type | Required | Description |
|---|---|---|---|
from |
endpoint | Yes | Source endpoint (output) |
to |
endpoint | Yes | Target endpoint (input) |
| Property | Type | Required | Description |
|---|---|---|---|
id |
integer | Yes | Component integer ID |
paramName |
string | Conditional | Parameter name (required if paramIndex is not provided) |
paramIndex |
integer | Conditional | Zero-based parameter index (required if paramName is not provided) |
The paramIndex provides reliable parameter matching when parameter names may vary due to localization or custom nicknames.
Groups organize components visually on the canvas.
{
"groups": [
{
"instanceGuid": "abcd1234-5678-90ab-cdef-1234567890ab",
"id": 1,
"name": "Input Parameters",
"color": "255,200,220,255",
"members": [1, 2, 3]
}
]
}
| Property | Type | Required | Description |
|---|---|---|---|
instanceGuid |
uuid | Conditional | Group instance GUID (required if id is not provided; both may be present) |
id |
integer | Conditional | Group integer ID (required if instanceGuid is not provided; both may be present) |
name |
string | No | Group name/nickname |
color |
string | No | ARGB color (A,R,G,B format), each channel 0–255 |
members |
integer[] | Yes | Component IDs in this group |
GhJSON uses prefixed string formats for geometric and special data types.
| Type | Format | Example |
|---|---|---|
| Text | text:value |
"text:Hello World" |
| Number | number:value |
"number:3.14159" |
| Integer | integer:value |
"integer:42" |
| Boolean | boolean:value |
"boolean:true" |
| Type | Format | Example |
|---|---|---|
| Point | pointXYZ:x,y,z |
"pointXYZ:1,2,3" |
| Vector | vectorXYZ:x,y,z |
"vectorXYZ:0,0,1" |
| Line | line2p:x1,y1,z1;x2,y2,z2 |
"line2p:0,0,0;1,0,0" |
| Plane | planeOXY:ox,oy,oz;xx,xy,xz;yx,yy,yz |
"planeOXY:0,0,0;1,0,0;0,1,0" |
| Circle | circleCNRS:cx,cy,cz;nx,ny,nz;r;sx,sy,sz |
"circleCNRS:0,0,0;0,0,1;5;1,0,0" |
| Arc | arc3P:x1,y1,z1;x2,y2,z2;x3,y3,z3 |
"arc3P:0,0,0;1,1,0;2,0,0" |
| Box | boxOXY:ox,oy,oz;xx,xy,xz;yx,yy,yz;x0,x1;y0,y1;z0,z1 |
See spec |
| Rectangle | rectangleCXY:cx,cy,cz;xx,xy,xz;yx,yy,yz;w,h |
See spec |
| Interval | interval:min<max |
"interval:0<10" |
| Color | argb:a,r,g,b |
"argb:255,128,64,32" |
Number sliders use a compact value format:
{
"name": "Number Slider",
"componentState": {
"value": "5.5<0,10>"
}
}
Format: value<min,max> where:
value is the current valuemin is the minimum valuemax is the maximum valueAdditional properties:
rounding: Rounding mode (“Round”, “None”, “Even”, “Odd”){
"name": "Panel",
"componentState": {
"value": "Hello World",
"multiline": true,
"wrap": true,
"drawIndices": false,
"drawPaths": true,
"alignment": 0,
"bounds": "150x100"
}
}
{
"name": "Value List",
"componentState": {
"value": [
{ "Name": "Option A", "Expression": "0" },
{ "Name": "Option B", "Expression": "1" },
{ "Name": "Option C", "Expression": "2" }
],
"listMode": "DropDown",
"selectedIndices": [0]
}
}
List modes: DropDown, CheckList, Sequence, Cycle, Toggle
{
"name": "C# Script",
"inputSettings": [
{
"parameterName": "x",
"variableName": "x",
"typeHint": "double",
"access": "item"
}
],
"outputSettings": [
{
"parameterName": "A",
"variableName": "A",
"typeHint": "object"
}
],
"componentState": {
"value": "A = x * 2;",
"marshInputs": true,
"marshOutputs": true,
"showStandardOutput": false
}
}
VB Script components have three code sections:
{
"name": "VB Script",
"componentState": {
"vbCode": {
"imports": "Imports System.Math",
"script": "A = Sin(x)",
"additional": "' Helper functions here"
}
}
}
{
"name": "Scribble",
"componentState": {
"value": "Design Notes",
"font": {
"name": "Arial",
"size": 14,
"bold": true,
"italic": false
},
"corners": [
"100,100",
"300,100",
"300,200",
"100,200"
]
}
}
GhJSON documents SHOULD validate against the JSON Schema at:
https://architects-toolkit.github.io/ghjson-spec/schema/v1.0/ghjson.schema.json
Beyond schema validation, implementations SHOULD verify:
id values are uniqueid values reference existing componentsparamName values exist on referenced componentsmembers reference existing component IDsWhen deserializing, implementations MAY additionally verify:
componentGuid or name matches an installed component{
"components": [
{
"name": "Number Slider",
"instanceGuid": "11111111-1111-1111-1111-111111111111",
"id": 1,
"pivot": "100,100",
"componentState": { "value": "5<0,10>" }
}
]
}
{
"schemaVersion": "1.0",
"components": [
{
"name": "Number Slider",
"instanceGuid": "11111111-1111-1111-1111-111111111111",
"id": 1,
"pivot": "100,100",
"componentState": { "value": "5<0,10>" }
},
{
"name": "Number Slider",
"instanceGuid": "22222222-2222-2222-2222-222222222222",
"id": 2,
"pivot": "100,150",
"componentState": { "value": "3<0,10>" }
},
{
"name": "Addition",
"componentGuid": "a0d62394-a118-422d-abb3-6af115c75b25",
"instanceGuid": "33333333-3333-3333-3333-333333333333",
"id": 3,
"pivot": "300,125"
},
{
"name": "Panel",
"instanceGuid": "44444444-4444-4444-4444-444444444444",
"id": 4,
"pivot": "500,125"
}
],
"connections": [
{ "from": { "id": 1, "paramName": "Number" }, "to": { "id": 3, "paramName": "A" } },
{ "from": { "id": 2, "paramName": "Number" }, "to": { "id": 3, "paramName": "B" } },
{ "from": { "id": 3, "paramName": "Result" }, "to": { "id": 4, "paramName": "Input" } }
]
}
{
"schemaVersion": "1.0",
"metadata": {
"description": "Simple addition example",
"author": "GhJSON Team",
"created": "2026-01-11T10:00:00Z"
},
"components": [
{
"name": "Number Slider",
"instanceGuid": "11111111-1111-1111-1111-111111111111",
"id": 1,
"pivot": "100,100",
"componentState": { "value": "5<0,10>" }
},
{
"name": "Number Slider",
"instanceGuid": "22222222-2222-2222-2222-222222222222",
"id": 2,
"pivot": "100,150",
"componentState": { "value": "3<0,10>" }
},
{
"name": "Addition",
"instanceGuid": "33333333-3333-3333-3333-333333333333",
"id": 3,
"pivot": "300,125"
}
],
"connections": [
{ "from": { "id": 1, "paramName": "Number" }, "to": { "id": 3, "paramName": "A" } },
{ "from": { "id": 2, "paramName": "Number" }, "to": { "id": 3, "paramName": "B" } }
],
"groups": [
{
"instanceGuid": "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa",
"name": "Inputs",
"color": "255,200,220,255",
"members": [1, 2]
}
]
}
The recommended MIME type for GhJSON files is:
application/vnd.grasshopper.ghjson+json
The GhJSON schema is registered at:
| Version | Date | Changes |
|---|---|---|
| 1.0 | 2026-01-11 | Initial specification |