Skip to content
Library provides low-level API to control NW.js app auto-updates
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
Lib Remove backupDir before copy to it Mar 11, 2019
example updating dependencies for npm audit Nov 30, 2018
.gitignore going 1.1.0-beta Apr 20, 2017 updating version Oct 18, 2017
LICENSE Create LICENSE Nov 26, 2018 release 1.1.7 Nov 29, 2018
book-cover.png adding book promo Sep 8, 2017
index.js - Fix log Oct 1, 2017
nw-autoupdater.gif animated gif to show Strategy ScriptSwap Apr 24, 2017
package-lock.json 1.1.10 Mar 12, 2019
package.json 1.1.10 Mar 12, 2019

NW-Autoupdater v1.1


FOSSA Status Join the chat at

Library provides low-level API to control NW.js app auto-updates. This project can be seen as a reincarnation of node-webkit-updater, which is not maintained anymore.


  • Node >= 7 compliant
  • clean async/await syntax
  • supports both Zip/Tar.Gz archives
  • fires download/install progress events

Strategy ScriptSwap

Autoupdater in action

📹 Screencast: Running nw-autoupdater examples in the terminal on Ubuntu

What do we do to autoupdate (see demo A or demo B)

  • readRemoteManifest reads manifest from the remote release server
  • checkNewVersion( rManifest ) checks if the version in the remote manifest greater than one of the local manifest
  • If the remote manifest doesn't have newer version, skips the update flow
    • We subscribe for download events
    • We subscribe for install events
  • download( rManifest ) downloads the latest available release matching the host platform (according to the packages map of the remote manifest)
  • unpack( updateFile ) unpacks the release archive (zip or tar.gz) in a temporary directory
  • Strategy AppSwap
    • restartToSwap( extraArgs ) closes the app and launches the downloaded release
    • isSwapRequest() - checks if we need to go the swap flow (while running in tmp and therefore having the initial app directory unlocked for writing)
    • swap() - backs up actual version and replaces it with the new one
    • restart( extraArgs ) - restarts the updated app from its original location
  • Strategy ScriptSwap
    • restartToSwap() closes the app and launches the swap script, which launches the application when it's done


  • Run release server (see example)
  • Add to your client manifest (package.json) field manifestUrl pointing at release server
  • Package your app by using nwjs-builder (see example)
  • Update the contents of packages field in release server manifest (e.g. by running node update.js)
  • Update version field in release server manifest
  • Launch your app and observe it's auto-updating




new AutoUpdate( manifest, options );


  • manifest - e.g. require( "./package.json" )
  • options.strategy - (OPTIONAL) can be ScriptSwap or AppSwap. By default AppSwap
  • options.executable - (OPTIONAL) executable if it doesn't match project name
  • options.backupDir - (OPTIONAL) directory to backup. By default it's <project_name>.bak next to app directory
  • options.execDir - (OPTIONAL) app directory. By default it's extracted from process.execPath (nwjs-builder bundles the app into self-extractable and process.cwd() is not a reliable source). Yet on a Mac process.execPath contains the full path to the executable within MacOS bundle. So you rather use this option to set the app path directly.
  • options.updateDir - (OPTIONAL) temporary directory where the downloaded package gets extracted. By default /tmp/nw-autoupdater
  • options.logPath - (OPTIONAL) the full path to the log file. By default nw.App.dataPath + "/nw-autoupdater.log": Windows: %LOCALAPPDATA%/<project_name>; Linux: ~/.config/<project_name>; OSX: ~/Library/Application Support/<project_name>
  • options.verbose - (OPTIONAL) when true swap script reports verbose in the log file. By default false
  • options.swapScript - (OPTIONAL) you custom swap script content (NOTE: available only for ScriptSwap strategy)
  • options.accumulativeBackup - (OPTIONAL) when true for every backup creates a new folder. By default false

Writing custom swap script

