miso

Thinking in miso

Step 4: Connect the pieces and ship

So far data has flowed down: the app owns the model, view functions read it, the form receives props. Real apps also need to send things up and sideways. miso gives you a small set of tools; pick the least powerful one that works.

The toolbox

You need to…UseNotes
give a child read-only datamountWithProps_synchronous; child re-renders when props change; onPropsChanged to react
tell the parent something happenedmailParentasynchronous JSON message; parent's mailbox = checkMail …
share something with the whole treecontext (modifyContext)theme, language, session; opt in with useContext
notify components that don't know each otherMiso.PubSubtopics; publish / subscribe
poke a specific componentmail componentIdids come from ask inside Effect

Inverse data flow: the form tells the app

When the add form is submitted it does not reach into the app's model — it can't. It mails its parent, and the parent decides:

-- in addBookmarkForm's update
Submit -> do
  draft <- use form
  case validate draft of
    Left errs -> errors .= errs
    Right b   -> do
      mailParent b               -- b has a ToJSON instance
      form .= emptyDraft

-- in the app
app = (component m update viewApp)
  { mailbox = checkMail BookmarkAdded MailError
  , mount   = Just Init }

The child stays reusable (it knows nothing about bookmarks lists) and the app stays in control of its own state.

Routing

Make the selected bookmark a URL: /bookmarks/2. Derive a Router from a sum type, subscribe with routerSub and treat navigation as just another action — see Routing. Links stay real <a href> elements (crawlable, middle-clickable) with an onClickPrevent that pushes the route.

Prerender and hydrate

Because view is pure, the same code renders HTML on a server or at build time (toHtml), and the client hydrates it with miso instead of redrawing. Users see content before the WASM loads; search engines see everything. See HTML & prerendering.

Take it to mobile

Nothing above mentioned the DOM. Swap Miso.Html.Element for Miso.Native.Element, startApp for native, and the model, update, actions and data flow carry over to iOS and Android through Lynx — see miso native.

Recap

  1. Model: minimal state, derived values in view, sum types over booleans.
  2. Views by default; components for owned state, subs and lifecycle. Keys on lists.
  3. Actions are events; update is a pure fold; IO is scheduled at the edge.
  4. Props down, mail up, context around, PubSub sideways. Route, prerender, ship.

That is all of miso's architecture. The rest is the API.