Authoring walkthrough

How a component comes to life in Milda - from picking an archetype in the Studio to installing generated code - told from the language's point of view. Every click in the editor is writing the model described in the previous pages; this walkthrough makes that mapping visible.

We'll build a Button end to end, then sketch a Select to show how the same steps scale to a genuinely hard component.

#1. Pick an archetype

A new component starts from a blueprint, not a blank canvas. You pick Button from the archetype catalog, and with that one choice the component already meanssomething: its contract is “label/icon, fires an action”, and its behavior bundle - activation for the action, pressability for press/hover feedback - comes along for free. You never wire a click handler; firing the action is a contract obligation the archetype carries on every platform.

#2. Anatomy appears

The archetype's published anatomy materializes as the component's structure: an optional icon part and a labelpart. Parts are platform-neutral - the Studio never shows you an HTML tag, because the model doesn't contain one; the element is the generator's decision. You can skip optional parts, add nodes within what the content model allows, and group them - structure editing is editing the anatomy tree.

#3. Shape the contract

The Interface panel is where the component's public API lives - the part consumers of your generated library will see:

  • Props - bind the label part's text to a label prop. Names are neutral identifiers; each generator applies its own casing conventions.
  • Events - the archetype's activation already emits an action event; you surface it under the name you want.
  • Slots- expose a part as a consumer-fillable insertion point with an arity and a content contract. Slots are the component's children API.
  • Variants & sizes - declare variant and size props typed by context groups. They are not string switches: a context-typed prop plugs into the token-resolution machinery, which is what makes step 4 pay off.

#4. Bind facets to tokens

Styling the button means setting facets on parts: fill to an accent token, ink to a foreground token, corner to a radius role, inset for padding. Because every value is a token reference, the button automatically follows color scheme, density, brand - and platform. If variant is a context group, the solid and outline looks are just token aliases keyed by it; no conditional style logic exists anywhere.

#5. States & conditions

The Style tab offers condition axes - variant, size, and state. The states on offer are exactly what the composed behaviors emit: pressability contributes pressed and hovered, the ambient gate contributes disabled. You add “when pressed, darken the fill” as a state-keyed facet override. The editor can force each state in preview so you can see every combination without hunting for it.

#6. Preview

The Stage renders the component from the model, live - the same IR the generators will consume, realized by the editor's own preview. Browse with the keyboard, force states, switch variants through the prop bar. What you are testing is the model, not a prototype that will be rewritten later.

#7. Generate & release

A release runs the generator for each of the project's targets - React first - and publishes a versioned package to your registry. Versioning is computed from the contract: a contract-preserving change is a patch/minor, a breaking contract change bumps the major. The language's “contract is the identity” rule is what makes that computable.

#The same arc, for a Select

Now the payoff. Pick SingleSelect and the hard parts arrive already solved:

  1. The anatomy is a tree - trigger (with value and indicator) and surface (with option, its optional check, and label).
  2. Five behaviors come pre-wired: activation toggles the presentation, browse moves the highlight, selection commits the value, dismiss closes on outside/escape. Keyboard navigation, typeahead, and the open/close/commit choreography are the archetype's responsibility, not yours.
  3. The contract needs an options collection prop and a bound value; the change event comes from the selection atom.
  4. Styling keys on behavior states: option gets active (the browse highlight) and selected overrides; trigger gets an open state and a focus ring; the surface gets elevation - which resolves per platform through token aliasing.

Your work is the same kind of work as for the Button - contract, tokens, states - while the interaction engineering that usually makes selects a multi-week project is carried by the language.

#What you never do

  • Write platform code. No CSS, no HTML tags, no React. The Studio authors the neutral model; generators own everything platform-shaped.
  • Edit generated output.Generated code is an artifact, like a compiler's. Editing it forks you from the source of truth and the next release overwrites you.
  • Re-implement interaction. Behaviors come from the archetype; you configure and style them.

#Escape hatches are declared seams

No vocabulary covers everything, and Milda's answer to the last 20% is doctrine: extensibility happens through seams declared in the model, never by patching output.

  • Slots - where consumers inject their own content or components, declared with arity and a content contract.
  • Per-target options - realization choices (naming, emission style, output conventions) configured per target at release time, without touching the neutral model.

Because every seam is in the IR, it survives regeneration, appears in the contract diff, and works on every target - which is exactly what an edit to generated code can never promise.

Try it
The Quick start walks this same arc in a real project, and the Studio pages embed live pieces of the editor to play with.