NW.js
repository·main·Indexed 12 days ago
https://github.com/nwjs/nw.jsAn application runtime that enables developers to build native desktop applications using web technologies (HTML, CSS, and JavaScript) by combining the Chromium engine with Node.js.
What's inside NW.js
- NW.js (formerly node-webkit) is a runtime that allows you to call all Node.js modules directly from the DOM. This enables developers to build desktop applications using standard Web technologies (HTML, CSS, and JavaScript) while having full access to Node.js capabilities for file system access, networking, and other system-level operations.
Handle the window 'close' event for clean shutdown
mainThe
closeevent is emitted whenWindow.close()is called. If you listen to this event,Window.close()will not actually close the window immediately. This allows you to perform shutdown tasks.Important: To force the window to close after your tasks are done, you must call
this.close(true). Callingthis.close()withouttrueinside thecloseevent listener will cause an infinite loop.Best Practice: To provide a smooth user experience, call
this.hide()immediately in thecloseevent so the window disappears instantly, then perform your cleanup and callthis.close(true).Mac Note: On Mac, the callback receives an argument indicating if the window is being closed via
<kbd>⌘</kbd>+<kbd>Q</kbd>. It is set to the string'quit'if true, otherwiseundefined.// Listen to main window's close event nw.Window.get().on('close', function () { // Hide the window to give user the feeling of closing immediately this.hide(); // Perform shutdown work... // Finally, force close this.close(true); });Use Node.js APIs and modules in the DOM
mainNW.js allows you to call Node.js code and modules directly from your web pages. You can use
require()to load built-in Node.js modules (likeos,fs, etc.) or modules installed vianpm.<script> // Use the Node.js 'os' module directly in the browser context var os = require('os'); document.write('You are running on ', os.platform()); </script>How content verification works
mainContent verification (also known as "app signing") is a security feature that prevents the loading of unsigned files when using an official NW.js binary.
When an application is signed, a
verified_contents.jsonfile is generated containing signatures for the application files using a private key. The corresponding public key is embedded within the NW.js binary.To run a signed application with strict enforcement, use the
--verify-content=enforce_strictflag. If any file (such asindex.html) is modified after signing, NW.js will detect the corruption and terminate immediately.Security Note: This feature prevents loading unsigned files with your official binary, but it does not prevent an attacker from loading your modified app using a different, non-official NW.js binary. For higher security, consider using C++ modules, NaCl, or compiling JavaScript to binary with
nwjc.nw --verify-content=enforce_strict .Understand JavaScript Contexts in NW.js
mainIn NW.js, scripts running in different windows or frames live in different JavaScript contexts. Each context has its own global object and its own set of global constructors (like
ArrayorObject). This isolation prevents prototype pollution from one window affecting another and provides security boundaries between windows.NW.js operates using two primary types of contexts:
- Browser Context: Used by scripts loaded via traditional web methods (e.g.,
<script>tags, jQuery, RequireJS). It has access to DOM APIs and Web APIs. - Node Context: Used by scripts loaded via Node.js
require()or thenode-mainmanifest field. It has access to Node.js globals like__dirnameandprocess, but cannot access Web APIs (likedocumentoralert()) directly.
By default, NW.js runs in Separate Context Mode, where these two types of contexts are distinct.
- Browser Context: Used by scripts loaded via traditional web methods (e.g.,
Enable Proprietary Codecs in NW.js
mainPre-built NW.js binaries do not include certain proprietary codecs (like H.264) due to licensing and patent constraints. To use these codecs, you must either use community-provided binaries or build your own FFmpeg DLL/NW.js build.
Warning on Licensing: Using H.264 requires compliance with patent royalties and source code licenses. Consult a lawyer regarding licensing constraints. Simply using these workarounds does not grant you the legal right to redistribute patented media formats.
Resolve relative paths in require() based on JavaScript context
mainThe behavior of relative paths in Node's
require()method changes depending on the JavaScript context of the file calling it:- Node context: If the parent file is running in the Node context, the relative path is resolved relative to the parent file's directory.
- Browser context: If the parent file is running in the browser context, the relative path is resolved relative to the application's root directory (the directory containing your manifest file).
Communication between JavaScript and Native Client modules
mainThe Native Client programming model supports bidirectional, asynchronous communication between JavaScript and the Native Client module.
- Asynchronous Nature: Both sides can initiate and respond to messages without waiting for a response (similar to web workers or client/server communication).
- API: The messaging system is part of the Pepper API.
- JavaScript side: Use the
.postMessage()method on the module instance (retrieved via an<embed>tag) to send data to the C++ module. - C++ side: Implement the
HandleMessage()member function to receive messages and usePostMessage()to send responses back to JavaScript.
How NW.js works: Core Concepts
mainNW.js is an application runtime that combines Chromium and Node.js.
Key architectural features include:
- Unified Context: Node.js and WebKit run in the same thread. This means function calls between the DOM and Node.js are straightforward, and objects exist in the same heap, allowing them to reference each other directly.
- Web Technology Stack: You can build native desktop applications using modern HTML5, CSS3, JavaScript, and WebGL.
- Node.js Integration: You have complete support for Node.js APIs and all third-party modules available via
npmdirectly from your web pages.
Use NaCl and PNaCl in NW.js
mainNW.js supports NaCl (Native Client) and PNaCl (Portable Native Client), allowing you to embed native C++ modules within your application.
Requirement: This feature is only available in the SDK and NaCl flavor of NW.js. If you are using a standard build, you will not be able to use these features.
Use tray.menu to handle clicks and platform differences
mainThe
tray.menuproperty defines the menu that appears when interacting with the tray. Because interaction patterns vary by OS, setting themenuproperty is the standard way to ensure cross-platform compatibility:- macOS: The menu is shown when the tray is clicked.
- Windows/Linux: The menu is shown on a right-click. A left-click triggers the
clickevent instead of showing the menu.
Understand NW.js Architecture and Context Changes
mainNW.js now runs internally as a Chrome App. Key architectural shifts include:
- Protocols: The default protocol has changed from
file://tochrome-extension://. Theapp://protocol from older versions is replaced bychrome-extension://(where the host is the generated ID). - API Namespace: All NW-specific APIs (including
require()) have moved fromnw.guito thenwobject. While a compatibility wrapper fornw.guiis provided, it is slated for deprecation. - Node.js Context: The Node.js context is now part of the DOM context of the background page. This means you have access to all DOM features and
chrome.*platform APIs directly within the Node context. - Mixed Context Mode: If running with the
--mixed-contextflag,nw.*acts as a mirror ofwindow.*. Warning: In this mode, you cannot share variables among frames or windows by assigning them to the Node context. Avoid this mode if your app relies on variable sharing via the Node context. - Application Entry: While you can specify an HTML file as the
mainfield inpackage.json, NW.js internally launches the first window via JS from the background page.
- Protocols: The default protocol has changed from