

Flight: A lightweight, component-based JavaScript framework from Twitter - uggedal
http://twitter.github.com/flight/

======
dmragone
Recently I discussed with colleagues why Ruby on Rails succeeded where no
Python framework did. One hypothesis put forward was that there was 1 popular
Ruby framework (Rails), but many popular Python frameworks.

I wonder if it will be the same for JavaScript front-end frameworks, with no
one gaining the greatest mindshare.

Not necessarily make any claims about what's preferable (one framework to rule
them all vs many competing options) - though I'm certainly curious about that
as well for the front-end frameworks.

~~~
drudru11
I will give you my 2 cents on this argument.

tl;dr - Python had no web frameworks built in or community favorite. Rails was
a complete re-think of how to do web apps in the age of XML (acaffolding,
convention over config, etc.) Every language since has now realized this and
copied Rails. This is a good thing.

if you want a story while drinking coffee, read below...

I was a serious Python guy from 1996 til 2006. I still like and respect
Python. Before Python, I was a wanna-be Smalltalk fan. (This is important
towards the end)

Python always had a philosophy of 'batteries included'. This means that it
will have libraries for just about everything you need as supported parts of
the language. Contrast this with Perl where CPAN quality was very hit or miss.
Then contrast this with Lua or Scheme. They had too many libraries and none
were standard. Most of those were, again, not supported or not of production
quality.

As a result of 'batteries included', Python was just a dream to work with.
Everything was doable or easy _and_ performant 'enough'. I could go on, but
that still wouldn't do it justice. They had a great language design, great
libraries, and portability. Python is still a great framework. They didn't
have a good 'CPAN'. This was ok, since the built-ins were good. Outside of
that, it was a bit of a mess.

However, over the years, it became obvious that Python had a huge flaw. They
did not deal with HTTP or HTML well. People don't even talk about this
anymore, but the promoted framework was 'Plone'. This framework was so complex
and convoluted, that building a simple web app was just not possible. It is
not spoken about anymore. New frameworks popped up as a result, and very few
of those were much good. This was a huge problem. Most people had to build
their own production system. I had to switch languages for a job in 2002, and
I didn't deeply follow the web framework discussion in Python for quite some
time. I can tell you this, though. There wasn't a single framework that popped
up as the winner or as exciting.

I'm typically a conservative. When I see a new thing, my typical take away is
"this has been done before, what did they not learn from prior art". For
example, lets say someone creates a new OS. If they don't _really_ understand
Unix, they will get it wrong.

When the first Rails screen-cast came out, I took a look. There was a lot of
buzz that was increasing. I go, 'what the heck, it is only 5 minutes and it is
a video.'

What I saw was an excellent architecture for building web apps. This
architecture was better than anything else out there by quite a wide margin.
They supported modern HTML. Convention over configuration. ActiveRecord was
truly a treasure. The default site actually looked relatively decent (vs. the
typical programmer, zero whitespace, huge serif, Netscape circa 1998 site).
They URL conventions looked good. This architecture was human friendly. These
people understood what a modern app should look like.

I was sold. Just from that screencast.

I believe in using whatever language is needed, if the framework is excellent.
I wanted to build excellent web apps, so I learned Ruby. Ruby was easy to
learn, and it is as good as Python. Much to my surprise it was the first
language to pull off having Smalltalk blocks! People didn't even notice this
and now they really like it. Everytime I showed this to coworkers, they would
go 'what is that? I don't understand'. When people eventually learn Rails,
they would go.. "check out these block things. They

So, in summary, Python didn't have a web framework. Rails was an excellent
design, compared to _any_ languages framework. Rails is pretty much going to
be here for quite some time.

BTW, at this point. Rails is not my first choice. I think it is too heavy and
web architecture has shifted a lot. Still, it would be in my top 3 choices.

~~~
vph
> I had to switch languages for a job in 2002, and I didn't deeply follow the
> web framework discussion in Python for quite some time

Good Lord. This is like 11 years ago?

~~~
saraid216
Learning Plone was a requirement for an internship I was considering in 2006,
fwiw.

~~~
drudru11
You have my sympathies.

------
glymor
This looks like Twitter's version of Web Components?

You might have heard of it shadow DOM etc. Basically the idea is to be able to
add GUI components eg <progressbar> that are as integrated as the native ones
are.

[https://dvcs.w3.org/hg/webcomponents/raw-
file/tip/explainer/...](https://dvcs.w3.org/hg/webcomponents/raw-
file/tip/explainer/index.html)
<https://plus.google.com/103330502635338602217/posts>

