Slide 1

Slide 1 text

Native Javascript applications with NW.JS Jacopo Daeli Software Engineer Paris, Jun 5th 2015 Best of Web

Slide 2

Slide 2 text

Clever.js What am I working on at this moment? It’s a good looking and clever open source framework to help developers build web applications quickly. It's designed to give them a quick and organised way to start developing node.js based web apps with useful modules like Mongoose and Passport pre-bundled and configured.

Slide 3

Slide 3 text

What are we going to talk about today? - What it is NW.JS a.k.a NodeWebkit - Implementation details - Uses cases - Debugging - Real example: Stream Booth

Slide 4

Slide 4 text

What is it NW.JS? (1) NW.JS is a web app runtime based on Chromium and Node.js. It lets you to call Node.js modules directly from DOM and enables a new way of writing native applications with all Web technologies. It's created and developed in Intel Open Source Technology Center.

Slide 5

Slide 5 text

What is it NW.JS? (2) Node-WebKit project changed name in January 2015 to NW.JS. Since it is migrated to io.js for updated V8 engine, which helps a lot for integration with latest Chromium versions, it has been renamed because both parts of the name are irrelevant now.

Slide 6

Slide 6 text

What is it NW.JS? (3) It integrates Node.js functions into Chromium App const fs = require('fs'); fs.readdir(…, function(…) { for (let i in files) { document.write(files[i]); } }); Applications bin cores dev etc home Library net private sbin …

Slide 7

Slide 7 text

What is it NW.JS? (4) Node.js functions live into the main (renderer) thread. require process global … console documents frames … window object renderer thread

Slide 8

Slide 8 text

