Open-source project
nwjs/nw.js avatar
nwjs/nw.js

NW.js: no GitHub releases, nightlies that are never signed, and one thread shared with Chromium

GitHub describes it as Call all Node.js modules directly from DOM/WebWorker and enable a new way of writing applications with all Web technologies.. The repository metadata lists JavaScript as its primary language. The metadata lists the MIT license. This article stays within the project description and details documented in the GitHub repository README.

41,169 stars3,851 forksJavaScriptMIT

At a glance

What is it?
NW.js is an MIT licensed desktop app runtime built on Chromium and Node.js, where page code and Node modules share a thread and a heap. The repository is a landing page and issue tracker rather than the whole source, and its download verification story differs between stable and nightly.
Who is it for?
NW.js fits a team that wants to write a desktop app in HTML and JavaScript, take npm modules without a bridge layer, and ship a single package across Linux, macOS and Windows. It does not fit an application whose UI must stay responsive during heavy synchronous work, since that is the direct cost of the shared thread, and it does not fit a compliance process that expects an MIT licence to describe the shipped binary.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 8 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 25, 2026, and from our analysis. They are not legal advice.

Editorial analysis

This repository is a landing page and an issue tracker, not the runtime

The README is unusually direct about the arrangement. The source code for NW.js and the daily development spans multiple repositories in the organisation, and this repository is for issue tracking, a landing page, and part of the source code. Read that as a build instruction in itself: a single clone is not the whole product, so you cannot produce a runtime from this tree alone. The files at the root confirm the shape. There is a BUILD.gn and an nw.gypi, which is a GN and GYP build configuration pair of the kind used inside the Chromium source tree, along with a DEPS file and a patch directory for modifications applied during the build. There is also src, test and tools. Anyone planning to build from source needs the other repositories in the organisation as well, and the README does not enumerate them, so that discovery work happens outside this page.

Node and WebKit share one thread and one heap, which is both the pitch and the trap

The performance claim in the feature list is the project's defining technical decision. Node and WebKit run in the same thread, so function calls are straightforward, and objects live in the same heap and can just reference each other. That is why you can write document.write(process.version) inside a script tag in an ordinary HTML file and have it work, with no context bridge and no preload script. It is also the source of the sharp edge. A single thread shared by the renderer and Node means a long synchronous Node operation, a large synchronous file read or a CPU-bound loop, blocks rendering in the same frame. The same sharing removes isolation, so page JavaScript and Node code in the same context can reach each other's objects without ceremony. The README presents the shared thread purely as an advantage and says nothing about blocking, so a team adopting it for a UI that must stay responsive has to design around a constraint the documentation does not flag.

There are no GitHub releases, so the README download list is the release index

The repository publishes no GitHub releases, which means the version history of a runtime that people install by hand lives in three other places: the CHANGELOG.md at the root, the download list in the README, and a mapping file at nwjs.io/versions.json that carries version information for previous releases. The README list currently leads with v0.117.0, dated September 25th, 2026, based on Node.js v26.7.0 and Chromium 154, and it links release notes on the project blog rather than in the repository. Each entry names the Node and Chromium versions it tracks, which is the single most useful piece of information for anyone pinning a build, and there is a nightly link for the current git tip. The consequence for release hygiene is that there is no release page to diff, no tag list to browse and no signed artefact attached to a release, so the README and the blog are the changelog.

Nightly downloads are checksummed but never signed

Binary verification has been documented since 0.32.0, and the scheme has two halves with different coverage. Both the stable and nightly download directories contain a SHASUMS256.txt listing checksums for each downloadable file as well as for the files inside the download package, and you fetch and check it like this:

console
$ curl -O https://dl.nwjs.io/vx.y.z/SHASUMS256.txt
$ grep nwjs-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c -

The stable releases, and here the README is explicit that nightlies are excluded, also carry a GPG detached signature of that manifest as SHASUMS256.txt.asc. So the two tiers are not equivalent. A stable download can be traced back to a maintainer key. A nightly download can only be shown to match a manifest that is itself unsigned, which proves the file is intact relative to the manifest and says nothing about who wrote the manifest. If you are pulling from the nightly tree, that is the trust level you are working with. Note also that the manifest lists checksums for files inside the package, while the documented grep command selects only the top-level archive.

The documented key import names one keyserver and offers no fallback

To check the signature rather than just the checksum, you import the NW.js maintainer release key and then verify the detached signature:

console
$ gpg --keyserver pool.sks-keyservers.net --recv-keys 78680FA9E21BB40A
$ curl -O https://dl.nwjs.io/vx.y.z/SHASUMS256.txt.asc
$ gpg --verify SHASUMS256.txt.asc SHASUMS256.txt