Mozilla's X-Tags implementation seems closer to the goal though:
<http://www.x-tags.org/> IIRC it can do this because it's using
Object.observable internally to detect DOM changes.

ie with X-tags you don't need the javascript definition part, just: <x-map
data-key="39d2b66f0d5d49dbb52a5b7ad87aea9b"></x-map>.

~~~
cristiantincu
Web Components is the storm that will wipe away all these frameworks:
Backbone, Ember, Angular, Knockout, etc.

Unfortunately, we’ll have to stick around with them for the following couple
of years, probably, as for now, most of the Web Components APIs are available
only in Chrome Canary and Firefox dev builds. Monkey-patching (AKA “shimming”)
to the rescue…

In my opinion, the more certain nowadays libs resemble the Web Components
specs, the more clear the developers’ choice towards those libs should be.

------
scottrblock
I've played around with most of the JavaScript MV(whatever)'s and I'm just not
sure about this.

 _"Flight is organized around the existing DOM model with functionality mapped
directly to DOM nodes"_

It seems the point of using backbone or which ever other framework (I'm
partial to Angular so far), is to decouple from the DOM, so that if and when
your markup changes, your JavaScript doesn't. This doesn't seem any better
than well written jQuery.

Am I missing something?

~~~
pfraze
It looks like the concerns are different between Backbone and Flight.

Flight is for building UI components, not client views. I think it might be
akin to jquery widget plugins, but with more structure to make it easier and
potentially more extensible (eg the mixins).

So yeah, in this case I think they were right to ride on DOM events.

------
vicapow
why not just use component?

<http://github.com/component/component>

~~~
jongleberry
agreed. the problem with these AMD frameworks is that the asynchronous nature
and deeply nested callbacks are almost completely unnecessary because you end
up concatenating/minifying the assets before production anyways. You end up
with unreadable files. With synchronous CommonJS frameworks, most of this
nesting is eliminated.

~~~
reissbaker
With AMD you generally only have one (in a rare case, two) levels of
indentation added on top. I much prefer CommonJS too, but deep nesting's not
really a fair accusation.

~~~
jongleberry
true. i'm being a little sarcastic, but 1-2 levels of _unnecessary_
indentation bothers me when it's easily avoidable.

~~~
reissbaker
Fair enough. Aesthetic reasons aren't the worst ones in the world.

It's also just so... Yeesh. Complicated, in comparison.

------
karl_nerd
What I think is interesting to see, is that the patterns from Nicholas zakas'
"scalable Javascript architecture" spreads into new frameworks.

Enforcing components w/o return values, communicating via pub/sub is also seen
in aura.js and backbone marionette. I think this thinking will lead to more
stable, easy to change js apps. Exciting!

------
agilord
This is a really great concept, that enables client applications on a
different scale (and reduces their complexity very much). Thanks Twitter team!

A big advantage over web components (or angular, or others) is that this is
much more lightweight, less polluted and has a better separation of concerns.
(On the other hand, web components will be a great deal for browser-app shops
developing for third parties).

------
weareconvo
Seeing as how Bootstrap fails at even the most elementary of tasks (using
absolute instead of relative values for positioning, for example, screws
everything up when the user's zoom is anything other than 100%, among many,
many, many other flaws), anybody who uses this framework is a competitor I
am... not worried about.

------
Kiro
I've read the page two times now and still don't understand what it does. Can
someone explain?

------
benregenspan
Why not just use Flash?

~~~
gummydude
welcome to 2013

------
dos1
> _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._

This is a maintainability nightmare. I've gone down this route on hand rolled
JS frameworks before and it leads to untold headaches. Sometimes a little
coupling is the right solution. Many times it is better for components to have
knowledge of their environment. In most applications (other than iGoogle
maybe) one thing on a page depends on another. I feel it's far better to
explicitly call out those dependencies by having a reference to the other
components and directly invoking methods on them with known arguments of a
known type.

Edit: Also, what kind of memory allocation implications are there with event
subscriptions and no references to the components themselves?

~~~
danso
Er...why is this broadcast model a maintainability nightmare compared to
coupling components to their environment and to other components? I guess
maybe it's too much abstraction for a website in which you know most
components won't be reused...but then you wouldn't be Flight's intended
audience.

~~~
dos1
So a component subscribes to some event somewhere. Who's triggering the event?
When you're debugging in Firebug or someplace, what does your call stack look
like? How hard is it to find the source of the event? All you know is it
bubbled up from somewhere.

