Drawings are stored in the app’s private storage, one folder per drawing (ADR 0010):
<app support directory>/
├── settings.json # app preferences
├── drawings/
│ └── <id>/
│ ├── drawing.json # the drawing (this document)
│ ├── history.json # undo/redo history (optional)
│ ├── meta.json # dates used by the gallery
│ └── thumbnail.png # gallery thumbnail
└── trash/
└── <id>/ # same layout, plus "deletedAt" in meta.json
Every file is written atomically: to <name>.tmp first, then renamed.
drawing.json{
"schemaVersion": 6,
"revision": 12,
"sheet": { "width": 1114, "height": 663 },
"background": { "color": 4294967295, "pattern": "lines" },
"elements": [
{
"type": "stroke",
"id": "9f2c…",
"tool": "crayon",
"color": 4293212486,
"width": 10,
"points": [120.5, 88, 0.5, 0, 131.25, 90.5, 0.5, 16],
"erasures": [
{ "id": "41ab…", "width": 20, "points": [125, 60, 0.5, 0, 126, 120, 0.5, 40] }
]
},
{
"type": "text",
"id": "77d0…",
"text": "Ciao nonna!",
"color": 4287513773,
"font": "playwrite",
"fontSize": 48,
"transform": { "x": 540, "y": 120, "scale": 1.4, "rotation": -0.2 }
}
]
}
| Field | Meaning |
|---|---|
schemaVersion |
Format version. Readers migrate older versions and refuse newer ones. |
revision |
Increases at every save; history.json must carry the same value. |
sheet |
Fixed sheet size in sheet units (not pixels). |
background |
Paper color (ARGB) and pattern: none, lines, bigSquares, smallSquares or dots. Omitted for plain white paper. One printed centimeter is the sheet’s long side divided by 29.7 (an A4 page). |
outline |
The coloring page the drawing started from (ADR 0022): {"pack": "pastello-nature", "page": "house"}, the ids of a content pack and of one of its pages. Omitted for a blank sheet. The artwork is not copied: a missing pack shows a placeholder. |
elements |
Elements from bottom to top (z-order). |
Any element may have a transform (omitted when it changes nothing): the
element is described in local coordinates, scaled by scale, rotated by
rotation (radians, clockwise on screen) and moved by x, y.
| Field | Meaning |
|---|---|
text |
The text; lines are separated by \n. |
color |
ARGB as a 32-bit integer. |
font |
andika, playwrite, fredoka or comicNeue. |
fontSize |
Size in sheet units, before the transform’s scale. |
The local origin of a text is the center of its box.
{ "type": "sticker", "id": "c1f0…", "pack": "fluent-animals", "item": "dog_face", "size": 160 }
| Field | Meaning |
|---|---|
pack, item |
Which sticker, in which content pack (ADR 0018). The artwork is not copied into the drawing. |
size |
Side of the sticker’s square, in sheet units, before the transform’s scale. |
A sticker whose pack is not installed is drawn as a “?” placeholder; the reference is kept, so it reappears when the pack is installed.
{ "type": "shape", "id": "5e2a…", "kind": "star", "extent": [120, 110], "color": 4280110296, "strokeWidth": 10, "filled": true }
| Field | Meaning |
|---|---|
kind |
ellipse, rectangle, triangle, star, heart, line or arrow. |
extent |
Figures: width and height of the box they are inscribed in. Lines and arrows: vector from start to end (it can be negative). The local origin is the center. |
color, strokeWidth |
Outline (and fill) color, outline width in sheet units. |
filled |
Present and true for filled figures; lines are never filled. |
The area colored by a tap of the paint bucket (ADR 0021). Fills are painted under every other element, newer fills above older ones.
{ "type": "fill", "id": "8c1d…", "color": 4294956554, "left": 102, "top": 64, "rows": [[0, 96], [0, 40, 52, 44]] }
| Field | Meaning |
|---|---|
color |
ARGB as a 32-bit integer. |
left, top |
Sheet column and row of the mask’s origin, in whole sheet units. |
rows |
One list per row, from top down: start, length pairs of colored pixels, start relative to left, sorted and not touching. One pixel is one sheet unit. |
erasures |
Eraser passes attached to this fill, as for strokes. |
| Field | Meaning |
|---|---|
id |
32 hex characters, unique in the drawing. |
tool |
pencil, marker, brush, crayon, rainbow, highlighter, neon, glitter, stars, spray or watercolor. |
color |
ARGB as a 32-bit integer (ignored by rainbow). |
width |
Base width in sheet units. |
points |
Flat list of x, y, pressure, time quadruples: sheet units, 0–1, milliseconds since the stroke started. Rounded to hundredths. |
seed |
Only for glitter, stars, spray and watercolor: places their random pieces, so a reopened drawing looks exactly the same. Their points are stored as drawn, not simplified. Missing means 0. |
erasures |
Eraser passes attached to this stroke, in the stroke’s local coordinates. The same pass (same id) is attached to every stroke and fill it touched. Texts, stickers and shapes are never erased. |
history.json{
"schemaVersion": 6,
"revision": 12,
"undo": [ { "type": "add", "stroke": { … } } ],
"redo": []
}
Commands: add (element), update (before, after: the same element
moved, resized, rotated or edited), delete (element, index in the
z-order), erase (sheetErasure as drawn, and erasures: the pass in each
touched stroke’s coordinates, by stroke id) and clear (removed: the
elements that were on the sheet), batch (commands: several commands
applied as one undo step, for lasso selections), background (before,
after). Version 1 forms (add with stroke,
erase with erasure and strokeIds) are still read. At most 100 undo steps are
kept. If revision does not match drawing.json, or the file cannot be read,
the history is discarded and the drawing is opened without it
(ADR 0007).
meta.json{ "createdAt": "2026-10-24T18:02:11.000", "updatedAt": "2026-10-24T18:40:03.000" }
Files in the trash also have deletedAt; they are purged 30 days later.
“Export all drawings” in the parents’ page writes a .zip (ADR 0020):
pastello-backup.json
drawings/
└── <id>/ # 32 hexadecimal characters
├── drawing.json
├── history.json
├── meta.json
└── thumbnail.png
pastello-backup.json holds the backup format (currently 1), the app
version that wrote it and the date:
{ "format": 1, "appVersion": "1.1.0 (2)", "createdAt": "2026-10-30T18:00:00.000" }
The trash is not exported. On import, entries outside this layout are
ignored, drawings already in the gallery or in the trash are skipped, and a
drawing that cannot be decoded (for example from a newer schema version) is
skipped and reported. A missing or damaged meta.json is replaced with the
import date; a thumbnail that is not a PNG is dropped.
| Version | Changes |
|---|---|
| 1 | Strokes and erasures. |
| 2 | Texts, element transforms, update and delete commands. Version 1 files are read as they are. |
| 3 | Stickers. Older files are read as they are. |
| 4 | Shapes. Older files are read as they are. |
| 5 | Paper color and pattern. Older files are read as they are (white paper). |
| 6 | Magic brushes: highlighter, neon, glitter, stars, spray and watercolor strokes, stroke seed. Paint bucket fills. Coloring page outline. Older files are read as they are. |
drawingSchemaVersion in packages/pastello_engine.migrateDrawingJson and a test with a file in the
old format.