Overview

Flight is a lightweight, component-based JavaScript framework that maps behavior to DOM nodes. Twitter uses it for their web applications. By way of example, we've included a simple email client demo (browse the source) built over the Flight framework. There's also a flight implementation over on the todoMVC site (source), courtesy of @mkuklis

Flight uses jQuery and requires a module loader with support for AMD, like WebPack or Require.js. Please read the Flight documentation for installation instructions.

Why Flight?

Flight is distinct from existing frameworks in that it doesn't prescribe or provide any particular approach to rendering or providing data to a web application. It's agnostic to how requests are routed, which templating language you use or even if you render your HTML on the client or the server. While some web frameworks encourage developers to arrange their code around a prescribed model layer, Flight is organized around the existing DOM model with functionality mapped directly to DOM nodes.

Not only does this obviate the need for additional data structures that will inevitably influence the broader architecture, but by mapping our functionality directly onto the native web we get to take advantage of native features. For example, we get custom event propagation for free by piggy-backing off DOM event bubbling, and our event handling infrastructure works equally well with both native and custom events.

How does it work?

Flight enforces strict separation of concerns. When you create a component you don't get a handle to it. Consequently, components cannot be referenced by other components and cannot become properties of the global object tree. This is by design. Components do not engage each other directly; instead, they broadcast their actions as events which are subscribed to by other components.

Why events?

Events are open ended. When a component triggers an event it has no knowledge of how its request will be satisfied or by whom. This enforced decoupling of functionality allows the engineer to consider each component in isolation rather than having to reason about the growing complexity of the application as a whole.

By making DOM node events proxies for component events, we let the web work for us:

we get event propagation for free

a component can subscribe to a given event type at the document level or it can choose to listen only those events originating from within a specified DOM Node

subscribing components do not distinguish between custom events from other components (e.g. dataMailItemsServed ) and native DOM node events (e.g. click ), and process both types of event in an identical fashion

Mobility and Testing

Each component is a module, which aside from a minimal set of standard dependencies (relevant Flight utilities and mixins), has no reference to the outside world. Thus a given component will respond to a given event in the same way, regardless of environment. This makes testing both simple and reliable — events are essentially the only variable and a production event is easy to replicate in testing. You can even debug a component by triggering events in the console.

Mixins

A mixin defines a set of functionality that is useful to more than one object. Flight comes with built-in support for functional mixins, including protection against unintentional overrides and duplicate mixins. While classical JavaScript patterns support only single inheritance, a component (or other object) can have multiple mixins applied to it. Moreover mixins requires a fraction of the boilerplate required to form traditional classical hierarchies out of constructor-prototypes hybrids, and don't suffer the leaky abstractions of the latter ('super', 'static', 'const' etc.)

Documentation and Demo

The project includes full documentation as well as an example app in the form of an email client:

Contributions

We welcome outside contributions! Check out our GitHub issues to see what needs doing. To get started, you could try a helpwanted ticket!