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 ES5-shim and jQuery. Additionally you will need to include an AMD implementation such as require.js or loadrunner. 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:

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

Our GitHub page includes full documentation as well as a sample app in the form of an email client:

Future Work

Flight is an ongoing project. We’re planning to add a full testing framework as well as making available more of the utilities that we use for the Twitter website frontend. We also look forward to your contributions and comments. We know we haven’t thought of everything and with your help we can continue to improve Flight for the benefit of everyone.

We welcome issues and pull requests on GitHub and questions, or assistance to others, on our mailing list.

Acknowledgements

Flight was a group effort.

The following folks contributed to the project: Angus Croll (@angustweets), Dan Webb (@danwrong), Kenneth Kufluk (@kpk) and the members of the Twitter web team.

Thanks also to Tom Hamshere (@tbrd) for his work on the README.md and Nicolas Gallagher (@necolas) for general contributions to this site.

On behalf of the Web Core team,
—Angus Croll, Engineer (@angustweets)