Say I want to add a component to a page. Which events do I need to trigger to
make it do the kind of things I want? What do I need to pass as a payload to
those events? How do I know if there's a consumer for my event or not? If
there _isn't_ a consumer that's probably an issue.

The eventing bus adds an additional layer of indirection. If your app can be
truly decoupled, then this would be great. But I just don't see that use case
being very common. I have never worked on an application where the broadcast
model was more benefit than pain in the long run.

~~~
Isofarro
> So a component subscribes to some event somewhere. Who's triggering the
> event?

Look at the event source.

> When you're debugging in Firebug or someplace, what does your call stack
> look like?

Look at the data passed to the event. The callstack starts at the function
attached as a listener to the event.

Is the event data incorrect? Then the problem is in the code that triggers the
event.

Is the event data correct? Then the problem is in the code listening to the
event.

> Say I want to add a component to a page. Which events do I need to trigger >
> to make it do the kind of things I want? What do I need to pass as a >
> payload to those events?

Documentation. That is indeed the cost of using an abstraction that decouples
code, but it's also a cost that has benefits - good documentation is useful.

> How do I know if there's a consumer for my event or not?

It's not important. That's the point of an event-based system, it's a
decoupling. De-coupling is an abstraction. It works on pages that are based on
components or modules.

If you don't want that abstraction, then using code based on that abstraction
isn't a particularly good idea.

Event-based frameworks do need documentation - but reusable code should be
documented anyway. There's just more emphasis on getting the documentation
done in event-based systems.

~~~
moonboots
> Look at the data passed to the event. The callstack starts at the function
> attached as a listener to the event.

> Is the event data incorrect? Then the problem is in the code that triggers
> the event.

> Is the event data correct? Then the problem is in the code listening to the
> event.

It's difficult to reason about the event triggering code when it's call stack
is not available. For a larger code base where an event is trigger in multiple
locations with different logic in each location, it may be difficult to
pinpoint the triggering code, let alone reason about that code. Direct
function calls are much easier to debug because you can walk up the chain of
calls and inspect the variables and state of each frame.

~~~
Isofarro
> For a larger code base where an event is trigger in multiple locations with
> different logic in each location, it may be difficult to pinpoint the
> triggering code, let alone reason about that code.

Populate the event with the event source.

> Direct function calls are much easier to debug because you can walk up the
> chain of calls and inspect the variables and state of each frame.

If your listener depends on knowing the state of the triggering code, it is a
sign your events are too granular. If you require a complete stack trace to be
able to debug a listener to the event, that sounds like you have a bigger
architectural problem to deal with.

Events are coarse. The listener should not care about why the event was fired,
only that the event has occurred. Events are not a replacement for direct
function calls. They are a mechanism for de-coupling pieces of code that can
be independent of each other. It doesn't sound like your situation is one
where there's that independence.

~~~
drgath
> If your listener depends on knowing the state of the triggering code, it is
> a sign your events are too granular.

That isn't practical debugging. If I'm debugging an event that was fired and I
don't know why, or the payload doesn't match my expectations, it would be very
useful to inspect the state of the triggering function and see where things
went wrong.

------
WayneDB
How can anyone build a serious front-end without proper keyboard support?
Every single one of these new-fangled web UI kits is missing this important
feature and if you're going to do it at all, it really does need to be a core
consideration.

This is my biggest complaint about most web apps and the number one reason
that I think web apps are perceived to be less powerful. Give me a break web
devs! (Or, should I say browser makers?) Let's get serious already!!

(Also if we're talking browser manufacturers, I'd really, really like to see a
_completely_ separate abstraction for apps than documents. C'mon man!! We've
been inventing the same thing for 20 years, let's get it right for once :)

------
bvcqw
Why not just use Angular?

~~~
taligent
Why not just use KnockoutJS?

~~~
aymeric
You can end up with a hard to maintain code with knockout.js if you don't
structure it well. I found <https://github.com/danderson00/knockout.composite>
recently that seems to adopt a similar philosophy (pubsub) to what Flight does
while keeping the benefit of knockout.

~~~
WickyNilliams
I've used this knockout extension to great success [1]. It's intuitive, it
leverages knockout's internal pubsub, and fits in with the KO ethos. It can be
used to synchronise observables across models (which is awesome as it's events
without overhead), or as a general purpose event system.

Ryan is one of the core contributors to knockout, by the way, so you can be
assured of its quality.

[1] [http://www.knockmeout.net/2012/05/using-ko-native-
pubsub.htm...](http://www.knockmeout.net/2012/05/using-ko-native-pubsub.html)

