SlideShare a Scribd company logo
Building Isomorphic Apps 
@spikebrehm
Spike Brehm 
____________________________ 
@spikebrehm 
@AirbnbNerds
1. Why Isomorphic JavaScript 
2. Isomorphic in the Wild 
3. How to Isomorph
Why Isomorphic JavaScript
What is Isomorphic 
JavaScript?
JavaScript code that can be shared between environments.
i·so·mor·phic 
same form
http://blog.nodejitsu.com/scaling-isomorphic-javascript-code/
Persistence 
Client 
DOM manipulation UX JavaScript 
View layer 
Application 
logic Routing 
Backend 
Ruby 
Python 
Java 
PHP 
Ye Olde Web App
Backend 
Ruby 
Python 
Java 
PHP 
Fat-Client, circa 2011 
Persistence 
Client 
DOM manipulation UX JavaScript 
View layer 
Application 
logic Routing
DOM manipulation UX 
Persistence 
Client 
JavaScript 
Shared 
JavaScript 
View layer 
Application 
logic Routing 
Backend 
Ruby 
Python 
Java 
PHP 
Isomorphic, circa 2013
Shared View Layer
DOM manipulation UX 
Persistence 
Client 
JavaScript 
Shared 
JavaScript 
View layer 
Application 
logic Routing 
Backend 
Ruby 
Python 
Java 
PHP 
Isomorphic, circa 2013
View layer
Markup 
Data presentation 
I18n 
Date, Currency formatting 
URL formatting
Isomorphic Use Cases 
1. “Single Page Apps” that can be fully rendered on 
the server. 
2. Ambitious apps that share logic between client & 
server to accomplish novel things.
Why go to the trouble?
Performance 
Initial pageload speed. 
SEO* 
Crawlable single-page apps. 
Flexibility 
Run code anywhere. 
Maintainability 
Reduce code duplication.
Performance
Client-rendered app 
Download 
skeleton 
HTML 
User sees 
content 
Download 
JavaScript 
Fetch data 
from API 
Evaluate 
JavaScript 
Exacerbated on mobile: high 
latency, low bandwidth
Server-rendered app 
Download 
full 
HTML 
Download 
JavaScript 
User sees 
content 
Evaluate 
JavaScript
Isomorphic JavaScript in the 
Wild
Flickr 
! Yahoo’s Modown libraries 
(successor to Mojito).
Instagram* 
! Facebook’s React library 
in a Django app.
Airbnb Mobile Web 
! Airbnb’s Rendr library, built on 
Backbone and Express.
Asana 
! Entire App runtime synced 
between client & server.
Meteor 
! Realtime app framework.
Isomorphic JavaScript is a 
spectrum
Entire view 
layer and app 
logic shared 
Small bits of 
view layer or 
logic shared
Many 
abstractions 
Few 
abstractions
How to Isomorph
Isomorphic JavaScript can be 
environment agnostic 
or 
shimmed per environment.
Environment 
agnostic 
Does not depend on browser-specific properties 
(window) or server-specific properties 
(process.env, req.cookies).
E X A M P L E 
Handlebars.js 
var template = ! 
'<ul>' ! 
'{{#each posts}}' ! 
' <li>{{title}}</li>' ! 
'{{/each}}' ! 
'</ul>';! 
! 
var templateFn = Handlebars.compile(template);! 
var html = templateFn({posts: posts});
Shimmed per 
environment 
Provide shims for accessing environment-specific 
properties so module can expose a single API. 
window.location.pathname 
vs 
req.path
E X A M P L E 
Superagent 
superagent! 
.get('/api/posts.json')! 
.end(function(res) {! 
console.log(res.status, res.body, res.headers);! 
});
Abstractions
A B S T R ACT I O N 
Cookies 
Client document.cookie =! 
'myCookie=1; Domain=.example.org'; 
Server 
res.setHeader(! 
'Set-Cookie: myCookie=1; ' +! 
'Domain=.example.org'! 
);
A B S T R ACT I O N 
Redirects 
Client 
document.location.href = '/login';! 
! 
window.pushState({}, '', '/login'); 
Server res.redirect('/login');
H AC K T I M E 
Let’s write a module that abstracts the setting of 
cookies, providing the same API for client & server.
H AC K T I M E 
setCookie('myCookie', 'the value'); 
document.cookie = 'myCookie=the%20value'; 
or 
res.setHeader('Set-Cookie: myCookie=the%20value;');
H AC K T I M E 
setCookie('myCookie', 'the value', {! 
path: '/',! 
domain: '.example.org',! 
expires: new Date(2014, 12, 31)! 
}); 
document.cookie =! 
'myCookie=the%20value; Domain=.example.org; ' +! 
'Path=/; Expires=Sat, 31 Jan 2015 05:00:00 GMT';
That looks kinda hard…
Building Isomorphic Apps (JSConf.Asia 2014)
NPM & Browserify* to the 
rescue
Browserify* Use CommonJS to require() modules in the 
browser.
Browserify* Package dependencies from node_modules into 
our bundle.
*or Webpack. 
Webpack is like Browserify, but with more bells-and- 
whistles included by default. 
Used by Instagram, Facebook, Yahoo!.
H AC K T I M E 
Caveat: It’s Different on the Server 
app.use(function(req, res, next) {! 
...! 
! next();! 
}); 
! 
setCookie('myCookie', 'the value', {res: res});! 
! 
! 
!
How do we make a shimmed-per-environment module? 
Utilize package.json’s “browser” field.
{! 
"name": "set-cookie",! 
"dependencies": {...}! 
}! 
! 
! 
!
{! 
"name": "set-cookie",! 
"dependencies": {...},! 
"browser": "./lib/client.js"! 
}! 
! 
! 
Swap out the entire implementation.
{! 
"name": "set-cookie",! 
"dependencies": {...},! 
"browser": {! 
"./lib/node.js": "./lib/client.js"! 
}! 
}! 
Swap out specific files.
{! 
"name": "set-cookie",! 
"dependencies": {...},! 
"browser": {! 
"./lib/node.js": "./lib/client.js",! 
"cookie": "cookie-browser"! 
}! 
} 
Swap out dependencies.
Let’s build `set-cookie`. 
https://github.com/spikebrehm/set-cookie
Module 
structure 
.! 
"## index.js! 
"## lib! 
$ %## setter! 
$ "## index.js! 
$ %## client.js! 
"## node_modules! 
$ %## cookie
// ./index.js! 
! 
var cookie = require('cookie');! 
var setter = require('./lib/setter');! 
! 
module.exports = function(name, value, options) {! 
var cookieStr = cookie.serialize(name, value, options);! 
setter(cookieStr, options);! 
};
// ./lib/setter/index.js! 
! 
module.exports = function setter(cookieStr, options) {! 
var res = options && options.res;! 
! 
if (!res)! 
throw new Error('Must specify `res` ' +! 
'when setting cookie.’);! 
! 
res.setHeader('Set-Cookie', cookieStr);! 
};
// ./lib/setter/client.js! 
! 
module.exports = function setter(cookieStr) {! 
document.cookie = cookieStr;! 
};
// ./package.json! 
! 
{! 
"name": "set-cookie",! 
"dependencies": {! 
"cookie": "^0.1.2"! 
},! 
"browser": {! 
"./lib/setter/index.js": "./lib/setter/client.js"! 
}! 
}
// ./index.js! 
! 
var cookie = require('cookie');! 
var setter = require('./lib/setter');! 
! 
module.exports = function(name, value, options) {! 
var cookieStr = cookie.serialize(name, value, options);! 
setter(cookieStr, options);! 
};
Projects of Note
React 
Reactive UI component library from Facebook. 
Designed from the ground up to support isomorphic rendering. 
http://facebook.github.io/react/ 
var UserProfile = React.createClass({ 
render: function() { 
return <div> 
<img src={this.props.user.thumbnailUrl} /> 
<h3>{this.props.user.name}</h3> 
</div>; 
} 
}); 
React.render(<UserProfile user={user} />, mountNode);
React 
Reactive UI component library from Facebook. 
Designed from the ground up to support isomorphic rendering. 
http://facebook.github.io/react/ 
var UserProfile = React.createClass({ 
render: function() { 
return <div> 
<img src={this.props.user.thumbnailUrl} /> 
<h3>{this.props.user.name}</h3> 
</div>; 
} 
}); 
React.render(<UserProfile user={user} />, mountNode);
React 
Reactive UI component library from Facebook. 
Designed from the ground up to support isomorphic rendering. 
http://facebook.github.io/react/ 
var UserProfile = React.createClass({ 
render: function() { 
return <div> 
<img src={this.props.user.thumbnailUrl} /> 
<h3>{this.props.user.name}</h3> 
</div>; 
} 
}); 
var html = React.renderToString(<UserProfile user={user} />);
Fluxible 
Yahoo’s isomorphic Flux implementation: Dispatchr, Fetchr, Routr. 
Provides a way to “dehydrate” server state and “rehydrate” on client. 
https://github.com/yahoo/flux-examples
Isobuild 
Meteor’s build system for isomorphic apps. 
Like Browserify & Webpack, uses static analysis to compute 
dependencies. Can target client, server, Android, or iOS. 
https://www.meteor.com/isobuild 
if (Meteor.isClient) { 
// counter starts at 0 
Session.setDefault("counter", 0); 
Template.hello.events({ 
'click button': function () { 
// increment the counter when button is clicked 
Session.set("counter", Session.get("counter") + 1); 
} 
}); 
} 
if (Meteor.isServer) { 
Meteor.startup(function () { 
// code to run on server at startup 
}); 
}
Isobuild 
Meteor’s build system for isomorphic apps. 
Like Browserify & Webpack, uses static analysis to compute 
dependencies. Can target client, server, Android, or iOS. 
https://www.meteor.com/isobuild 
if (Meteor.isClient) { 
// counter starts at 0 
Session.setDefault("counter", 0); 
Template.hello.events({ 
'click button': function () { 
// increment the counter when button is clicked 
Session.set("counter", Session.get("counter") + 1); 
} 
}); 
} 
if (Meteor.isServer) { 
Meteor.startup(function () { 
// code to run on server at startup 
}); 
}
isomorphic-tutorial 
Small sample isomorphic app, written from scratch using Handlebars/ 
React, Director (routing), and Superagent (API requests). 
https://github.com/spikebrehm/isomorphic-tutorial 
// app/routes.js 
var apiClient = require('./api_client'); 
module.exports = function(match) { 
match('/posts', function(callback) { 
apiClient.get('/posts.json', function(err, res) { 
if (err) return callback(err); 
var posts = res.body; 
callback(null, 'posts', {posts: posts}); 
}); 
}); 
};
isomorphic-tutorial 
Small sample isomorphic app, written from scratch using Handlebars/ 
React, Director (routing), and Superagent (API requests). 
https://github.com/spikebrehm/isomorphic-tutorial 
<h1>Posts</h1> 
<ul> 
{{#each posts}} 
<li><a href="/posts/{{id}}">{{title}}</a></li> 
{{/each}} 
</ul>
Thanks! 
More resources available at 
http://spike.technology 
! 
@spikebrehm 
@AirbnbNerds

More Related Content

PDF
JSConf US 2014: Building Isomorphic Apps
PDF
General Assembly Workshop: Advanced JavaScript
PDF
Integrating Browserify with Sprockets
PDF
Isomorphic JavaScript: #DevBeat Master Class
PDF
Building Isomorphic JavaScript Apps - NDC 2015
PDF
In Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
PDF
Isomorphic JavaScript with Nashorn
PDF
The Evolution of Airbnb's Frontend
JSConf US 2014: Building Isomorphic Apps
General Assembly Workshop: Advanced JavaScript
Integrating Browserify with Sprockets
Isomorphic JavaScript: #DevBeat Master Class
Building Isomorphic JavaScript Apps - NDC 2015
In Pursuit of the Holy Grail: Building Isomorphic JavaScript Apps
Isomorphic JavaScript with Nashorn
The Evolution of Airbnb's Frontend

What's hot (20)

KEY
Getting Started with HTML 5 Web workers
PDF
Node, express & sails
PDF
Web workers
PDF
Service Worker 201 (en)
PDF
Browserify
PDF
JavaScript Web Workers
PPTX
Workshop Intro: FrontEnd General Overview
PDF
Sails.js Intro
PDF
Packing it all: JavaScript module bundling from 2000 to now
PDF
JavaScript Dependencies, Modules & Browserify
PDF
Isomorphic web application
ODP
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
PDF
NodeWay in my project & sails.js
PPTX
An Intro into webpack
PPTX
Webpack
PDF
Webpack DevTalk
PDF
Web Workers
PDF
Grunt.js and Yeoman, Continous Integration
PDF
Avoiding Common Pitfalls in Ember.js
PDF
Webpack Tutorial, Uppsala JS
Getting Started with HTML 5 Web workers
Node, express & sails
Web workers
Service Worker 201 (en)
Browserify
JavaScript Web Workers
Workshop Intro: FrontEnd General Overview
Sails.js Intro
Packing it all: JavaScript module bundling from 2000 to now
JavaScript Dependencies, Modules & Browserify
Isomorphic web application
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
NodeWay in my project & sails.js
An Intro into webpack
Webpack
Webpack DevTalk
Web Workers
Grunt.js and Yeoman, Continous Integration
Avoiding Common Pitfalls in Ember.js
Webpack Tutorial, Uppsala JS
Ad

Similar to Building Isomorphic Apps (JSConf.Asia 2014) (20)

PDF
ParisJS #10 : RequireJS
PDF
Web APIs & Apps - Mozilla
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
PDF
从小书签到浏览器扩展的应用
PDF
Intro to node.js - Ran Mizrahi (27/8/2014)
PDF
Intro to node.js - Ran Mizrahi (28/8/14)
PDF
Html5 and beyond the next generation of mobile web applications - Touch Tou...
PDF
soft-shake.ch - Hands on Node.js
PDF
A Story about AngularJS modularization development
PPTX
Running Vue Storefront in production (PWA Magento webshop)
PPT
Building Single Page Application (SPA) with Symfony2 and AngularJS
PPTX
Event-driven IO server-side JavaScript environment based on V8 Engine
PDF
Mozilla Web Apps - Super-VanJS
PPT
Sanjeev ghai 12
PPT
Symfony2 and AngularJS
PDF
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
PDF
Refactor Large applications with Backbone
PDF
Refactor Large apps with Backbone
PDF
Refactoring Large Web Applications with Backbone.js
PDF
Vaadin 7 CN
ParisJS #10 : RequireJS
Web APIs & Apps - Mozilla
WebNet Conference 2012 - Designing complex applications using html5 and knock...
从小书签到浏览器扩展的应用
Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (28/8/14)
Html5 and beyond the next generation of mobile web applications - Touch Tou...
soft-shake.ch - Hands on Node.js
A Story about AngularJS modularization development
Running Vue Storefront in production (PWA Magento webshop)
Building Single Page Application (SPA) with Symfony2 and AngularJS
Event-driven IO server-side JavaScript environment based on V8 Engine
Mozilla Web Apps - Super-VanJS
Sanjeev ghai 12
Symfony2 and AngularJS
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
Refactor Large applications with Backbone
Refactor Large apps with Backbone
Refactoring Large Web Applications with Backbone.js
Vaadin 7 CN
Ad

Recently uploaded (20)

PDF
Modernizing your data center with Dell and AMD
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Encapsulation theory and applications.pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Empathic Computing: Creating Shared Understanding
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Approach and Philosophy of On baking technology
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Big Data Technologies - Introduction.pptx
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
Modernizing your data center with Dell and AMD
The AUB Centre for AI in Media Proposal.docx
Encapsulation theory and applications.pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Dropbox Q2 2025 Financial Results & Investor Presentation
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Chapter 3 Spatial Domain Image Processing.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
Understanding_Digital_Forensics_Presentation.pptx
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Empathic Computing: Creating Shared Understanding
Mobile App Security Testing_ A Comprehensive Guide.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Approach and Philosophy of On baking technology
The Rise and Fall of 3GPP – Time for a Sabbatical?
Big Data Technologies - Introduction.pptx
“AI and Expert System Decision Support & Business Intelligence Systems”

Building Isomorphic Apps (JSConf.Asia 2014)

  • 2. Spike Brehm ____________________________ @spikebrehm @AirbnbNerds
  • 3. 1. Why Isomorphic JavaScript 2. Isomorphic in the Wild 3. How to Isomorph
  • 5. What is Isomorphic JavaScript?
  • 6. JavaScript code that can be shared between environments.
  • 9. Persistence Client DOM manipulation UX JavaScript View layer Application logic Routing Backend Ruby Python Java PHP Ye Olde Web App
  • 10. Backend Ruby Python Java PHP Fat-Client, circa 2011 Persistence Client DOM manipulation UX JavaScript View layer Application logic Routing
  • 11. DOM manipulation UX Persistence Client JavaScript Shared JavaScript View layer Application logic Routing Backend Ruby Python Java PHP Isomorphic, circa 2013
  • 13. DOM manipulation UX Persistence Client JavaScript Shared JavaScript View layer Application logic Routing Backend Ruby Python Java PHP Isomorphic, circa 2013
  • 15. Markup Data presentation I18n Date, Currency formatting URL formatting
  • 16. Isomorphic Use Cases 1. “Single Page Apps” that can be fully rendered on the server. 2. Ambitious apps that share logic between client & server to accomplish novel things.
  • 17. Why go to the trouble?
  • 18. Performance Initial pageload speed. SEO* Crawlable single-page apps. Flexibility Run code anywhere. Maintainability Reduce code duplication.
  • 20. Client-rendered app Download skeleton HTML User sees content Download JavaScript Fetch data from API Evaluate JavaScript Exacerbated on mobile: high latency, low bandwidth
  • 21. Server-rendered app Download full HTML Download JavaScript User sees content Evaluate JavaScript
  • 23. Flickr ! Yahoo’s Modown libraries (successor to Mojito).
  • 24. Instagram* ! Facebook’s React library in a Django app.
  • 25. Airbnb Mobile Web ! Airbnb’s Rendr library, built on Backbone and Express.
  • 26. Asana ! Entire App runtime synced between client & server.
  • 27. Meteor ! Realtime app framework.
  • 29. Entire view layer and app logic shared Small bits of view layer or logic shared
  • 30. Many abstractions Few abstractions
  • 32. Isomorphic JavaScript can be environment agnostic or shimmed per environment.
  • 33. Environment agnostic Does not depend on browser-specific properties (window) or server-specific properties (process.env, req.cookies).
  • 34. E X A M P L E Handlebars.js var template = ! '<ul>' ! '{{#each posts}}' ! ' <li>{{title}}</li>' ! '{{/each}}' ! '</ul>';! ! var templateFn = Handlebars.compile(template);! var html = templateFn({posts: posts});
  • 35. Shimmed per environment Provide shims for accessing environment-specific properties so module can expose a single API. window.location.pathname vs req.path
  • 36. E X A M P L E Superagent superagent! .get('/api/posts.json')! .end(function(res) {! console.log(res.status, res.body, res.headers);! });
  • 38. A B S T R ACT I O N Cookies Client document.cookie =! 'myCookie=1; Domain=.example.org'; Server res.setHeader(! 'Set-Cookie: myCookie=1; ' +! 'Domain=.example.org'! );
  • 39. A B S T R ACT I O N Redirects Client document.location.href = '/login';! ! window.pushState({}, '', '/login'); Server res.redirect('/login');
  • 40. H AC K T I M E Let’s write a module that abstracts the setting of cookies, providing the same API for client & server.
  • 41. H AC K T I M E setCookie('myCookie', 'the value'); document.cookie = 'myCookie=the%20value'; or res.setHeader('Set-Cookie: myCookie=the%20value;');
  • 42. H AC K T I M E setCookie('myCookie', 'the value', {! path: '/',! domain: '.example.org',! expires: new Date(2014, 12, 31)! }); document.cookie =! 'myCookie=the%20value; Domain=.example.org; ' +! 'Path=/; Expires=Sat, 31 Jan 2015 05:00:00 GMT';
  • 43. That looks kinda hard…
  • 45. NPM & Browserify* to the rescue
  • 46. Browserify* Use CommonJS to require() modules in the browser.
  • 47. Browserify* Package dependencies from node_modules into our bundle.
  • 48. *or Webpack. Webpack is like Browserify, but with more bells-and- whistles included by default. Used by Instagram, Facebook, Yahoo!.
  • 49. H AC K T I M E Caveat: It’s Different on the Server app.use(function(req, res, next) {! ...! ! next();! }); ! setCookie('myCookie', 'the value', {res: res});! ! ! !
  • 50. How do we make a shimmed-per-environment module? Utilize package.json’s “browser” field.
  • 51. {! "name": "set-cookie",! "dependencies": {...}! }! ! ! !
  • 52. {! "name": "set-cookie",! "dependencies": {...},! "browser": "./lib/client.js"! }! ! ! Swap out the entire implementation.
  • 53. {! "name": "set-cookie",! "dependencies": {...},! "browser": {! "./lib/node.js": "./lib/client.js"! }! }! Swap out specific files.
  • 54. {! "name": "set-cookie",! "dependencies": {...},! "browser": {! "./lib/node.js": "./lib/client.js",! "cookie": "cookie-browser"! }! } Swap out dependencies.
  • 55. Let’s build `set-cookie`. https://github.com/spikebrehm/set-cookie
  • 56. Module structure .! "## index.js! "## lib! $ %## setter! $ "## index.js! $ %## client.js! "## node_modules! $ %## cookie
  • 57. // ./index.js! ! var cookie = require('cookie');! var setter = require('./lib/setter');! ! module.exports = function(name, value, options) {! var cookieStr = cookie.serialize(name, value, options);! setter(cookieStr, options);! };
  • 58. // ./lib/setter/index.js! ! module.exports = function setter(cookieStr, options) {! var res = options && options.res;! ! if (!res)! throw new Error('Must specify `res` ' +! 'when setting cookie.’);! ! res.setHeader('Set-Cookie', cookieStr);! };
  • 59. // ./lib/setter/client.js! ! module.exports = function setter(cookieStr) {! document.cookie = cookieStr;! };
  • 60. // ./package.json! ! {! "name": "set-cookie",! "dependencies": {! "cookie": "^0.1.2"! },! "browser": {! "./lib/setter/index.js": "./lib/setter/client.js"! }! }
  • 61. // ./index.js! ! var cookie = require('cookie');! var setter = require('./lib/setter');! ! module.exports = function(name, value, options) {! var cookieStr = cookie.serialize(name, value, options);! setter(cookieStr, options);! };
  • 63. React Reactive UI component library from Facebook. Designed from the ground up to support isomorphic rendering. http://facebook.github.io/react/ var UserProfile = React.createClass({ render: function() { return <div> <img src={this.props.user.thumbnailUrl} /> <h3>{this.props.user.name}</h3> </div>; } }); React.render(<UserProfile user={user} />, mountNode);
  • 64. React Reactive UI component library from Facebook. Designed from the ground up to support isomorphic rendering. http://facebook.github.io/react/ var UserProfile = React.createClass({ render: function() { return <div> <img src={this.props.user.thumbnailUrl} /> <h3>{this.props.user.name}</h3> </div>; } }); React.render(<UserProfile user={user} />, mountNode);
  • 65. React Reactive UI component library from Facebook. Designed from the ground up to support isomorphic rendering. http://facebook.github.io/react/ var UserProfile = React.createClass({ render: function() { return <div> <img src={this.props.user.thumbnailUrl} /> <h3>{this.props.user.name}</h3> </div>; } }); var html = React.renderToString(<UserProfile user={user} />);
  • 66. Fluxible Yahoo’s isomorphic Flux implementation: Dispatchr, Fetchr, Routr. Provides a way to “dehydrate” server state and “rehydrate” on client. https://github.com/yahoo/flux-examples
  • 67. Isobuild Meteor’s build system for isomorphic apps. Like Browserify & Webpack, uses static analysis to compute dependencies. Can target client, server, Android, or iOS. https://www.meteor.com/isobuild if (Meteor.isClient) { // counter starts at 0 Session.setDefault("counter", 0); Template.hello.events({ 'click button': function () { // increment the counter when button is clicked Session.set("counter", Session.get("counter") + 1); } }); } if (Meteor.isServer) { Meteor.startup(function () { // code to run on server at startup }); }
  • 68. Isobuild Meteor’s build system for isomorphic apps. Like Browserify & Webpack, uses static analysis to compute dependencies. Can target client, server, Android, or iOS. https://www.meteor.com/isobuild if (Meteor.isClient) { // counter starts at 0 Session.setDefault("counter", 0); Template.hello.events({ 'click button': function () { // increment the counter when button is clicked Session.set("counter", Session.get("counter") + 1); } }); } if (Meteor.isServer) { Meteor.startup(function () { // code to run on server at startup }); }
  • 69. isomorphic-tutorial Small sample isomorphic app, written from scratch using Handlebars/ React, Director (routing), and Superagent (API requests). https://github.com/spikebrehm/isomorphic-tutorial // app/routes.js var apiClient = require('./api_client'); module.exports = function(match) { match('/posts', function(callback) { apiClient.get('/posts.json', function(err, res) { if (err) return callback(err); var posts = res.body; callback(null, 'posts', {posts: posts}); }); }); };
  • 70. isomorphic-tutorial Small sample isomorphic app, written from scratch using Handlebars/ React, Director (routing), and Superagent (API requests). https://github.com/spikebrehm/isomorphic-tutorial <h1>Posts</h1> <ul> {{#each posts}} <li><a href="/posts/{{id}}">{{title}}</a></li> {{/each}} </ul>
  • 71. Thanks! More resources available at http://spike.technology ! @spikebrehm @AirbnbNerds