NW.js

repository·main·Indexed 12 days ago

https://github.com/nwjs/nw.js

An 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.

Tokens
40.9K
Snippets
142
Records
232
Agent score
98%

What's inside NW.js

  1. Introduction to NW.js

    main
    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.
  2. Handle the window 'close' event for clean shutdown

    main

    The close event is emitted when Window.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). Calling this.close() without true inside the close event listener will cause an infinite loop.

    Best Practice: To provide a smooth user experience, call this.hide() immediately in the close event so the window disappears instantly, then perform your cleanup and call this.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, otherwise undefined.

    // 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);
    });
  3. Use Node.js APIs and modules in the DOM

    main

    NW.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 (like os, fs, etc.) or modules installed via npm.

    <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>
  4. How content verification works

    main

    Content 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.json file 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_strict flag. If any file (such as index.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 .
  5. Understand JavaScript Contexts in NW.js

    main

    In 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 Array or Object). 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:

    1. 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.
    2. Node Context: Used by scripts loaded via Node.js require() or the node-main manifest field. It has access to Node.js globals like __dirname and process, but cannot access Web APIs (like document or alert()) directly.

    By default, NW.js runs in Separate Context Mode, where these two types of contexts are distinct.

  6. Enable Proprietary Codecs in NW.js

    main

    Pre-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.

  7. Resolve relative paths in require() based on JavaScript context

    main

    The 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).
  8. Communication between JavaScript and Native Client modules

    main

    The 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 use PostMessage() to send responses back to JavaScript.
  9. How NW.js works: Core Concepts

    main

    NW.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 npm directly from your web pages.
  10. Use tray.menu to handle clicks and platform differences

    main

    The tray.menu property defines the menu that appears when interacting with the tray. Because interaction patterns vary by OS, setting the menu property 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 click event instead of showing the menu.
  11. Understand NW.js Architecture and Context Changes

    main

    NW.js now runs internally as a Chrome App. Key architectural shifts include:

    • Protocols: The default protocol has changed from file:// to chrome-extension://. The app:// protocol from older versions is replaced by chrome-extension:// (where the host is the generated ID).
    • API Namespace: All NW-specific APIs (including require()) have moved from nw.gui to the nw object. While a compatibility wrapper for nw.gui is 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-context flag, nw.* acts as a mirror of window.*. 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 main field in package.json, NW.js internally launches the first window via JS from the background page.