Create high-performance mobile UIs with Famo.us
Level up to a native-code user experience for JavaScript apps
The JavaScript developer community eagerly greeted the spring 2014 public beta release of the Famo.us open source UI-rendering framework. Famo.us promises to eliminate some of the last bottlenecks that prevented JavaScript and web technology from dominating the mobile development scene: slow UIs and a poor user experience (UX).
Famo.us targets the hardware graphics processing unit (GPU) on the mobile device to achieve the highest possible rendering frame rate, and it adds a sophisticated physics engine for a gratifying UX. JavaScript developers are no longer at a disadvantage compared to Objective-C, Swift, or Java™ developers when they create UIs for mobile apps.
This article introduces the fundamental concepts of Famo.us and explores its design. It then goes hands-on with several working examples, including a typical mobile app UI that you can use as an application template for developing with Famo.us. (See Download to get the full sample code.)
How Famo.us works
Animation is created by the rapid display of successive pages (frames) with changed elements. Frame rate is the number of frames that are displayed per second. A high frame rate creates the optical illusion of motion because of the latency in human vision (the same principle behind motion pictures). To create animation on web pages, elements' style attributes — position, color, and opacity — are modified every frame. How quickly these attributes can be updated ultimately determines the maximum frame rate of a UI. For interaction with web applications, 60 frames per second (fps) is deemed the optimal rate for a smooth, native-application-like UX. When 60 fps can't be achieved consistently, undesirable UX effects such as jerkiness and dropouts (known collectively as Jank) occur.
At its core, Famo.us is a cross-browser, high-performance UI layout, and optimization library with its own animation and physics engine — written in JavaScript. Famo.us is optimized to perform its work within the shortest possible time per frame. (A recent Famo.us benchmark shows that Famo.us can take as little as 1 to 2 ms per 16.7 ms frame while it handles typical animation and has no performance overhead otherwise.) The target UI can then be rendered at the best possible frame rate — typically a minimum of 60 fps. The Famo.us project is committed to maintaining or improving this fps performance in all subsequent releases.
Operationally, Famo.us replaces typical DOM-centric layout operations and
2D or 3D animations with its own high-performance alternative. Figure 1
illustrates the inner workings of Famo.us. The Famo.us engine (a singleton
object) is called for every frame by the browser's requestAnimationFrame()
(rAF) callback function.
Sixty times per second corresponds to 60 fps or 1/60s (16.7 ms) per frame.
Each callback is known as an engine tick in Famo.us.
Figure 1. Operation of the Famo.us library