The README gives exactly one keyserver host and no alternative, and it publishes the key fingerprint inline as 1E8B EE8D 5B0C 4CBC D6D1 9E26 7868 0FA9 E21B B40A. That fingerprint is the important part of the procedure, because it lets you confirm the key you received is the one the project intends, and it is the only defence if the named host is unreachable, since you could then obtain the same key from a different source and compare. The consequence of the single-host instruction is practical rather than theoretical: on a network where that host is blocked, the documented path simply stops, and nothing here tells you what to do next. Automate the fetch of the fingerprint before you rely on this in a build pipeline.

The MIT licence covers the code in this repository, not the binary you ship

The licence section is two sentences and the distinction matters. The code for NW.js in this repository uses the MIT licence, and anyone wanting to redistribute the binary is pointed at the packaging and distribution page on the wiki. So the MIT badge on the repository describes the source, not the artefact. An application built with NW.js bundles a Chromium build and a Node.js runtime inside its own package, and both of those carry their own licence terms, which the MIT grant in this repository does not address or override. For most developers this is a packaging detail they never think about. For anyone who has to answer a legal or compliance question about a shipped desktop application, it is the whole question, and the answer is not in this README. Keep the distinction in mind before you treat a repository licence as clearance for a binary.

The macOS entry is arm64 only and still says Mac 10.10+

The download matrix for v0.117.0 is asymmetric in a way worth reading carefully. Linux has two links, 64bit and arm64. Windows has two, 32bit and 64bit. macOS has one, listed as Mac 10.10+ and pointing at an arm64 archive. The arm64 name means an Intel Mac has no build offered in that row, and the separate note directing Windows XP and early macOS users to a legacy build implies the modern list is not the place to look. The Mac 10.10+ label also sits directly beside a runtime based on Chromium 154 and Node.js v26.7.0, with no stated current minimum, so the label appears inherited from an earlier era of the download table rather than re-derived. If you are on an Intel Mac, or on a recent macOS and want to know the actual floor, neither question is answered by this page, and the versions.json mapping file and the release notes are where you have to go.

The documentation toolchain is pinned to a much older mkdocs than the runtime

The docs live in the repository alongside the code, with a docs directory, an mkdocs.yml, a .readthedocs.yaml and a custom_theme directory, which is a documentation site built in-tree and hosted on Read the Docs. The Python side is pinned hard in a three-line requirements.txt: Pygments 2.11.0, mkdocs 1.2.4 and pymdown-extensions 7.0.0. Those are old pins, and reproducing the site locally means creating an environment that matches them rather than a current one. It is a small file and an unremarkable decision, but it tells you something about the project's shape: the documentation tooling is maintained on its own schedule, separate from the runtime's Node and Chromium cadence. Support channels are dated in the same way. The mailing list is a Google group called nwjs-general, English only, and the README carries a note that old node-webkit links can be repaired by substituting nwjs-general for node-webkit, which is a small archive of a renaming that predates most current users.

Editorial conclusion

NW.js fits a team that wants to write a desktop app in HTML and JavaScript, take npm modules without a bridge layer, and ship a single package across Linux, macOS and Windows. It does not fit an application whose UI must stay responsive during heavy synchronous work, since that is the direct cost of the shared thread, and it does not fit a compliance process that expects an MIT licence to describe the shipped binary. Before you adopt it, read the release notes to decide whether you need the SDK build, verify stable downloads against the signed checksum manifest rather than the nightly tree, check the licence obligations for redistributing a Chromium bundle, and confirm a macOS build exists for your architecture.

Frequently asked questions

What is NW.js used for?

It is an app runtime based on Chromium and Node.js for writing native desktop applications in HTML and JavaScript, with Node.js modules callable directly from the DOM. It was created in the Intel Open Source Technology Center and is available on Linux, macOS and Windows.

How do I install NW.js?

Download a build, currently v0.117.0 from September 25th, 2026, based on Node.js v26.7.0 and Chromium 154, with separate archives for Linux, Windows and macOS, or take the nightly from the live-build directory. The README advises that you might want the SDK build, and says to read the release notes. Downloads can be checked against SHASUMS256.txt.

How do I use nw.js?

Create an index.html, create a package.json whose main field points at it, then run the runtime against the directory. The README gives /path/to/nw . on other platforms, notes you can drag the folder containing package.json onto nw.exe on Windows, and on macOS the binary sits inside the bundle at /path/to/nwjs.app/Contents/MacOS/nwjs.

Is NW.js better than Electron?

The README contains no comparison with Electron at all. It states NW.js's own characteristics instead: full Node.js API and third-party module support, Node and WebKit in the same thread and heap for direct object references, easy packaging, and availability on Linux, macOS and Windows. Whether those suit your project is a judgement the page leaves to you.

What is NWJS on my PC?

NW.js applications bundle the runtime, and the executable inside such a bundle is named nw on some platforms and nwjs on macOS, where the README notes the binary is hidden inside the .app file. So an nw or nwjs executable on a machine usually belongs to an installed application that packaged its own runtime rather than to a standalone NW.js installation.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nwjs-nw-js.svg)](https://hysenlabs.com/projects/nwjs-nw-js)