Shpadoinkle is a Haskell UI programming paradigm.

The core idea here is to model user interfaces as functions with type:

view :: Model -> Html m Model

This lets you describe the view as a pure function predicated on the current application state. It also suggests that changes to application state are dictated by the view.

Here is a simple example, which displays a counter:

view :: Int -> Html m Int
view model = (1)
  div []
  [ text $ pack $ show model (2)
  , button
    [ onClick (model + 1) ] (3)
    [ text "Increment" ]
1 The function receives the current application state (which is just an Int)
2 Shows the current state to the user in a text node
3 When the user clicks the <button> it is added to the model

That is it. If you can understand what is going on in the above example, you understand Shpadoinkle, it’s that simple. There is no dispatch, no payloads, no event types, no giant update function, no networks of state managers, no templating, no special HTML syntax, no magic attributes, no digest cycle, and nothing fancy going on.

In fact, the only part of Shpadoinkle that actually performs work is only about 12 lines of code.


High Performance

By not doing much work, Shpadoinkle is quite fast. The rendering backend is modular, so you can always take advantage of the latest work done on virtual DOM rendering. When faster techniques are available, you can adopt them easily.


Shpadoinkle is high-level code, and rarely mentions low-level details. Developers do not have to worry about causality or when DOM nodes get replaced.


There is no need to wire model updates to locations in the DOM by elaborate passing of messages and payloads. Components are highly composable. Impedances in types for subcomponents are resolved with nothing more than fmap (typically with some lenses).


By keeping UI composition pure, runtime errors don’t occur in practice. Code is easy to test as model updates are typically pure functions, and HTML output is transparent.