
Riot.js – A 1kb client-side MVP framework - tipiirai
https://moot.it/blog/technology/riotjs-the-1kb-mvp-framework.html
======
jashkenas
While I'd usually prefer to be nice in the mornings ... starting off with
those benchmarks got my goat. So.

This sort of thing is a _beautiful_ demonstration of marketing, big promises,
and bombastic rhetoric in open source. But one of the best things about open
source is that you don't have to take such claims at face value. If you
actually look at the source, you'll find:

[https://github.com/moot/riotjs/blob/29ae687ca0633b703e124331...](https://github.com/moot/riotjs/blob/29ae687ca0633b703e124331f6395052b051355b/riot.js)

* A funny syntax for string interpolation. (Not templates)

* A strange bug relating to "popstate", ignoring browser support for folks on IE.

* A simple proxy to jQuery's `on`, `off`, `emit`, and `one` functions. (Why not just use jQuery events directly?)

* A simple proxy to "pushstate" and "popstate". (Ditto)

... and that's about it.

Calling this, "The fastest, smallest and most powerful client side framework
for building large scale web applications," is pretty funny stuff — but I
guess it might also be true. There's almost _literally nothing_ here except
for jQuery.

That said, if this were rewritten as a "you don't need a library to do MVC"
blog post, then more power to it — it would be right on. But at the moment,
it's a pretty spectacular piece of puffery — the sad thing being just how
effective this sort of thing can be: [http://cl.ly/SFzy](http://cl.ly/SFzy).
"Riot.js" might be a particularly egregious example, but similar tactics can
be found all over the place. As a community, it would be nice if we could
spend a little more time reading source, and seeing what libraries _actually_
do and what can be done with them, and less time just drinking down the PR.

(And if this is all an elaborate joke, then I'm an ass for falling for it ;)
But that's not the sense I get.)

~~~
sergiotapia
You say that like it's a bad thing. I like the idea that riot.js is small
enough that it 'outsources' it's meaty functions to jQuery (a library you most
likely have in your project already). It means fewer bugs and less work for
you! More time to enjoy life. There are tons of very smart developers working
on jQuery,why replicate their work on riot.js?

If your project doesn't use jQuery feel free to use the right tool for the
right job - I can't remember the last time I worked on a web project that
didn't have jQuery.

~~~
nilliams
I'm pretty sure Jeremy was not criticising the jQuery dependency, since his
framework (Backbone) also depends on it. He is just stating that there's
nothing actually _in_ riot.js, it _just_ proxies to jQuery.

The project might as well just be a blog post with what I'd consider the only
useful and _non-hyperbolic_ aspect which was:

> What people refer to as spaghetti is in fact a mixture of model and view
> code. To avoid it, simply separate your model code from the view with
> observables.

Fine. I agree that people shouldn't falsely miscredit jQuery for causing
spaghetti code and understanding basic separation is valuable. Unfortunately
the following line is one of hyperbole:

> You don't need a framework for that.

Which I have a problem with for 2 reasons:

1\. That is not _all_ frameworks do. They also reduce the amount of
boilerplate, repetitive code you have to write. Riot.js does not appear to do
so (significantly). Look at the amount of code in the TodoMVC example's model
[1]. That would be dramatically less code when using Backbone.

2\. Nobody _needs_ a framework. But frameworks establish conventions and
conventions are very valuable for collaboration as well as general discussion
of patterns and ideas.

And as for:

> Current frameworks persuade false beliefs with shiny websites and finely
> crafted marketing without transparent, scientific analysis. They solve
> hypothetical problems and cause new problems instead. Unfortunately, large
> communities are dealing with irrelevant issues.

Seriously? I want to swear and throw things, and I'm not even a framework
author.

[1]
[https://github.com/moot/riotjs/blob/master/todomvc/dist/todo...](https://github.com/moot/riotjs/blob/master/todomvc/dist/todo.js)

~~~
tipiirai
Riot does templating, routing and separation of concerns rather beatutifully,
I would say. Those are the things most frameworks are build for. What do you
see missing?

The amount of Todo MVC code in Riot is actually smaller than in Backbone but
like I say on the post the focus should not be on the code size but on
simplicity – and this is why Riot advocates MVP a lot. Actually Backbone also
seems like a MVP framework to me.

~~~
ssmoot
It seems the Presenter example is pretty broken (unless I'm just stupid). I
don't see a `todo` variable defined anywhere, but it's used in several places.
Perhaps `var model =` was just missed in a rename?

Also, the "toggle all" function uses a `filter` variable that's undefined
AFAICT.

I'm not trying to knock the framework. I like what I see. Just a little hard
to follow along when I'm not sure if the code is wrong, or my understanding of
it is.

~~~
sanderjd
I thought the same thing about the `store` variable in the `Todo` object. Not
sure what we're missing.

------
mjackson
There isn't very much to see here, if anything. A few meaningless
microbenchmarks, and some "plain old JavaScript objects" that hijack jQuery's
event subsystem so they can emit events just like DOM elements. We've been
doing imperative, evented programming in the browser for years now.

 _Even if_ you're inclined to argue that this style of programming doesn't
lead to a giant mess (and I'm inclined to believe that it does, even if you
are _the most disciplined_ of programmers) I still don't see the benefit of
adding this 1K of JavaScript to my page at all. I can duplicate $.observable
with a vanilla jQuery object.

To call this the "most powerful client side framework for building large scale
web applications" is downright laughable.

~~~
felxh
This isn't just 'imperative, evented programming' though. It gives a clear
answer on how to separate your code into concerns, although I agree that there
isn't much forcing you to follow good practices.

The problem with the typical 'jquery-type' programming was that apps were
essentially an ad-hoc collection of (sometimes massive) event handlers. I
think the problem boiled down to:

* there wasn't much experience and consensus on how to organise javascript code (split it into module etc.)

* the DOM is global, meaning you can register event handlers to anything from anywhere (To make matters worse events bubble up and down the DOM tree)!

It seems like people immediately resorted to extremes to solve these issue -
basically trying to abstract away the DOM and even javascript completely -
whereas the solution could be something much simpler and subtler.

------
ollysb
The current crop of frameworks do feel like they're trying to abstract away
the browser a little bit. They have the feel of something like JSF1 (java),
they get the job done but the abstraction is so thick that it's difficult to
integrate things like jquery without jumping through a few hoops. A lighter
framework that achieves the same things without all the fuss would be very
welcome. The danger is that the abstraction is too thin and you end up writing
half a framework yourself to plug the gaps but maybe riotjs has managed to get
closer to the sweet spot.

------
sequoia
I apologize if I'm missing something, I'm not a data visualization expert, but
what the heck is going on with that graph?
[http://content.screencast.com/users/sequoia.m/folders/Jing/m...](http://content.screencast.com/users/sequoia.m/folders/Jing/media/4571c9dc-4664-4dd4-9c3f-0c0e86647fd3/2013-11-01_0847.png)

~~~
druska
The bars are relative to data in it's own category (eg. 200x), you're
comparing apples to oranges.

~~~
tipiirai
Thanks for the short way of explaining how it works. Will add this exact
clarification on the site.

------
defen
I think it's rather disingenuous to call this a "1 kb" framework when it
depends on jQuery (83,612 bytes as of 2.0.3). I don't know about the other
frameworks, but the current stable version of angular is 81,447 bytes and does
not depend on jQuery, and is significantly more expressive.

------
felxh
I really love the minimal approach and a lot of it echoes my experience as
well. One thing that I would love to see (mostly because I haven't found good
solutions for it myself) is how CSS fits into the whole thing. The way I see
it, CSS touches several aspects in the MVP pattern. There is the view part,
which is strictly how things look on the screen but there is also the
presenter part, which includes thing like, 'now show this thing', 'animate
this, and when it is done, do this'.

------
Yaggo
I love the refreshingly minimal approach, although jQuery dependency ruins
some of the excitement, but still, great work guys!

~~~
tipiirai
Thanks. jQuery dependency is intentional since the library promotes the use of
jQuery on the presenter layer.

~~~
aniketpant
I really like this outlook.

Most developers don't bother about the presentation layer and they think that
jQuery is a pain but most front-end designer and developers rely on it.

Great step.

------
maaarghk
This looks really pretty good. I think I would miss things like ng-each, but I
guess not that's not -too- hard to re-implement using $.data('each'). Maybe. I
will consider using this for a site I'm building right now, see what happens.

------
jashkenas
[Retracted.]

... but, if you're going to test Underscore templates for speed, you need to
use the `variable` setting to avoid the `with` block.

~~~
esailija
I don't think that's fair since a templating engine could easily avoid the
actual with statement but provide same convenience. Optimization should be
done in the implementation (which is fully possible here) and not at the cost
of API ergonomics.

~~~
jashkenas

        > a templating engine could easily avoid the actual with 
        > statement but provide same convenience
    

I'm afraid that's not possible. If you look at other micro-templating
libraries that allow arbitrary JavaScript values, you'll find that there are
two options. Either you can support naked variables, and you have to use
"with" to bring them into scope ... _or_ you have to prefix all of your
variable accesses off a "data" object, which is less ergonomic, but faster.
Underscore supports both.

If you've got a patch that is able to do otherwise, I'd love to see it ;)

~~~
esailija
I wasn't aware that the benchmark comparison was about micro-templating, it
includes libraries like handlebars.

I am sure you realize you can just walk the AST for what identifiers are being
used in the template code and forward declare them in the generated code so
that reference errors are not caused.

~~~
jashkenas
If you allow arbitrary JavaScript, then I'm sure you realize that you can't
"just walk the AST" ;)

At compile time, you have no idea which identifiers are incoming data values —
to be supplied by the caller of the template function — and which identifiers
already exist in scope.

~~~
esailija
Let me put it in code terms. In the following template script:

    
    
        <div>@hello</div>
    

The generated code can be like (not including runtime lib):

    
    
        var ___html = "";
        var hello = hasown.call(data, "hello") ? data.hello : "";
    
        ___html += '<div>' +
                    safeString(hello, HTML_GENERIC) +
                    '</div>';
    
        return ___html;
    

Which gives same effect as `with`.

------
gbaygon
[off topic] i find very distracting that the title in the page changes when
"Someone is writing..." a comment.

~~~
Jgrubb
This is the second article I've read on this site, and the second time that
I've noticed after about 5 minutes that my computer's fan sounds like it's
about to take off. Disconnect gets stuck in some kind of loop on their site
and I feel like it's because of that feature (edit: because I've never seen
that feature or that Disconnect freakout on any other site).

------
euphemize
I like how this looks, I definitively want to try it out.

With that being said :

> _Here 's the shocking part: a 1Kb library requires the least keystrokes to
> build the Todo MVC application_

I'll decide on my own if it's shocking or not. Also I don't care that much
about keystrokes, there's nothing wrong with verbose/expressive languages. I
want my code to be readable and maintainable, and then concise if possible.
This project looks cool but I wish its creator(s) was/were a bit more humble.

~~~
tipiirai
I still find it really surprising that I was able to write the Todo APP in
least amount of keystrokes by using only 1kb of "framework" code.

And I totally agree that the goal should be readability and maintainability –
this is what the post is mostly about.

~~~
STRML
Except, that's not true - the Angular TodoMVC code is smaller and more
expressive, and Angular's JS is actually smaller than Riot + jQuery.

I get what you're trying to do here but please don't resort to misleading
statements to prove your point. This community sees right through it and every
time you say things like this, you lose credibility.

------
api
I love minimal code. When you try to do minimal, often what you end up doing
is stripping away everything you don't need -- extreme YAGNI -- and getting to
the core of something. Even if the result ends up being too minimal, it's
often extremely educational.

To remove the jQuery dependency I'd suggest looking at this:
[http://minifiedjs.com/](http://minifiedjs.com/)

------
sequoia
It looks like the meat of $.observable is mostly just passing thru to jQuery
[https://github.com/moot/riotjs/blob/master/riot.js#L29-L54](https://github.com/moot/riotjs/blob/master/riot.js#L29-L54)
I don't really have an opinion on whether this is good or bad but it's worth
noting that jQuery is doing the heavy lifting here.

A couple code notes:

* why, in the observable function, are you switching functionality not by the name of the function called ('on','emit', etc.) but by the index of that function name in the array on line 32? This strikes me as brittle because adding to or rearranging that array would cause the whole function to fall apart. It's also harder to read- I'm looking at `if(i == 2)` rather than `if( fnName === 'emit' )`. Does this yield a significant performance gain or is it just to juice the final "weight" of the library (<1kb)? I ask because it sure as heck makes the code harder to read.

* Using `name` & `names` as variable names makes the code harder to read, as it doesn't give any meaningful context about what the variable stores (besides the fact that it probably represents a thing that has a "name"). It looks like in this case it represents event names but more descriptive variable names would eliminate this ambiguity & it would make no difference to the code weight after minification.

I bring these things up because this lib looks cool & I like the "you can
easily read the whole source" point, but this obsession with brevity (that's
what it looks like at least) causes code readability to suffer & greatly
diminishes the benefit of being able to "easily read the whole source." Make
the code more readable & more people will use the project & contribute. :)

------
swah
How can someone just beat Resig's or Jashkenas' code performance "that
easily"?

~~~
jashkenas
[https://github.com/moot/riotjs/blob/master/riot.js#L12-L21](https://github.com/moot/riotjs/blob/master/riot.js#L12-L21)

By only supporting simple single property accesses. All that this can do is
print values from an object — no loops, conditionals, filters, methods, or
anything else — like the others support. Think string interpolation, not
templates.

~~~
tipiirai
Yeah. The idea is to support variable substitution (string interpolation)
only. The loops are supposed to be done on the Presentation layer.

~~~
jasonlotito
You should remove the need to wrap the replacement strings in {} so the
templates don't need to be rewritten. As it stands now, you're requiring
people to write a template once, than rewrite it, and then debug the final
result. Better to just use basic HTML.

------
namuol
How hard would it be to remove the jQuery dependency? It looks like it really
only needs $.on/$.off/$.one/$.emit, which could surely cut the _actual_ size
down a _lot_ from 94kb.

~~~
woah
Someone needs to get started on breaking JQ down into it's component pieces.
So much in there that I never use.

~~~
shmageggy
[https://www.google.com/search?q=jquery+build](https://www.google.com/search?q=jquery+build)

------
wiremine
Here is the entire source:
[https://github.com/moot/riotjs/blob/master/riot.js](https://github.com/moot/riotjs/blob/master/riot.js)

~~~
seanhandley
* jQuery not shown

------
danmaz74
TL;DR: "You don't need a framework for that"

------
gadr90
1kb, plus jQuery's 50. This must be a joke...

~~~
tony_landis
Indeed. The whole reason for the existence of all these frameworks riot is
being compared is to to simplify development.

Angular has no dependancies. Knockout also has no dependancies, so it's
actually 13k > than riot.

For anyone who really serious about going minimal, here are some alternatives
to jquery to build on.

9.7kb [http://zeptojs.com/](http://zeptojs.com/) 3.4kb
[https://github.com/rpflorence/snack](https://github.com/rpflorence/snack)
5.0kb
[https://github.com/julienw/dollardom/](https://github.com/julienw/dollardom/)
10kb [http://xuijs.com/](http://xuijs.com/) <1kb
[https://github.com/honza/140medley](https://github.com/honza/140medley)

What a riot!

------
dmackerman
It looks like a nice little library. Unfortunately, most of these "micro super
fast i can build a todo app in 4 lines of code" things aren't enough anymore.

Most of us aren't building "Todo" apps. We're building bigger apps which
require - or are more suitable - for a framework like Angular/Ember. That's
just my 2 cents.

~~~
tipiirai
Moot is a complete discussion system built with Riot / MVP. There is no other
app than Todo MVC to make comparisons.

------
rimo
Seems really nice, but I would not call this a framework. Just like Backbone,
it is more of a library than anything else.

~~~
mattgreenrocks
The lack of framework-ness is what makes it interesting: you're not handing
your _entire app 's architecture_ to a framework and hoping for the best. This
library knows its place, and it is happy to be there, instead of spreading
itself all over your code and claiming it is helping you.

------
gosukiwi
I like this idea, you can in fact build a MVP framework without writing a 1kb
library, assuming he's not counting the dependencies (jQuery), you can aswell
use Hogan/Mustache/Underscore templates, a router libarary, an observer
library and jQuery.

I just dislike the use of "new" in javascript...

------
driverdan
This is a nice academic exercise but isn't very useful for real world apps.
The logicless "views" alone make building anything complex impossible.

One of the reasons this is so light is that it forces you to write boilerplate
code for models. I use libs to eliminate boilerplate, not force it upon me.

------
facorreia
I think 'once' would be a better name for the API function instead of 'one'.

~~~
felxh
+1 to that. I would even suggest 'onceOn'.

------
conorwade
Completely ignoring the technical aspects of the framework. The branding being
used looks like a rip-off of Riot the design and development studio in
England. [http://riothq.com](http://riothq.com)

~~~
woah
THEY'RE BOTH RIPPING OFF OWS
[http://occupywallst.org/](http://occupywallst.org/)! Power to the people.

------
brannon
I think this looks great. Thought I'd let you know I found a typo though. In
the jQuery section, last paragraph, "Riot takes a puristic approach and does
not allow you to do mix any logic inside HTML views."

------
leokun
Precompilation renders template rendering speeds...moot.

What a weird factor to use for choosing a template engine. Also there already
is a popular unit test framework called riot.js

~~~
tipiirai
> Precompilation renders template rendering speeds.

Not 100% sure what you mean but if you measure the time to render a HTML
fragment 100 times the total time is 1 x pre-compilation + 100 x rendering.
The pre-compilation has virtually no effect on the total time.

~~~
leokun
I mean that if you do the HTML parsing to JavaScript portion as part of your
deploy, instead of in the browser at render time, then all you're measuring is
string concatenation and HTML render times, which should always be the same.
Template rendering speeds in that case mean nothing.

~~~
STRML
Exactly - with the proliferation of Grunt in most modern webapp builds, it is
incredibly simple to pre-compile your templates in your production builds. In
fact, it's so fast (and I get useful stacktraces when my tpls have errors)
that I started precompiling templates in development, too.

I find the bottleneck is 99% the browser's HTML parser and 1% the actual
templating library.

If somebody had any tips on how to bring down the "Parse HTML" time spent in
the Chrome inspector (see Timeline), I would be interested to know. Tips other
than, of course, "parse less HTML".

------
Iuz
There's always room for microframeworks, thank you.

------
jscheel
I'm going to go ahead and assume this is satire.

------
Sujan
Uh MVP (Minimum Viable Product) vs. MVP (Model View Presenter). That will be
confusing.

(still nice project of course)

~~~
cmsd2
I still find it hard not to think "Most Valuable Player" whenever i read MVP

~~~
bennyg
This is the real winner of the confusing acronym debate. Thank you little
league for forcing me to think that startups only need an insane athlete to
start getting users and feedback to mold the product.

------
ronocod
Would be nice to have Angular, Backbone and Knockout included in the speed
graph.

~~~
hellerbarde
Backbone's Underscore was included.

------
aniketpant
@tipirai Could you please put up more posts on usage and the documentation?

~~~
tipiirai
I'll do that on my next post. I just wanted to push out the general idea
first.

------
woah
key feature of many frameworks is that they break if you don't follow them
carefully, limiting damage from 10x developer's hacked together code. does
riot provide similar functionality?

~~~
tipiirai
Developing with Riot is completely different from other frameworks. It's just
3 functions and after 1.0 the API will be hardened. It's more of a design
pattern than a framework. The application developer is the biggest culprit for
breaking things.

~~~
sugerman
Calling this a framework is a bit of a stretch isn't it? I don't see how a few
helper functions that rely on a very large library constitute a framework for
doing anything at all.

~~~
tipiirai
Yeah. I guess it's more of an library, but it promotes the use of MVP design
pattern / way of coding – and can thus be interpreted as a framework. I might
change it to library if it makes more sense.

------
CmonDev
Which tool did you use to make those MVP diagrams? They look gorgeous!

~~~
JLehtinen
Thanks! They were drawn in Adobe Illustrator.

------
pearjuice
_Oh I didn 't know Cristopher Poole is a programmer!_

Okay, he isn't.

------
namuol
1kb (+ 93kb for mandatory jQuery dependency)