The Famo.us API
The Famo.us API presents its own set of high-level composable objects — such as surfaces, views, and widgets— to the developer. Your Famo.us code creates the scene graph to be rendered (currently called a render tree in Famo.us), wires up event handling, and directs or schedules animations.
Each node in the Famo.us scene graph is a render node. The scene graph is processed into render spec and build spec intermediary representations that the Famo.us rendering component uses internally to make updating of the target more efficient.
The rendering component evaluates the scene graph at the supported frame rate (currently 60 fps) and outputs the required updates to the browser's DOM, a Canvas element, or WebGL. (The beta implementation of Famo.us targets the browser's DOM only.) Famo.us is designed to output to any of its supported targets — even simultaneously (supporting multimode operations) — on the same screen.
Surfaces and renderables
In Famo.us, you compose and animate renderables. The lowest-level
common renderable that you work with is a Surface
. A
Surface
displayed in the browser's DOM is a
<div>
element. (If you inspect a Famo.us
Surface
, you can see the <div>
.) Other
specialized types of surfaces in Famo.us are represented by other HTML5
elements:
Surface
is a<div>
.VideoSurface
is a<video>
.ImageSurface
is a<img>
.InputSurface
is a<input>
.CanvasSurface
is a<canvas>
.
The Surface
class has a content
field. This field
is where you add the HTML to be rendered on the Surface
(within the underlying <div>
).
Famo.us does not intervene in how or where you get this
content
, which is a string that is rendered as HTML. This
string is a natural integration point for any template, data sourcing, or
data binding technology. In addition, the mini-DOM that is formed by the
HTML on a rendered Surface
can be manipulated — except
for any layout, containment, or animation work, which should be done
through Famo.us.
“When you program with Famo.us, you gain in performance and rendering flexibility, in exchange for direct immediate-mode manipulation of the page's DOM.”
Comparison with 3D rendering libraries
This architecture of Famo.us is similar to WebGL 3D-rendering JavaScript libraries, including Three.js and SceneJS. Knowing the similarities and differences can help to fast-track your mastery of Famo.us:
- Frame rendering is triggered by browser rAF in both architectures.
- In 3D rendering libraries, you position and place triangles and 2D objects (such as walls, or floors) and higher-level 3D geometries (such as pyramids, spheres, cubes, or meshes of polygons) into the scene graph. In Famo.us, you position and place 2D surfaces or higher-level objects such as views or widgets in your scene graph.
- In 3D rendering libraries, you can transform an object by adding and chaining transformation nodes in the scene graph, where the object is the leaf. In Famo.us, you can add and chain modifier nodes into the scene graph, where a surface or other renderable is the leaf.
- In SceneJS, you can specify a complex scene graph by using JSON and
modify it through ID attributes on the graph nodes. Famo.us has a
Scene
component that you can use to build a complex scene graph via JSON; you modify it through ID attributes on render nodes. - In 3D libraries, object attributes are animated and tweened on rAF callbacks. In Famo.us, the properties of surfaces (more generally, renderables) are updated and tweened on each tick of the Famo.us engine, which is driven by the browser's rAF callback.
- 3D libraries often include a physics engine to make animation more realistic. Famo.us includes a full physics engine to make animations more intuitive to the user.
- Even though all objects in a 3D scene are composed of triangles, developers seldom need to work with individual triangles because 3D rendering libraries typically include meshes of common geometries such as spheres and pyramids. Even though the fundamental renderable in Famo.us is a surface, you seldom need to work with an individual surface because the library includes many prefabricated high-level UI views and widgets.
- HTML has no role in a 3D library other than the Canvas element being
the element that the 3D viewport is rendered on. In Famo.us, HTML is
what you render on a surface, but HTML no longer defines the structure
of the UI page; the structure is specified in JavaScript code. You no
longer need to manage a raft of<
<div>
or<table>
tags to control layout; and CSS is used only to affect element style, not layout. (HTML is still important because — when the DOM is targeted — all visual elements are HTML elements.) - The rendering component of 3D libraries typically targets Canvas, WebGL, and SVG output — favoring WebGL for its almost direct access to the underlying 3D-rendering GPU hardware. The Famo.us rendering component targets Canvas, DOM, and WebGL. Famo.us has a DOM updater that uses known GPU optimizations offered by leading browsers to achieve its performance objective.
Working with Famo.us
A look at an actual Famo.us app helps you anchor the concepts. The example
in Figure 2 is the default application included with the Famo.us starter
kit and also generated by default by the generator-famous
package (see Three ways to run Famo.us). The
application trivially rotates a rendition of the Famo.us logo around the
y-axis.
Figure 2. Default application that is generated
by generator-famous

