Pux uses purescript-smolder's markup monad. HTML ev is an alias for Markup (DOMEvent -> ev), which is used with do notation to describe a state's view:

view :: State -> HTML Event
view count =
  div do
    button #! onClick (const Increment) $ text "Increment"
    span $ text (show count)
    button #! onClick (const Decrement) $ text "Decrement"

Learn more about do notation and monad basics in Functors, Applicatives, and Monads in Pictures.

Smolder provides constructors for each element or attribute, like div or button, or className and href. When applicable, constructors take an argument for a child element or attribute value. Also provided are operators for combining elements with attributes or event handlers.


Element constructors are provided by Text.Smolder.HTML, with container elements taking an argument for children.

Children can be text:

h1 $ text "Hello, World"

Or another element:

div $ p (text "PureScript")

Or multiple elements using do notation:

div do
  h1 $ text "Hello, World"
  p $ text "I'm HTML."

Sometimes you want an empty container element. Because HTML is a monoid, you can use mempty:

div mempty


The ! operator is used to add attributes to elements:

a ! href "" ! className "yellow" $ text ""

Optional attributes can be declared using the !? operator in combination with a boolean:

button !? state.loading (className "loading") $ text "Save"

Event handlers

The #! operator is used with constructors from Pux.DOM.Events to add event handlers to elements:

button #! onClick (const Increment) $ text "Increment"

Pux provides constructors for creating event handlers for all the DOM events via Pux.DOM.Events. These constructors take an argument of type DOMEvent -> ev where ev is the type of your application events. This is so that data in the raw DOM event can be used in the application events. If the DOM event is not needed by the application event, it can be ignored using the const function as shown in the example above.

DOMEvent is an alias for purescript-dom's Event, so you can name your application event type the same without a name collision.

Pux elements and attributes

In addition to purescript-smolder, Pux provides its own element and attribute constructors in Pux.DOM.HTML and Pux.DOM.HTML.Attributes:

  • The style element and attribute take CSS from purescript-css.
  • focus declaratively controls input focus.
  • key is for rendering optimization (used by React and others).
  • data_ constructs properties prefixed with "data-".

HTML from lists

Often elements need to be generated from a Foldable, whether a List, an Array, etc. Use for_ from purescript-foldable-traversable:

colors :: Array String
colors = ["purple","red","green"]

color :: String -> HTML Event
color s = li $ text s

view :: HTML Event
view = ul $ for_ colors color


Use Pux's memoize where it's important to avoid unnecessary rendering:

view :: State -> HTML Event
view = memoize \state -> div $ text state.message

It's important that memoize is only used at a top-level declaration and not inside a view. This is because PureScript is eagerly evaluated like JavaScript. If memoize is used inside a view it will recreate the memoized function every time the view is called.

Next: Rendering

Previous: Events