How editing works
The model behind the canvas — what is parsed, what is written back, and why your diffs stay small.
Stacki is a file editor with a visual surface, not a project format. Everything below explains what that costs and what it guarantees.
The model
A page is parsed into a tree: an optional layout wrapper, then nodes — elements,
component instances, text, expressions, loops, conditions, comments, and raw
blocks like <style> and <script>. Each node carries its props and its
children.
The panels edit that tree. Saving writes it back as Astro source.
Saving
Edits are written about 300ms after you stop typing. There is no save button; the file on disk is what the canvas is rendering, which is why the preview and the file can never disagree.
Your formatting survives
Writing the tree back naively would reformat the whole file, and a save that reformats is a save you cannot review. So each node is compared against what it was: rebuild it the way Stacki would write it from scratch, and if that says the same thing the original said, hand back the original.
Kept as written: import quote style, blank lines between nodes and at the end of
the file, multi-line attributes, the text of a loop head or condition, a closing
bracket on its own line, <x/> versus <x />, and a file with no frontmatter.
Editing a node reflows that node. Across 54 real files, 53 round-trip byte for byte when nothing has been edited.
When the model cannot hold a file
Arbitrary expressions, unusual nesting, markup Stacki cannot represent — the page opens in the code editor instead of the canvas, with live preview still running. It is never partially converted and never rewritten destructively.
The dev server
Stacki runs the project’s own astro dev with a generated config layered on top
— that config is what injects the markers the canvas uses to map a click back to
a node in the file. Those markers exist only in the dev rendering; they are not
in your source and not in your build.
If the generated config ever fails to load, the preview starts on the project’s own config rather than not starting at all.