3. The top-level object

A design file is one JSON object with five members, written in this order:

A design file is one JSON object with five members, written in this order:

json
{
  "$schema": "https://raw.githubusercontent.com/arthurafarias/vscode-extension-ui-designer/master/schemas/design-1.0.schema.json",
  "$comment": "SoftForge UI Designer design file (FMT-001). Do not edit `tree`. To change the design, append one event per line to `wal`, starting the line with a comma, or use the `ud` command.",
  "designVersion": "1.0",
  "tree": { },
  "wal": [
    {"seq":0,"op":"wal.base","epoch":"ep-0c2e4a6b8d1f","treeHash":"sha256:…"}
  ]
}
Member Type Meaning When it is missing or wrong
$schema string URL of the JSON Schema of this format version (section 11). Editors use it for completion and validation. Ignored; written again with the next change.
$comment string Instructions for agents and people who open the file as text. The text above, verbatim. Ignored; written again with the next change.
designVersion string Format version, "<major>.<minor>". This document describes "1.0". Read before anything else (section 10). Read as the current version, with a warning.
tree object The consolidated document (section 4). An empty document with one page (section 9.1).
wal array The wal.base marker followed by the events since the last consolidation (section 5). An empty list.

Members a reader does not know are kept and written back unchanged.

3.1 Layout on disk#

Writers produce one fixed layout:

  • the five members in the order shown, indented by two spaces;
  • the tree pretty printed with two spaces per level;
  • the WAL with one entry per line: first the wal.base marker, indented by four spaces, then every event as four spaces, a comma, and the event as compact JSON without any space or line break (line breaks inside texts are written as \n by JSON);
  • event members in the order seq, at, by, op, group, note, then the payload;
  • a line break at the end of the file.

Saving a change therefore produces this diff, and nothing else:

diff
--- a/login.design
+++ b/login.design
@@ -301,5 +301,6 @@
     {"seq":12,"at":"2026-10-05T16:40:00.000Z","op":"wal.base","epoch":"ep-9b7d5f3a1c0e","treeHash":"sha256:6f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0"}
     ,{"seq":13,"at":"2026-10-06T09:12:30.412Z","by":"Ada","op":"node.update","id":"nd-9f1b3d5c7e2a","set":{"characters":"Sign in to SoftForge"}}
+    ,{"seq":14,"at":"2026-10-06T09:20:04.118Z","by":"Ada","op":"node.update","id":"nd-4c6e8a0b2d1f","set":{"paddingTop":48}}
   ]
 }

The layout is a convention for git, not a requirement for reading: a reader parses the file as ordinary JSON and accepts any spacing. A writer that changes a file whose layout differs (hand edited, or repaired, section 9) writes it in the canonical layout at that moment.

The tree is written in a stable order so that two consolidations of the same document give the same text: pages by index; nodes depth-first, page by page, siblings by index; other maps by index where they have one, else by id; members of an object in the order of the tables of section 4, unknown members last.

An empty file (zero bytes or only white space) is a document that has not been written yet: the editor opens it as a blank design with one page and writes the file with the first change.