Main concepts

A Flame application consists of the following record

type Application model message = {
      init :: model,
      view :: model -> Html message,
      update :: model -> message -> model,
      subscribe :: Array (Subscription message)

The type variable model refers to the state of the application. message, on the other hand, describes the kinds of events the application can handle.

Application state

In the counter example we set our model as a simple type alias

type Model = Int

that is, the state of our application is a single integer. In a real world application, the model will probably be something more interesting – Flame makes no assumption about how it is structured.

With our model type declared, we can define the initial state of the application

init :: Model
init = 0

The first time the application is rendered, Flame calls the view function with init.

Application markup

The view function maps the current state to markup. Whenever the model is updated, Flame patches the DOM by calling view with the new state.

In the counter example, the view is defined as

view :: Model -> Html Message
view model = HE.main "main" [
      HE.button [HA.onClick Decrement] "-",
      HE.text $ show model,
      HE.button [HA.onClick Increment] "+"

The messages raised on events are used to signal how the application state should be updated.

See Defining views for an in depth look at views.

State updating

The update function handles events, returning an updated model. In a Flame application, we reify native events as a custom data type. In the counter example, we are interested in the following events:

data Message = Increment | Decrement

and thus our update function looks like

update :: Model -> Message -> Model
update model = case _ of
      Increment -> model + 1
      Decrement -> model - 1

See Handling events for an in depth look at update strategies.


Finally, we can specify events that come from outside of the view as an array to subscribe. Such events include window, document – and even messages arbitrarily raised by user code. These messages will then be handled in the usual way by the update function.

In the counter example no external events are handled, so the subscription list is empty

subscribe :: Array (Subscription Message)
subscribe = []

See Handling external events for an in depth look at subscriptions.


Having all pieces put together, we can either render the application to the DOM, as in the case of the counter example

main :: Effect Unit
main = FAN.mount_ (QuerySelector "body") {

or as a String with Flame.Renderer.String.render, which can be used server-side.

See Rendering the app for an in depth look at rendering.

Next: Defining views