Plain JSON
A .xcs file is a single JSON document in UTF-8, not an archive. Open one in a text editor and you'll see keys such as canvasId, canvas, device, version and often cover, a base64 PNG of the design used as its preview. A ua string records which program saved it, such as xToolCreativeSpace/2.6.38 or xToolStudio/1.6.8, and extName names the machine, like S1, P2 or F1 Ultra.
Canvases and layers
canvas is a list, because a project can have several canvases. Each has an id, a title (often a translation key such as {panel}1), a displays list of objects and a layerData table keyed by colour, for example "#fe0002": {"name": "{Red}", "order": 1, "visible": true}. Each object names its colour in layerColor.
Objects and their transform
Object types seen in real files include PATH (SVG path data in dPath), RECT, CIRCLE, LINE (with an endPoint), POLYGON (a flat points list), REGULAR_POLYGON, PEN, TEXT, BITMAP and QRCODE. Each carries x, y, width, height, angle in degrees, scale, skew in radians, and offsetX/offsetY. Units are millimetres with Y pointing down. The local drawing maps onto the canvas by the matrix
a = cos(angle + skew.y) × scale.x b = sin(angle + skew.y) × scale.x
c = −sin(angle − skew.x) × scale.y d = cos(angle − skew.x) × scale.y
e = offsetX f = offsetY
and x, y are where the local box's top-left corner lands. A skew of π mirrors an object. Boxes such as rectangles and pictures have their local size at width / scale.x by height / scale.y. Text keeps one positioned PATH per letter in charJSONs, already placed on the canvas, which is why lettering survives without the font.
Laser settings
Settings live under device.data, a map written as {"dataType": "Map", "value": [[key, value], …]}. It is keyed by canvas id, and each canvas holds another map keyed by object id. Every object records a processingType, such as VECTOR_CUTTING (Cut), VECTOR_ENGRAVING (Score), FILL_VECTOR_ENGRAVING (fill engrave) or BITMAP_ENGRAVING, plus a block for each type with power in percent, speed in mm/s, repeat for passes and, for engraving, density in lines per centimetre. A materialType says whether xTool's own preset or the user's custom values apply.
The .xs format
xTool Studio 1.7 and later save .xs files: a ZIP holding project.json, profiles.json, one JSON file per canvas, displays in chunks, and a device file whose bindings tie objects to setting profiles. Long paths can sit in a separate vectors/ store, referred to by hash. The objects themselves have the same shape as in .xcs.
How we checked it
Kerfview's reader is its own code. On publicly shared projects saved by many versions of xTool's software, the shapes it draws match the proportions of the preview xTool saved in each file. Other open projects that read the format include xcsReader and unofficial-xcs-writer.