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… | Use | Notes |
|---|---|---|
| give a child read-only data | mountWithProps_ | synchronous; child re-renders when props change; onPropsChanged to react |
| tell the parent something happened | mailParent | asynchronous JSON message; parent's mailbox = checkMail … |
| share something with the whole tree | context (modifyContext) | theme, language, session; opt in with useContext |
| notify components that don't know each other | Miso.PubSub | topics; publish / subscribe |
| poke a specific component | mail componentId | ids 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
- Model: minimal state, derived values in
view, sum types over booleans. - Views by default; components for owned state, subs and lifecycle. Keys on lists.
- Actions are events;
updateis a pure fold; IO is scheduled at the edge. - Props down, mail up, context around, PubSub sideways. Route, prerender, ship.
That is all of miso's architecture. The rest is the API.