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, and — since writers
need names, not prose — the stitch parameters as they stand today. That
table is a snapshot: the parameter set grows additively with the
application, so treat it as enough to get started, never as a closed list.
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.
Every field is optional on read: a reader substitutes the default for
anything absent, so a writer only sets what its object kind actually uses.
The table below is what a writer needs to produce a design today. It is a
snapshot, not a closed list — the 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).
| Field | Type | Default | Applies to | Meaning |
|---|---|---|---|---|
stitchLengthMM | number | 2.2 | run, fill | Length of one stitch along a run, a fill row, or a travel. |
passes | integer | 1 | run | 1 single, 3 bean/triple, 5 heavy. |
densityMM | number | 0.4 | satin, fill | Satin: spacing between penetrations along the column. Fill: spacing between rows. Smaller is denser. |
autoSpacing | boolean | true | satin | Local column width scales the spacing; densityMM is the baseline at 3 mm width. |
angleDeg | number | 45 | fill | Scanline angle; 0 is horizontal rows. Ignored by ring fills and guided fills. |
fillPattern | enum | diagonal | fill | diagonal, brick, scatter, wave, chevron, contour (shown as Ring in the app since 0.9.1 — the raw value stays for compatibility), guided, sashiko. |
pullCompMM | number | 0.2 | satin, fill | Outward widening per side against thread pull. |
satinWidthMM | number | 3.0 | satin | Column width for satins drawn as a stroke; the stored rails derive from it. |
capStart, capEnd | enum | flat | satin | flat, round or point. Open columns only. |
tieIn, tieOff | enum | standard | all | none, small or standard. |
underlay | object | see below | satin, fill | Foundation under the cover. |
satinEdge | object | disabled | fill | Automatic satin border around a fill. |
foam | object | disabled | satin | 3D puff foam under the column. |
sashiko | object | see below | fill | Read only when fillPattern is sashiko. |
accordion | object | disabled | satin | Spacing that travels along the column, so the fabric shows through at one end. |
fillGuides | array of point arrays | [] | fill | Flow lines for guided fills: one line means rows run parallel to it, two or more make the angle interpolate between them. |
fillGuide | point array | absent | fill | Legacy. A single flow line, written by versions before fillGuides existed. Readers should treat a present fillGuide as the first entry of fillGuides; writers should not emit it. |
shading | object | absent | fill | Gradient shading of a blend member. Omit unless you are building blend groups. |
underlay:
| Field | Type | Default | Meaning |
|---|---|---|---|
enabled | boolean | true | Underlay on or off. |
firmness | enum | auto | auto, light, standard, firm or custom. Everything except custom overrides types; custom uses types verbatim. |
types | array of enum | ["centerRun","zigzag"] | edgeRun (inset contour run), centerRun (down a satin spine), zigzag (coarse, under satin), tatamiLight (coarse cross-hatch, under fill). |
insetMM | number | 0.4 | Inward inset so the underlay never peeks out. |
densityMM | number | 2.0 | Spacing of underlay penetrations. |
doubleCross | boolean | false | Fill only: two diagonal passes instead of one. |
satinEdge: enabled (boolean, false), widthMM (number, 1.0),
insetMM (number, 0).
foam: enabled (boolean, false), densityMM (number, 0.3),
tearInsetMM (number, 0.5).
sashiko: motif (grid, asanoha, seigaiha, kikko or igeta),
scaleMM (number, 8), stitchLengthMM (number, 2.5), angleDeg
(number, 0), insetMM (number, 0.5), passes (integer, 1).
accordion: profile (off, fadeOut, fadeIn, bothEnds or
feather), openMM (number, 1.4 — the spacing reached at the open end,
against densityMM at the dense end), and the optional pair axisStart /
axisEnd (points). Without the axis each column fades over its own
length; with it, every column measures its position along that one line,
which is how a word fades across its letters rather than each letter
fading by itself. profile: off means the whole object is unaffected —
that is the value in almost every file.
These are design values. A generator may compensate them when it
derives stitches — StitchPencil tightens density, underlay and pull
compensation for knit and pile fabrics (settings.fabric) — without ever
writing the compensated numbers back into the object.
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.