SlideShare a Scribd company logo
1 of 71
Download to read offline
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…
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

What's hot

Getting Started with HTML 5 Web workers
Getting Started with HTML 5 Web workersGetting Started with HTML 5 Web workers
Getting Started with HTML 5 Web workersFlumes
 
Node, express & sails
Node, express & sailsNode, express & sails
Node, express & sailsBrian Shannon
 
Service Worker 201 (en)
Service Worker 201 (en)Service Worker 201 (en)
Service Worker 201 (en)Chang W. Doh
 
Workshop Intro: FrontEnd General Overview
Workshop Intro: FrontEnd General OverviewWorkshop Intro: FrontEnd General Overview
Workshop Intro: FrontEnd General OverviewVisual Engineering
 
Packing it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to nowPacking it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to nowDerek Willian Stavis
 
JavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & BrowserifyJavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & BrowserifyJohan Nilsson
 
Isomorphic web application
Isomorphic web applicationIsomorphic web application
Isomorphic web applicationOliver N
 
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08Tim Stephenson
 
NodeWay in my project & sails.js
NodeWay in my project & sails.jsNodeWay in my project & sails.js
NodeWay in my project & sails.jsDmytro Ovcharenko
 
Grunt.js and Yeoman, Continous Integration
Grunt.js and Yeoman, Continous IntegrationGrunt.js and Yeoman, Continous Integration
Grunt.js and Yeoman, Continous IntegrationDavid Amend
 
Avoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.jsAvoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.jsAlex Speller
 
Webpack Tutorial, Uppsala JS
Webpack Tutorial, Uppsala JSWebpack Tutorial, Uppsala JS
Webpack Tutorial, Uppsala JSEmil Öberg
 

What's hot (20)

Getting Started with HTML 5 Web workers
Getting Started with HTML 5 Web workersGetting Started with HTML 5 Web workers
Getting Started with HTML 5 Web workers
 
Node, express & sails
Node, express & sailsNode, express & sails
Node, express & sails
 
Web workers
Web workersWeb workers
Web workers
 
Service Worker 201 (en)
Service Worker 201 (en)Service Worker 201 (en)
Service Worker 201 (en)
 
Browserify
BrowserifyBrowserify
Browserify
 
JavaScript Web Workers
JavaScript Web WorkersJavaScript Web Workers
JavaScript Web Workers
 
Workshop Intro: FrontEnd General Overview
Workshop Intro: FrontEnd General OverviewWorkshop Intro: FrontEnd General Overview
Workshop Intro: FrontEnd General Overview
 
Sails.js Intro
Sails.js IntroSails.js Intro
Sails.js Intro
 
Packing it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to nowPacking it all: JavaScript module bundling from 2000 to now
Packing it all: JavaScript module bundling from 2000 to now
 
JavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & BrowserifyJavaScript Dependencies, Modules & Browserify
JavaScript Dependencies, Modules & Browserify
 
Isomorphic web application
Isomorphic web applicationIsomorphic web application
Isomorphic web application
 
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
WordPress as a Platform - talk to Bristol Open Source Meetup, 2014-12-08
 
NodeWay in my project & sails.js
NodeWay in my project & sails.jsNodeWay in my project & sails.js
NodeWay in my project & sails.js
 
An Intro into webpack
An Intro into webpackAn Intro into webpack
An Intro into webpack
 
Webpack
WebpackWebpack
Webpack
 
Webpack DevTalk
Webpack DevTalkWebpack DevTalk
Webpack DevTalk
 
Web Workers
Web WorkersWeb Workers
Web Workers
 
Grunt.js and Yeoman, Continous Integration
Grunt.js and Yeoman, Continous IntegrationGrunt.js and Yeoman, Continous Integration
Grunt.js and Yeoman, Continous Integration
 
Avoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.jsAvoiding Common Pitfalls in Ember.js
Avoiding Common Pitfalls in Ember.js
 
Webpack Tutorial, Uppsala JS
Webpack Tutorial, Uppsala JSWebpack Tutorial, Uppsala JS
Webpack Tutorial, Uppsala JS
 

Similar to Building Isomorphic Apps (JSConf.Asia 2014)