In main.js, the solo ImageSurface
is created by the code that
is shown in Listing 1.
Listing 1. Creating the ImageSurface
(renders to
DOM
<img>)
var logo = new ImageSurface({ size: [200, 200], content: '/content/images/famous_logo.png', classes: ['backfaceVisibility'] });
In Listing 1, the content
option corresponds to the
src
attribute of the underlying <img>
tag.
The classes
option adds CSS classes to the HTML element. The
backfaceVisibility
CSS class, which ensures that users can
see the back side of the logo as it turns, is defined in app.css as:
.backfaceVisibility { -webkit-backface-visibility: visible; backface-visibility: visible; }
Context— a mini DOM manager that is associated with a DOM node — manages one scene graph, represented by all the DOM within the node. Typically you have only one context instance (unless you're working on special projects such as multiple perspectives or heads-up displays).
Modifiers are render nodes in the Famo.us scene graph that modify some attributes of (typically, apply transformations to) render nodes below them. You can chain multiple modifiers together, in which case the transformation matrixes are combined together, and the leaves of the scene graph are always renderables.
In this example, the centerSpinModifier
contains an
origin
property and a transform
property. The
origin
property is specified relative to the containing
parent — in this case, the Famo.us context. Figure 3 shows the
convention for specifying the Famo.us origin
.
Figure 3. Convention for setting the
origin
property

In Figure 3, nine points are arranged in a 3x3 grid. [0.0] is at the upper left, and [1,1] is at the lower right. [0.5, 0.5] is the center point. The rest of the points follow this convention, such as [1,0] at the upper right and [0,1] at the lower left.
The transform
attribute in centerSpinModifier
returns a function that rotates around the y-axis, via
Transform.rotateY()
:
var initialTime = Date.now(); var centerSpinModifier = new Modifier({ origin: [0.5, 0.5], transform : function() { return Transform.rotateY(.002 * (Date.now() - initialTime)); } }); mainContext.add(centerSpinModifier).add(logo);
This code completes the simple scene graph that is shown in Figure 4.
Figure 4. Scene graph for the default application

Now the Famo.us engine evaluates the in-memory scene graph and efficiently
updates the DOM on every frame, approximately 60 times per second, driven
by rAF. Each time, the centerSpinModifer
checks the time that
is elapsed since initialTime
and rotates the logo
incrementally around the y-axis. You can easily adjust the 0.002 constant
to vary the speed of the spin.
To summarize:
- You create the
logo
ImageSurface
. - You create a Famo.us
Modifier
that:- Sets the logo to rotate around its own center
(
origin
= [0.5 0.5]) at the center of the context - Uses a
transform
that incrementally rotates around the y-axis
- Sets the logo to rotate around its own center
(
- You add the
Modifier
to the scene graph and then add thelogo ImageSurface
directly below theModifier
. - The Famo.us engine processes the scene graph and updates the DOM at rAF rate, and the logo rotates nonstop.
Extending the example
To take the default example further, the next example rotates 100 instances of the logo, laid out in the form of a 10x10 square, alternating rotation between the x-axis and the y-axis. Figure 5 shows the final app in action.
Figure 5. Extended app that rotates 100 logo instances

Figure 6 shows the scene graph that must be constructed for this example.
Figure 6. Scene graph of extended app

You can see how this version extends the previous example:
- The scene graph now has 100 branches instead of 1.
- Each branch now has two modifiers. Another translation modifier is created and added before the rotation modifier to move the logo first to the required position.
The code to create the modifiers and add them to the context for each logo, which is shown in Listing 2, is similar to the first example. It contains the computation work to animate and update every frame.
Listing 2. Extended example of code to rotate 100 logos
var mainContext = Engine.createContext(); var initialTime = Date.now(); function rotY() { return Transform.rotateY(.002 * (Date.now() - initialTime)); } function rotX() { return Transform.rotateX(.002 * (Date.now() - initialTime)); } for (var i=0; i< 10; i ++) for (var j=0; j<10; j++) { var image = new ImageSurface({ size: [50, 50], content: '/content/images/famous_logo.png' }); var transMod = new Modifier({ size: image.getSize.bind(image), transform: Transform.translate(j * 50, i * 50, 0) } ); var rotMod = new Modifier({ origin: [0.5, 0.5], // xor transform : (((i % 2) !== (j % 2)) ? rotY : rotX) }); mainContext.add(transMod).add(rotMod).add(image);
This app has two separate transform functions, rotY
to rotate
around the y-axis and rotX
to rotate around x-axis. The
branches of the scene graph are created in a nested
i
-j
loop. The two modifiers added to each branch
are named transMod
(translation of the logo image into place)
and rotMod
(rotation of the logo around its own origin).
To alternate between x-axis and y-axis rotation, rotMod
's
transform
attribute is changed alternately by:
transform : (((i % 2) !== (j % 2)) ? rotY : rotX)
As in the first example, you set up the scene graph in-memory, and the Famo.us engine takes care of processing it and updating the DOM at rAF rate.
Transitions and tweens for animation
In UI creation, you typically work with animations of finite duration. One example is the "bounce" that users observe when they reach the end of a scrolling list. Another is the flipping of a playing card from its back to reveal its face.
Famo.us supports transitions via the Transitionable
class,
which represents attributes that can make the transition over time. The
next example shows the use of two tween transitions.
When you run the app, you see a list of developerWorks articles that displays within a Famo.us scroll view in the middle of the page. This list rotates around the y-axis at a constant pace for the first 10 seconds. Then, it snaps back violently and bounces around for the next 10 seconds. While this finite-duration animation is taking place, you can continually scroll through the list (with your mouse wheel if you're using a desktop browser). Figure 7 shows the app in action.
Figure 7. Scrolling article list rotates around y-axis that is animated by tween transitions

Views such as the scrolling list of articles are prefabricated higher-level
Famo.us components (in this case a ScrollContainer
) that can
be composed together for easy UI creation. The next example explores
Famo.us views and widgets in more detail. For now, it is sufficient to
understand that the scroll list consists of a sequenced set of Famo.us
Surface
s. Listing 3 shows the list-creation code.
Listing 3. Creating a scrolling list of articles
function createArticlesList() { artListSVC = new ScrollContainer({ scrollview: {direction: Utility.Direction.Y} }); var lines = []; artListSVC.sequenceFrom(lines); for (var i in articles) { var surf = new Surface({ content: '<div class"a-title">' + articles[i].title + '</div>', size: [undefined, 50], properties: { textAlign: 'left', color: 'black' } }); surf.addClass('article-cell'); surf.addClass('backfaceVisibility'); surf.artIdx = i; surf.pipe(eh); lines.push(surf); } artListSVC.container.addClass('backfaceVisibility'); artListSVC.container.addClass('borderbox'); }
In Listing 3, an array of Famo.us
Surface
s is created, named lines
. Each
Surface
created displays the name of one developerWorks
article. A Famo.us ScrollContainer
named
artListSVC
is created, and its sequenceFrom()
method is used to configure the scroll list with the lines
array.
Programming tween transitions
A view such as artListSVC
is also a renderable (managing its
own internal scene graph with renderables as leaves). The view can be
transformed via a modifier (or modifiers) and added to the context's scene
graph, as in previous examples. The code that adds artListSVC
to the context is:
var sm = new StateModifier({align:[0.5, 0.5], origin: [0.5, 0.5]}); mainContext.add(sm).add(artListSVC);
A StateModifier
is a modifier that maintains state over time
(internally, through Transitionable
s). When you animate by
using tween transitions, you specify only the beginning and end states
(also known as key frames). The tween transition interpolates the
intermediate state values and supplies them to the rendering engine on
every tick. You do not need to calculate or maintain intermediate state in
your own code.
Listing 4 shows the code that programs the tween transition.
Listing 4. Animating with tween transition
Transitionable.registerMethod('tween', TweenTransition); � sm.setTransform(Transform.rotateY(Math.PI), {method: 'tween', curve:'linear', duration:10000}, function() { sm.setTransform(Transform.rotateY(2 * Math.PI), {method: 'tween', duration: 10000, curve: 'spring'}); });
The code in Listing 4 first registers
TweenTransition
as a tween
method with
Transitionable
. The setTransform()
method of the
StateModifier
is then used to add the tweened
rotateY
transform. The setTransform()
method
takes a transform as the first argument, a Transitionable
as
the second, and a completion callback function as the third.
In Listing 4, the first animated transition lasts
10 seconds, and the scroll list rotates around the y-axis at a linear
pace. When this first tween completes, the callback is fired, and the
second tween uses a spring
curve that snaps back and bounces
for the next 10 seconds.
It's not necessary to register the TweenTransition
explicitly,
because Famo.us uses TweenTransition
by default if the
method
attribute is not specified for a
Transitionable
. However, Listing 4
illustrates how you might register another transitioning method —
such as a transition from the Famo.us physics engine. (Coverage of the
Famo.us physics engine is out of scope for this article.)
Rendering perspective
The rendering perspective, which you specify in pixels, correlates to the
distance from the viewer's "camera" to the scene that is rendered. Use
Context.setPerspective()
to set this value. A smaller value
brings the viewer closer to the rendered objects while it maintain the
same field of view and is loosely analogous to a wide-angle lens on a
camera. By varying the perspective, you can enhance the look of many
animations. Perspective is set to 500 in this example for a more dramatic
effect.
Applying Famo.us to a typical mobile app UI
The examples so far operate Famo.us like a 3D rendering library, except with 2D surfaces — pure object animation. The next sample confirms that this style of composition and animation translates to the construction of a mobile UI.
Figure 8 shows a common mobile application layout. A navigation bar is at the top, and "back" and "more" buttons (not shown in Figure 8) are activated depending on the state of the UI. At the bottom is a tab bar that consists of a set of toggle buttons (each of which you can style by using CSS) that selects the items that are displayed in the content area. The content area is in the middle, flexibly sized depending on the device size.
Figure 8. Composing mobile app UIs in Famo.us

Typically, the app contains a thumb-scrollable list of items that users can further explore. In this example app, you can choose between a list of developerWorks articles and a list of open source movies.
When the user selects one of the items, the content area changes to display the selected item. The item might open only within the content area (that is, with header and footer still visible) or occupy the entire screen (obscuring the header and footer).
Trying out the app
Try the app in your mobile browser:
When the app starts, it displays the list of articles, as in Figure 9.
Figure 9. App display of developerWorks articles

If you touch the Videos button in the tab bar, the list of open source movies is displayed, as in Figure 10.
Figure 10. App display of open source videos

If you touch one of the videos in the list, it loads and plays in the content area, as in Figure 11.
Figure 11. App playing a movie

In Figure 11, notice that the navigation bar now shows a back button. If you touch that button, the list of videos is displayed again. Touch Articles again to redisplay the list of articles. Now touch one of the article names. The app loads and displays the selected article, as in Figure 12.
Figure 12. App display of a selected article

Using Famo.us views and widgets
Combining Famo.us views and widgets makes creation of the mobile app UI straightforward.
Surfaces (and renderables in general) and views can be composed into widgets. Views can contain complex orchestration and interaction logic among the managed renderables. Views can receive, process, and emit events by using the eventing support in Famo.us. Widgets are themselves render nodes that can be added as leaves of the context's scene graph. Famo.us comes with a selection of ready-to-use views and widgets:
Scrollview
controls a sequential list of renderables (in x or y direction) and enables scrolling through the list with touch or mouse — typically, through a sequence of surfaces.HeaderFooterLayout
manages three renderables: a header and a footer of specified size, and a content area of variable size. This view is used to lay out the example's mobile UI.EdgeSwapper
is container that manages display of multiple renderables by sliding them in from the edge of the parent. The example mobile UI uses this view to display the two scrollable lists.ScrollContainer
is view that contains aScrollview
and a managedSurface
that is used to clip theScrollView
's displayed content. The example mobile UI uses aScrollContainer
in theHeaderFooterLayout
's content area to display lists of articles or videos.
The example mobile UI uses three widgets:
NavigationBar
is a mini app-view that manages the display of a title surface and two clickable surfaces that represent the "back" and "more" buttons of a navigation bar. The widget emitsback
andmore
events.TabBar
manages a horizontally or vertically laid out bar of widgets. (The default is a toggle button.) When a managed widget is selected, its corresponding ID is emitted with aselect
event.ToggleButton
is a button, either on or off, that displays two managed surfaces.
Using the available views and widgets, the mobile UI becomes the scene graph that is shown in Figure 13.
Figure 13. Scene graph for the mobile app UI

Although the context is still at the root of the tree, the modifiers and leaves of the tree are no longer easily discernable. Each composed Famo.us view encapsulates components' management details, providing the expected user interactions and behavior — and eliminating the need for you to code them.
To create the mobile UI, you code up the scene graph; the Famo.us engine then processes it and updates the DOM at rAF rate:
- Create the list of articles — a Famo.us
ScrollContainer
containing aScrollview
managing a list ofSurface
s (cells in the list), one for each article:function createArticlesList() { artListSVC = new ScrollContainer({ scrollview: {direction: Utility.Direction.Y} }); var lines = []; artListSVC.sequenceFrom(lines); for (var i in articles) { var surf = new Surface({ content: '<div class="a-title">' + articles[i].title + '</div><div class="a-desc">' + articles[i].desc + '</div>', size: [undefined, 100], properties: { itemType: 'article', listIndex: i, textAlign: 'left', color: 'black' } }); surf.artIdx = i; surf.pipe(eh); lines.push(surf); } } function createWebSurface() { wb = new Surface( ); }
Notice the highlighted
content
property, which is set to the HTML used to render a cell in the list, together with the associated CSS classes.itemType
andlistIndex
are two custom properties that identify the actual data item that is selected in theclick
event handler. - Create the list of videos. (The code, not shown here, is similar to the step 1 code).
- Create a
Surface
to display a selected article:function createWebSurface() { wb = new Surface( ); }
- Create a
Surface
to display a selected video:function createVideoSurface() { vs = new VideoSurface( { size: [undefined,undefined], autoplay: true } ); }
- Create the
NavigationBar
widget and add it to the header:function addHeader() { nb = new NavigationBar({ size: [undefined, 75], content: 'dW Famo.us', moreContent: '', backContent: '', properties: { lineHeight: '75px' } }); layout.header.add(nb); eh.subscribe(nb); eh.on('back', function() { rc.setOptions({ inTransition: false, outTransition: true }); if (backTarget !== undefined) rc.show(backTarget); setNavbarBack(false, undefined); }); }
- Create the
EdgeSwapper
view and add it to the content area. This controller swaps in the list of articles, the list of videos, the display of one article, or the display of one video:function addContent() { rc = new EdgeSwapper({ overlap: false, outTransition: false, size:[undefined, undefined] }); layout.content.add(rc); }
- Create the tab bar and add it to the footer:
function addFooter() { var tb = new TabBar({ }); layout.footer.add(tb); tb.defineSection(0,{content: 'Articles', onClasses: ['tabbuton'], offClasses: ['tabbutoff']}); tb.defineSection(1,{content: 'Videos', onClasses: ['tabbuton'], offClasses:['tabbutoff']}); tb.select(0); eh.subscribe(tb); eh.on('select', function(but) { rc.setOptions({ inTransition: false, outTransition: false }); switch (but.id) { case 0: rc.show(artListSVC); break; case 1: rc.show(vidListSVC); break; } setNavbarBack(false, undefined); }); }
The CSStabbuton
class styles the button's on state, andtubbutoff
styles the off state. The event handler for theselect
event displays the article list if button0
is touched or the video list if button1
is touched. - Display the article list in the content area. Add an event handler for
click
events that are emitted from the selection within theScrollview
:function init() { rc.show(artListSVC); eh.on('click', function(obj) { rc.setOptions( { inTransition: true, outTransition: false }); var surfaceProps = obj.origin.getProperties(); if (surfaceProps.itemType === 'article') { wb.setContent('<iframe width="100%" height="100%" src="' + articles[surfaceProps.listIndex].url + '"></iframe>'); rc.show(wb); setNavbarBack(true, artListSVC); } else { // video vs.setContent(videos[surfaceProps.listIndex].url); rc.show(vs); setNavbarBack(true, vidListSVC); } }); }
The in-memory scene graph is now specified, and required event handlers are all wired, ready for the Famo.us engine to process.
Examine the Famo.us scene graph that is created in this example (see Figure 13). You might easily modify it to select and display other information — simply by changing the data source and modifying styles. Such modifications can even be parameterized and automated. Essentially, you can create a UI application template for a general class of "browse a list and select to show item" mobile apps. A comprehensive collection of such application templates can be built over time to cover a large variety of possible app areas.
Conclusion
Creating native-code mobile apps is hard. You need to climb steep learning curves not only of multiple mobile operating systems (and revision differences), but also of different programming languages and hundreds of system APIs on each platform. Add proprietary or customized toolbelts, plus varying build-and-deployment pipelines and marketplaces, and you end up with a potpourri of fast-evolving technologies that you must keep up with and support. Even if you have ready-to-use boilerplate code for your application, adapting it to a new problem across mobile platforms can take weeks or months of coding and debugging.
Meanwhile, web technologies for mobile app development, despite their cross-platform promise, fall far short of delivering a native-code UX — until now. The Famo.us framework combines recent breakthroughs in browser optimization and mature concepts from 3D rendering libraries to deliver a high-performance, easy-to-use, highly automatable UI-creation platform for mobile web applications. Now JavaScript developers can easily create mobile apps that offer user experiences that rival native-code implementations.
Acknowledgments
The author would like to thank Andrew De Andrade and Larry Robinson of Famo.us for their kind assistance in reviewing the article; also Jeanne Feldkamp and Steve Newcomb for their time and the interview.
Downloadable resources
- PDF of this content
- Sample code (sample-code.zip | 65KB)
Related topics
- Famo.us: Visit the Famo.us website to access the official documentation, developer guides, and demos. While you're there, check out Famo.us university, an interactive training platform — created with Famo.us — where you can change code and immediately see the effects.
- "3D development with WebGL, Part 2: Code less, do more with WebGL libraries" (Sing Li, developerWorks, January 2014): Learn to program scene graphs and rAF rendering by using SceneJS and Three.js.
- Demo: Installing Famo.us: See how to install Famo.us by using the Famo.us Toolbelt.
- Famo.us + Angular: If you already work with AngularJS, check out this project. Ongoing open source community projects are working on integrating Famo.us with other popular JavaScript frameworks too, including Backbone, and Meteor.
- Famo.us: Download the Famo.us starter kit.
- Famo.us GitHub repository: Get the Famo.us source code.