AshSDUI prefers the smallest declarative surface that can still describe the screen. The package is designed around an authoring ladder, not around one mandatory abstraction.

The preferred ladder

The first stop is usually AshSDUI.LiveResource with resource metadata: view, ui_field, ui_intent, ui_query, and ui_binding. That path keeps the screen close to Ash metadata and lets generated forms and actions use one source of truth.

The next step is ash_sdui_view_opts/4 and recipe_overrides, which change presentation without discarding the generated host. After that comes a custom recipe, which still keeps the screen metadata-first while letting the page shell come from a layout tree. Only after those layers stop fitting should a screen move to a custom render/1 or a fully custom LiveView.

Why metadata is the source of truth

The package prefers metadata because duplicated UI declarations drift. Labels, widgets, and action intent become harder to trust when they are spread across UI modules, form components, LiveViews, and Storybook stories.

By keeping ui_field and ui_intent authoritative, AshSDUI can drive generated forms, actions, and proof surfaces from one place. This makes authoring smaller and safer for humans and agents.

The three layout paths

There are three distinct layout paths in the package.

Generated layout: :sdui views still start from view metadata. A recipe turns the resolved view into a layout tree, so the screen stays generated even though its final page shell is custom.

Ephemeral layouts are built directly in a LiveView from current records, mode switches, or runtime assigns. AshSDUI.LiveScreen.assign_layout/3 exists for this case because the layout is real, but it does not need persistence.

Persisted layouts are named layout trees stored through AshSDUI.Layout. They support draft and publish workflows and can later be reloaded without changing application code.

Why the layout API stays small

The package deliberately centers the layout API on fetch/2, register/2, save/3, and publish/2, with AshSDUI.Layout.Builder.resource/2 and resources/3 as the preferred authoring helpers. This keeps the public surface small while still covering code-authored, ephemeral, and persisted layouts.

That is also why AshSDUI.Layout.Persistence is no longer the documented path. It remains for compatibility, but it is not the abstraction the package wants new code to learn first.