This article is translated by Wendy of my article 开始 NODE-WEBKIT 前，你应该知道的. Wendy now lives in Toronto, Canada and is looking to join a startup in US or Canada as backend developer to build innovative products that make people’s lives easier and more efficient. Her skills include Node.js, PHP, Python and C++. If you’re interested, why not drop her an email?
Last weekend, Teahour invited Roger Wang, the creator of node-webkit to talk about the stories behind node-webkit and the use of HTML5 in desktop app development. Various web-based desktop app frameworks such as node-webkit, Chrome Apps, Titanium, TideSDK and Atom Shell have been developed over recent years and node-webkit remains one of the best.
- Desktop IDEs such as Light Table
- Games such as Brandon Must Die!
- Media apps such as Popcorn Time
- Tools such as Haroopod
- Enterprise apps such as metrics apps
- Terminals such as POS terminals
We could see that the apps are diverse and there’s no lack of elegant apps. The full of imagination can be attributed to hardware performance improvements, developments of Web, animations, graphics, audios, videos, 2D, 3D, WebGl, etc.
Essentially, node-webkit is only a web app runtime. When we talk about desktop apps, we think of GUI, responses to user actions and system-level interactions, so how did node-webkit manage to do that? In order to learn more about that, we need to first learn about Node and WebKit.
The browser security model prevents WebKit from issuing system calls, which is a must-have for desktop applications; since Node itself has system-level APIs but lacks rendering support, Roger had the idea in 2011 to create node-webkit, combining system-level operations and user interactions. After some trials with WebKitGTK and Node, he started using Chromium in 2012, basing the project entirely on Chromium from the initial Chromium Embedded Framework (CEF).
Following the fast development of Node and Chromium, node-webkit is at version 0.10 today. We’ll dive into the details of how node-webkit works.
Node is an event-driven framework with message processing based on libuv. The JS engine of WebKit is based on MessagePump of Chrome, which is also event-driven. Event-driven can be explained as when an event happens, for example, user input comes in, the corresponding code is executed to process the event. Node-webkit combines the event-processing of Node and WebKit into a single message loop.
We still have another challenge after combining event processing: we need to find a way for Node and WebKit to access the context of each other. There are two contexts in node-webkit: the Node context and the WebKit context. Accessing the context of each other means accessing the objects of each other, so during the initialization of node-webkit, the Node context will be injected into WebKit so that the WebKit context will have access to the Node context.
Node-webkit has made changes to the security model of WebKit as well. In node-webkit, there are two kinds of frames: Node frames and normal frames1. If you’re familiar with Web development, you probably know that issuing a cross-domain AJAX request will result in errors imposed by same-origin policy. The same restriction is imposed on normal frames of node-webkit as in a browser. However, there is no such restriction on Node frames: the same security token is shared in all Node frames, including the Node’s context and the WebKit’s Context, and cross-domain access are allowed and objects in the Node’s context are accessible too. Therefore, app developers must take precaution with untrusted user input to prevent destructive actions or put them into a normal frame.
It is worth noting that even though Chrome supports HTML5 pretty well, some features are implemented on the Browser layer (see the graph above) and the WebKit in node-webkit inherits up to the Contents layer (i.e. the WebContents layer on the above image) as node-webkit itself is the implementation of the Browser layer. Therefore, some HTML5 features such as Web Notification2 are not supported in node-webkit. Nevertheless, the Chromium team is moving these HTML5 features onto the Content layer, which is definitely good news for node-webkit.
If you look at the above graph carefully, you will find there is also UI rendering in the Browser layer. Node-webkit implements UI rendering in the same way: it has native UI component APIs such as Menu, System Tray, Clipboard etc. The implementation is inspired from the cross-platform UI of Chromium.
The current version of node-webkit is 0.10.0, based on Node v0.11.13 and Chromium v35.0.1916.113. Node-webkit bases its major updates on Chromium versions, hence the 10 in 0.10.0. The version change corresponding to Node or node-webkit itself is the third part of the version number, e.g. the last 0 in 0.10.0.
If you would like to learn more about node-webkit, you can listen to our Teahour Episode. If you are tempted to develop a cross-platform desktop app, then the official Wiki would definitely be a good place to start.
Thank you again for the translation, Wendy. If anyone is interested, check out her linkedin. Wish you all the best in the job hunting.