What is it NW.JS? (5) - It runs on OS X, Windows and Linux (of course) - It is easy for packaging and distribution: O@9L AK FG<=&O=:CAL Ak `j \Xjp ]fi gXZbXg`eg Xe[ [`jki`Ylk`fe @LED(BK >`c\j J\jfliZ\j 9gg app Standalone Executable

Slide 9

Slide 9 text

What is it NW.JS? (6) It’s also available on npm. You can run apps like this: # globally $ npm install -g nw $ nw ./my_nwjs_app # locally $ npm install nw $ node_modules/.bin/nw ./my_nwjs_app

Slide 10

Slide 10 text

What is it NW.JS? (6) It supports Node.js native and third party modules. Async

Slide 11

Slide 11 text

What is it NW.JS? (7) - It is based on Chromium and io.js - It is created and developed at Intel - It is open-sourced at GitHub on Dec’ 7 2011 - Get it at: https://github.com/nwjs/nw.js/ - Prebuilt binaries are available to easy development

Slide 12

Slide 12 text

Implementation details - Chromium uses MessagePump* family to support its internal message loop - Node.js uses libuv for message loop - NW.JS merges Node.js and Chromium’s message loop: it implements MessagePumpForUv to use libuv for Chromium’s message loop

Slide 13

Slide 13 text

Implementation details: structure of an app IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj dfy, E 9 \dfy, \dfy, IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' fy, dcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw k`Xc xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' ;C KL9JL ajfe y2 xen&[\dfy, ny 2 r y2 0)), ky2 .)), Xiy 2 ]Xcj\ 2 x`e[\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw y jg\Z`]`\j `e`k`Xc \[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' KL9JL n&[\dfy, ), )), Xcj\ [\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw ]`\j `e`k`Xc lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jkXiklg n`e[f xn`[k_y X [\]`e\ n`e[fn xkffcYXiy j_fn k_\ n`e[ xgfj`k`fey n`e[fnwj `e` x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e jkXiklg xn`[ [\]`e\ xkff j_fn k_ xgf n`e[fn Describes package information App HTML/CSS/JS files Node.js modules

Slide 14

Slide 14 text

Implementation details: manifest file (package.json) gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' [\dfy, j\ `e vu('Z EXZ GK 9ggc`ZXk xn`e jkXiklg IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' A;C KL9JL \'ajfe \y2 xen&[\dfy, fny 2 r k_y2 0)), g_ky2 .)), YXiy 2 ]Xcj\ y 2 x`e[\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw y jg\Z`]`\j `e`k`Xc n\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' ;C KL9JL \'ajfe y2 xen&[\dfy, fny 2 r _y2 0)), _ky2 .)), YXiy 2 ]Xcj\ y 2 x`e[\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw y jg\Z`]`\j `e`k`Xc n\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' ;C KL9JL \'ajfe y2 xen&[\dfy, fny 2 r _y2 0)), _ky2 .)), YXiy 2 ]Xcj\ y 2 x`e[\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw y jg\Z`]`\j `e`k`Xc n\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xgg Zfe]`gliXk`fe [`i\Zkfipwj Ge D`elo Xgg [XkX n`cc Y\ `e vu('Zfe]`g(en&[\dfw EXZ GK P `k `j vu(D`YiXip 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_ jkXiklg n`e[fnwj ]\Xkli\ xn`[k_y Xe[ x_\`g_k [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_ j_fn k_\ n`e[fnwj kffcY xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xeXd\y jg\Z`]` Zfe]`gliXk`fe [`i\Z Ge D`elo Xgg [XkX `e vu('Zfe]`g(en&[ EXZ GK P `k `j vu( 9ggc`ZXk`fe Klggfi IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy xeXd\y Zfe]`gliXk`f Ge D`elo Xg `e vu('Zfe]` EXZ GK P `k 9ggc`ZXk`fe xn`e[fn jkXiklg n`e[ xn`[k_y IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xeXd\y Zfe]`gliXk` Ge D`elo Xg `e vu('Zfe EXZ GK P ` 9ggc`ZXk`fe xn`e[f jkXiklg n`e IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xeXd\ Zfe]`gliXk Ge D`elo X `e vu('Zfe EXZ GK P 9ggc`ZXk`f xn`e[f jkXiklg n`e IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL gXZbXg\'ajfe r xeXd\y2 xen&[\dfy, xn`e[fny 2 r xn`[k_y2 0)), x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj IMA;C KL9JL KkilZkli\ f] Xe Xgg 9gg s&& gXZbXg\'ajfe s&& `e[\o'_kdc s&& aj( s W&& z s&& Zjj( s W&& z s&& i\jfliZ\j( s W&& z W&& ef[\Vdf[lc\j( W&& z <\jZi`Y\j gXZbXg\ `e]fidXk`fe 9gg @LED(;KK(BK ]`c\j Ff[\'aj df[l\cj xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' dfy, _kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw `e`k`Xc xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' MA;C KL9JL Xg\'ajfe d\y2 xen&[\dfy, e[fny 2 r `[k_y2 0)), \`g_ky2 .)), ffcYXiy 2 ]Xcj\ `ey 2 x`e[\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw X`ey jg\Z`]`\j `e`k`Xc _fn\[ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' ;C KL9JL jfe xen&[\dfy, y 2 r 2 0)), y2 .)), y 2 ]Xcj\ x`e[\o'_kdcy xeXd\y jg\Z`]`\j Xggwj Zfe]`gliXk`fe [`i\Zkfipwj eXd\' Ge D`elo Xgg [XkX n`cc Y\ jkfi\[ `e vu('Zfe]`g(en&[\dfw, fe EXZ GK P `k `j vu(D`YiXip( 9ggc`ZXk`fe Klggfikw jg\Z`]`\j `e`k`Xc [ kf lj\i xn`e[fny jg\Z`]`\j k_\ jkXiklg n`e[fnwj ]\Xkli\j' xn`[k_y Xe[ x_\`g_ky [\]`e\ n`e[fnwj j`q\' xkffcYXiy [\]`e\j n_\k_\i kf j_fn k_\ n`e[fnwj kffcYXi' xgfj`k`fey [\]`e\j n`e[fnwj `e`k`Xc gfj`k`fe' x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i xn`e[f jkXiklg n`e xn`[k_y [\]`e\ n`e xkffcYX j_fn k_\ n xgfj`k`f n`e[fnwj x_\`g_ky2 .)), xkffcYXiy 2 ]Xcj\ t, xdX`ey 2 x`e[\o'_kdcy t xdX`ey jg\Z`]`\j `e`k`Xc gXg\ j_fn\[ kf lj\i x jkXi x [\]` x j_fn x n`e[ Specifies app’s name Specifies initial app’s page Specifies startup window’s feature

Slide 15

Slide 15 text

Use cases: distribution platform for games - It supports most HTML 5 features - It’s GPU accelerated - It supports WebGL - Video and audio support

Slide 16

Slide 16 text

Use cases: File explorer and file editor - You can choose between Node’s fs module or HTML5 API - You can invoke file select dialogs in JS - Direct dragging files into the window is supported

Slide 17

Slide 17 text

Use cases: Media applications - It supports getUserMedia - Audio recording and camera capturing are enabled - and tag are supported: it can play ogg and web formats

Slide 18

Slide 18 text

Use cases: PopCorn Time (R.I.P)

Slide 19

Slide 19 text

Use cases: PopCorn Time (R.I.P) { "name": "Popcorn-Time", "homepage": "https://popcorntime.io", "repository": { "type": "git", "url": "https://git.popcorntime.io/popcorntime/desktop.git" }, "license": "GPL-3.0", "main": "app://host/src/app/index.html", "version": "0.3.7-2", "node-remote": "client.vpn.ht", "releaseName": "The car wont start", "scripts": { "postinstall": "node_modules/.bin/bower install && grunt setup", "postupdate": "node_modules/.bin/bower update && grunt setup", "test": "grunt --verbose" }, "window": { "title": "Popcorn Time", "icon": "src/app/images/icon.png", "toolbar": false, "frame": false, "min_width": 960, "min_height": 520, "resizable": true, "show": false, "position": "center" }, "dependencies": { "async": "0.9.0", "i18n": "0.5.0", "q": "2.0.2", "read-torrent": "1.0.0", "readdirp": "*", "request": "^2.36.0" … }, … } Manifest file (package.json):

Slide 20

Slide 20 text

Use cases: PopCorn Time (R.I.P) if (gui.App.fullArgv.indexOf('--reset') !== -1) { var data_path = require('nw.gui').App.dataPath; localStorage.clear(); fs.unlinkSync(path.join(data_path, 'data/watched.db'), function (err) { if (err) { throw err; } }); fs.unlinkSync(path.join(data_path, 'data/movies.db'), function (err) { if (err) { throw err; } }); fs.unlinkSync(path.join(data_path, 'data/bookmarks.db'), function (err) { if (err) { throw err; } }); fs.unlinkSync(path.join(data_path, 'data/shows.db'), function (err) { if (err) { throw err; } }); fs.unlinkSync(path.join(data_path, 'data/settings.db'), function (err) { if (err) { throw err; } }); } // Global App skeleton for backbone var App = new Backbone.Marionette.Application(); _.extend(App, { Controller: {}, View: {}, Model: {}, Page: {}, Scrapers: {}, Providers: {}, Localization: {} }); Extract of app.js file

Slide 21

Slide 21 text

Use cases: PopCorn Time (R.I.P) function Cache(table) { var self = this; this.table = table; var db = indexedDB.open(App.Config.cachev2.name, App.Config.cachev2.version); db.onsuccess = function () { self.db = this.result; }; db.onupgradeneeded = function () { var self = this; App.Config.cachev2.tables.forEach(function (tableName) { if (_.contains(self.result.objectStoreNames, tableName)) { return; } self.result.createObjectStore(tableName, { keyPath: '_id' }); }); }; this._openPromise = WrapRequest(db).promise; } Cache.prototype.set = function (key, value, options) { options = options || {}; var data = _.extend(value, { _id: key, _ttl: options.ttl || 14400000, _lastModified: +new Date() }); return WrapRequest(this.db.transaction(this.table, 'readwrite').objectStore(this.table).put(data)).promise; }; Extract of Cache class

Slide 22

Slide 22 text

Debugging (with devtools) // Add this to your manifest file, then you can // open devtools from the devtools button in the toolbar. { "window": { "toolbar": true } } // or you may open devtools programmatically require('nw.gui').Window.get().showDevTools() // Alternatively you can even use the --remote-debugging-port=port // command parameter to specify which port the devtools should listen to // For example, by running nw --remote-debugging-port=9222, you can // open http://localhost:9222/ to visit the debugger remotely. Open dev tools

Slide 23

Slide 23 text

Real Example: Stream Booth - Fork it on GitHub: https://github.com/JacopoDaeli/bestof-web-paris-2015 - It streams from the webcam to other devices in the same LAN. - It uses express for serving the webapp files to the audience’s devices - NW.JS app and the webapp exchange messages using socket.io - It uses getUserMedia API for reading from the user webcam - It uses an hidden canvas for getting a video frame each 33ms, converting it into a base64 URL and sending it to the audience. NOW THERE IS A LIVE DEMONSTRATION :-)