You can define with options.swapScript you own custom swap script:

 const updater = new AutoUpdater( require( "./package.json" ), {
          strategy: "ScriptSwap",
          swapScript: `

By default on Linux/MacIO the following script is used:

rsync -a\${VERBOSE} --delete \${APP_PATH}/. \${BAK_PATH}/
rsync -a\${VERBOSE} --delete \${UPDATE_PATH}/. \${APP_PATH}/

where the variables are populated from ARGV:

  • VERBOSE - "v" or ""
  • APP_PATH - application home directory
  • BAK_PATH - backup directory
  • UPDATE_PATH - update directory

For example, if you have for package not the entire NW.js application, but just HTML5 project, you set up the following script:

rsync -a\${VERBOSE} --delete \${APP_PATH}/. \${BAK_PATH}/
rsync -a\${VERBOSE} \${UPDATE_PATH}/. \${APP_PATH}/package

So it backups the project, but copies extracted packaged into package subfolder in application home directory


Reads package.json of the release server

const rManifest = await updater.readRemoteManifest();

Returns: Promise<manifest: Object>


Check if the release server has newer app version

const needsUpdate = await updater.checkNewVersion( rManifest );


  • rManifest - manifest of the release server

Returns: Promise<needsUpdate: boolean>


Download last available update to the temp directory

const updateFile = await rManifest, { debounceTime: 100 });


  • rManifest - manifest of the release server
  • options.debounceTime - (OPTIONAL) debounce time in milliseconds

Returns: Promise<filepath: string>


Unpack downloaded update

const extractDir = await updater.unpack( updateFile, { debounceTime: 100 } );


  • updateFile - path to downloaded update
  • options.debounceTime - (OPTIONAL) debounce time in milliseconds

Returns: Promise<directory: string>


Close this version of app and start the downloaded one with --swap param

await updater.restartToSwap();


  • extraArgs - (OPTIONAL) Extra arguments to be passed to the newly started app

Returns: Promise



Subscribe on download progress event

updater.on( "download", ( downloadSize, totalSize ) => {
  console.log( "download progress", Math.floor( downloadSize / totalSize * 100 ), "%" );


Subscribe on install progress event

updater.on( "install", ( installFiles, totalFiles ) => {
  console.log( "install progress", Math.floor( installFiles / totalFiles * 100 ), "%" );

Extra Methods required for Strategy AppSwap


Checks if the app launched for swap

const needsSwap = updater.isSwapRequest();

Returns: boolean


Backs up current version of the app and replaces it with the downloaded version

await updater.swap();

Returns: Promise


Restarts the updated app

await updater.restart();


  • extraArgs - (OPTIONAL) Extra arguments to be passed to the newly started app

Returns: Promise


nw-autoupdater welcomes maintainers. There is plenty of work to do. No big commitment required, if all you do is review a single Pull Request, you are a maintainer.

How to check changes

# Clone the git repo
git clone

# Navigate to the newly created directory
cd nw-autoupdater

# Switch the branch if needed
# Make changes in the code
# Bundle the package
npm pack

# You'will get a new file like `nw-autoupdater-1.1.7.tgz`
# Switch a client example
cd example/client-strategy-script/

# Install the updated package
npm i ../../nw-autoupdater-1.1.7.tgz

# Package demo app
npm run package

# Extract demo app package in a temp directory
unzip ../server/releases/ -d /tmp/Sandbox/

# Switch to release server example
cd ../server/
# Make sure dependencies up to date
npm i
# Update releases manifest
npm run update
# Start the server
npm start

# Now start the demo app from your temp /tmp/Sandbox/

# It says:
#  Application ver. 1.0.0
#  App is up to date...

# Switch back to demo app and update its version
cd ../client-strategy-script/
npm version patch
npm run package

# Back to the server to update manifest
cd ../server/
npm run update
npm start

# When starting the built app it updates

My book:

Cross-platform Desktop Application Development: Electron, Node, NW.js, and React

I split the book in four tutorials, starting with basics and advancing progressively though more and more complex aspects. So the first part guides on creating a file-explorer built with pure JavaScript and NW.js/Node.js. The second part is about creating a chat with Electron, React and PhotonKit. The third part is about screen capturer made with NW.js, React/Redux and Material UI. The last part guides on creating RSS aggregator with Electron, React, Redux and TypeScript.

You can’t perform that action at this time.