Skip to content

document.json

document.json is the editable project and the single source of truth. Everything else in the archive is either derived from it or metadata about it.

This page describes the structure a reader can rely on. It does not enumerate every parameter — the parameter set grows additively with the application, and enumerating it here would create a document that is wrong by the next release. For the exhaustive, authoritative definitions, read the Codable types in the reference implementation under Packages/Core/Sources/DocumentKit/.

If you only need stitches, you do not need this page at all — see plan.json.

{
"formatVersion": 1,
"id": "<uuid>",
"meta": { "title": "Cherry", "createdAt": , "modifiedAt": , "appVersion": "0.1" },
"hoop": { "name": "130 × 180 mm", "widthMM": 130, "heightMM": 180 },
"palette": [ { "red": 47, "green": 48, "blue": 50,
"catalogId": "madeira-polyneon", "code": "1800", "name": "Black" } ],
"projectColors": [ ],
"groups": [ { "id": "<uuid>", "name": "Cherry 1 blend", "joined": false } ],
"references": [ ],
"objects": [ ],
"settings": { "maxTravelMM": 6, "fabric": "knit", }
}

All coordinates are millimetres, hoop-centred, y up — the same system as plan.json.

Ordered thread colours. Objects reference them by index, which makes the array structural: an entry an object refers to MUST NOT be removed, and reordering it changes the design. Fields are the same as in the plan’s colorTable.

projectColors is a separate, non-structural convenience list — the user’s quick-access swatches. Nothing references it by index; a reader may ignore it.

Named groupings of consecutive objects. joined: true marks a group whose members were welded into one continuous stitch path rather than merely grouped. Membership is expressed on the objects, not here.

Trace images the design was drawn over: { id, name, centerMM, widthMM, opacity }. This is metadata only — the image bytes live in the archive under references/<uuid>.<ext>, matched by the lowercased UUID prefix of the entry name. See Container.

Project-wide values, for example maxTravelMM (the distance beyond which a connection becomes a trim rather than a stitched travel), the target fabric, and the display unit. Additive: expect keys you do not know.

The design itself. Array order is stitch sequence — the first object is sewn first, and that is also the drawing order, so later objects sit on top of earlier ones.

{
"id": "<uuid>",
"kind": "fill",
"name": "Fill 1",
"isVisible": true,
"isLocked": false,
"colorIndex": 0,
"displayOpacity": 1.0,
"geometry": { "region": { "outer": [ ], "holes": [ ] } },
"params": { "densityMM": 0.35, "stitchLengthMM": 2.5, "angleDeg": 45, }
}
FieldMeaning
idStable identity. Matches objectID in the plan’s objectRanges.
kindrun, satin, fill or manualStitch.
nameUser-facing label.
isVisibleHidden objects are not stitched.
isLockedEditing guard. Has no effect on output.
colorIndexIndex into palette.
displayOpacityCanvas display only. The stitch file always sews solid thread.
geometryOne of four cases, below.
paramsGenerator parameters for this object’s kind.

Optional per-object fields (absent means the default):

FieldValuesMeaning
groupIDuuidMembership in a groups entry.
postCommandnone | stop | colorChangeA manual machine command after this object. stop pauses without a thread change (trapunto, appliqué); colorChange forces a stop even for the same thread.
trimAfterauto | always | neverThread handling toward the next object. never connects with an uncut jump regardless of distance.
directionLockedbooleanThe stitch angle is governed by the object’s group rather than itself (blend groups share one axis).

Exactly one of four cases, encoded as a single-key object:

CasePayloadUsed by
centerline{ "points": [ … ] }Runs, and satins defined by a centre line plus a width
rails{ "railA": [ … ], "railB": [ … ] }Satins digitised as two rails
region{ "outer": [ … ], "holes": [[ … ], … ] }Fills, with optional holes
points{ "points": [ … ] }Manual stitches

Points are { "x": Double, "y": Double } in millimetres. Rails in the rails case are index-paired: railA[i] faces railB[i], and the pairing is what defines each stitch, not arc length. A reader that re-samples one rail without the other destroys the column.

Generator parameters. Which keys are meaningful depends on kind — a fill ignores satinWidthMM, a run ignores angleDeg. Common ones include stitchLengthMM, densityMM, angleDeg, pullCompMM, passes, underlay, tieIn/tieOff, capStart/capEnd, plus feature-specific sub-objects such as fillPattern, fillGuides, sashiko, satinEdge and foam.

This set grows. New keys appear in minor revisions without a formatVersion bump, and a reader MUST ignore the ones it does not know (compatibility rules).

document.json describes intent, not output. The number of stitches an object produces, where its seam lands, whether a connection becomes a trim — all of that is the result of running a generator over these parameters, and it is not recorded here. If you need the stitches, read the plan; if you need to regenerate them yourself, you are re-implementing the generators, and this file is the input, not the answer.