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.
Top level
Section titled “Top level”{ "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.
palette
Section titled “palette”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.
groups
Section titled “groups”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.
references
Section titled “references”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.
settings
Section titled “settings”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.
objects
Section titled “objects”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, … }}| Field | Meaning |
|---|---|
id | Stable identity. Matches objectID in the plan’s objectRanges. |
kind | run, satin, fill or manualStitch. |
name | User-facing label. |
isVisible | Hidden objects are not stitched. |
isLocked | Editing guard. Has no effect on output. |
colorIndex | Index into palette. |
displayOpacity | Canvas display only. The stitch file always sews solid thread. |
geometry | One of four cases, below. |
params | Generator parameters for this object’s kind. |
Optional per-object fields (absent means the default):
| Field | Values | Meaning |
|---|---|---|
groupID | uuid | Membership in a groups entry. |
postCommand | none | stop | colorChange | A manual machine command after this object. stop pauses without a thread change (trapunto, appliqué); colorChange forces a stop even for the same thread. |
trimAfter | auto | always | never | Thread handling toward the next object. never connects with an uncut jump regardless of distance. |
directionLocked | boolean | The stitch angle is governed by the object’s group rather than itself (blend groups share one axis). |
geometry
Section titled “geometry”Exactly one of four cases, encoded as a single-key object:
| Case | Payload | Used 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.
params
Section titled “params”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).
What a reader should not conclude
Section titled “What a reader should not conclude”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.