functional-frontend-architecture

A functional frontend framework.

MIT License

Stars
1.4K

functional-frontend-architecture

This repository is meant to document and explore the implementation of what is known as "the Elm architecture". A simple functional architecture for building frontend applications.

High level overview

The entire state is contained in a single data structure. Things can happen and the state should change accordingly. The number of things that can happen is described as a set of actions. Actions flow unidirectionally down the application. Actions are handled by pure update functions. Such a function takes an action and a state and returns a new state. The state is handed to a view function that returns a virtual DOM representation. A module is an encapsulated set of actions, an update function and a view function. Modules can be nested inside other modules and modules can contain other modules. This makes the architecture nestable and modular.

Features/goals/ideas

  • As few mutations in application code as possible. The vast majority of your
    application can be completely pure.
  • Time changing values and interactions with the world is introduced in a
    controlled manner through FRP.
  • Testing should be easy! And nothing is easier to test than pure side-effect
    free functions.
  • State should be easily inspectable for debugging and serialization. Also,
    time travel.
  • Minimalism and simplicity are center pieces in every used library.
  • Actions should be expressed as union types.
  • Everything should be modular and nestable.
  • Simple live code editing thanks to hot
    module replacement.

Documentation

Examples

  • Counters example without FRP This is several
    versions of a counters application. It starts out very simple and then
    gradualy increases in complexity. This is implemented with Snabbdom, union-type and Ramda.
  • Counters example with FRP This is similair to the above example but
    the architecture is bootstraped with Flyd as and FRP library.
  • Who to follow A small who to follow box using
    GitHubs API. It can be compared with a plain FRP version using
    Flyd

    and one using Rx.
  • Zip codes This is a translation of Elm's zip-codes
    example, designed to show how to use asyncronous tasks, specifically http
    requests. ES6 Promises are used here as stand-ins for Elm's Tasks.
  • TodoMVC A TodoMVC implementation built with Snabbdom,
    union-type, Ramda and Flyd.
  • File Uploader Implements a file-upload component,
    i.e. it renders a list of chosen files, shows their upload progress, and
    allows users to cancel uploads. It demonstrates asynchronous side effects
    and a realistic stand-alone reuseable component or 'widget'.
  • Hot module reloading Demonstrates how
    simple it is to use webpack's hot module replacement to achieve live code
    editing without browser refreshes.
  • Modal Demonstrates a technique for implementing modals.
  • Nesting A simple application that demonstrates three
    level nesting of components. This is intended to show how the action-routing
    scales.

Libraries

The architecture is implementation independent. It can be implemented with varied combinations of libraries. It only requires a virtual DOM library and a way to update JavaScript data structures without mutations. Having a nice representation of actions is also useful.

Virtual DOM libraries

The view layer in the architecture consists of pure functions that takes part of the applications state and returns a description of it's view. Such a description will typically be a virtual DOM representation that will later be rendered with a virtual DOM library. A number of options exists.

  • Snabbdom A small modular and
    extensible virtual DOM library with splendid performance.
  • virtual-dom A popular virtual
    DOM library.
  • React Mature and widely used. It
    supports JSX which many people like. It is however a bulky library. It
    supports stateful components which should not be used together with the
    architecture.

Updating data structures

When handling actions inside update functions it is necessary to update ones state without mutating it. Libraries can provide a help with regards to this.

  • Ramda Ramda provides a huge amount of functions for
    working with native JavaScript data structures in a purely functional way.

Representing actions