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.