Web APIs & Apps - Mozilla
Web APIs & Apps - MozillaWeb APIs & Apps - Mozilla
Web APIs & Apps - MozillaRobert Nyman
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
从小书签到浏览器扩展的应用
从小书签到浏览器扩展的应用从小书签到浏览器扩展的应用
从小书签到浏览器扩展的应用Alipay
 
Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)Ran Mizrahi
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Ran Mizrahi
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...RIA RUI Society
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch
 
A Story about AngularJS modularization development
A Story about AngularJS modularization developmentA Story about AngularJS modularization development
A Story about AngularJS modularization developmentJohannes Weber
 
Running Vue Storefront in production (PWA Magento webshop)
Running Vue Storefront in production (PWA Magento webshop)Running Vue Storefront in production (PWA Magento webshop)
Running Vue Storefront in production (PWA Magento webshop)Vendic Magento, PWA & Marketing
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSAntonio Peric-Mazar
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineRicardo Silva
 
Mozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSMozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSRobert Nyman
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsSimo Ahava
 
Refactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.jsRefactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.jsStacy London
 
Refactor Large applications with Backbone
Refactor Large applications with BackboneRefactor Large applications with Backbone
Refactor Large applications with BackboneColdFusionConference
 
Refactor Large apps with Backbone
Refactor Large apps with BackboneRefactor Large apps with Backbone
Refactor Large apps with BackbonedevObjective
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CNjojule
 

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

ParisJS #10 : RequireJS
ParisJS #10 : RequireJSParisJS #10 : RequireJS
ParisJS #10 : RequireJS
 
Web APIs & Apps - Mozilla
Web APIs & Apps - MozillaWeb APIs & Apps - Mozilla
Web APIs & Apps - Mozilla
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
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 (27/8/2014)Intro to node.js - Ran Mizrahi (27/8/2014)
Intro to node.js - Ran Mizrahi (27/8/2014)
 
Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)Intro to node.js - Ran Mizrahi (28/8/14)
Intro to node.js - Ran Mizrahi (28/8/14)
 
Html5 and beyond the next generation of mobile web applications - Touch Tou...
Html5 and beyond   the next generation of mobile web applications - Touch Tou...Html5 and beyond   the next generation of mobile web applications - Touch Tou...
Html5 and beyond the next generation of mobile web applications - Touch Tou...
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
A Story about AngularJS modularization development
A Story about AngularJS modularization developmentA Story about AngularJS modularization development
A Story about AngularJS modularization development
 
Running Vue Storefront in production (PWA Magento webshop)
Running Vue Storefront in production (PWA Magento webshop)Running Vue Storefront in production (PWA Magento webshop)
Running Vue Storefront in production (PWA Magento webshop)
 
Building Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJSBuilding Single Page Application (SPA) with Symfony2 and AngularJS
Building Single Page Application (SPA) with Symfony2 and AngularJS
 
Event-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 EngineEvent-driven IO server-side JavaScript environment based on V8 Engine
Event-driven IO server-side JavaScript environment based on V8 Engine
 
Mozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJSMozilla Web Apps - Super-VanJS
Mozilla Web Apps - Super-VanJS
 
Sanjeev ghai 12
Sanjeev ghai 12Sanjeev ghai 12
Sanjeev ghai 12
 
Symfony2 and AngularJS
Symfony2 and AngularJSSymfony2 and AngularJS
Symfony2 and AngularJS
 
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analystsMeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
MeasureCamp IX (London) - 10 JavaScript Concepts for web analysts
 
Refactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.jsRefactoring Large Web Applications with Backbone.js
Refactoring Large Web Applications with Backbone.js
 
Refactor Large applications with Backbone
Refactor Large applications with BackboneRefactor Large applications with Backbone
Refactor Large applications with Backbone
 
Refactor Large apps with Backbone
Refactor Large apps with BackboneRefactor Large apps with Backbone
Refactor Large apps with Backbone
 
Vaadin 7 CN
Vaadin 7 CNVaadin 7 CN
Vaadin 7 CN
 

Recently uploaded

New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 

Recently uploaded (20)

New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 

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…
  • 44.
  • 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