Skip to content

Widget Build And Installer ​

How nwm build currently packages your widget into installer and .ndpkg artifacts.

Table of Contents ​

Build Command ​

Run from your widget project folder:

bash
nwm build

What nwm build Does (Latest) ​

nwm build performs these steps:

  1. Validates required meta.json fields.
  2. Recreates dist/ from scratch.
  3. Creates temporary staging folders for installer and .ndpkg packaging.
  4. Copies Novadesk.exe into staging and renames it to <WidgetName>.exe.
  5. Copies requested addons into staging:
    • Installer staging gets all requested addons from meta.json.
    • .ndpkg staging excludes default built-in addons and keeps only non-default requested addons.
  6. Copies widget files (excluding dist/) into staging.
  7. Applies version/company/description/icon metadata to <WidgetName>.exe.
  8. Builds a self-extracting setup executable using installer_stub.exe.
  9. Creates a distributable ZIP package.
  10. Creates a .ndpkg package with metadata and an NDPKG footer.

Output Structure ​

Typical output:

  • dist/
    • YourWidgetName_v1.0.0.0.zip
    • setup.exe
    • YourWidgetName_v1.0.0.0.ndpkg

Notes:

  • ZIP name is generated as <SanitizedWidgetName>_v<SanitizedVersion>.zip.
  • .ndpkg name is generated as <SanitizedWidgetName>_v<SanitizedVersion>.ndpkg.
  • Setup EXE name depends on setup.setupName in meta.json.

Required meta.json Fields ​

nwm build fails if any of these are missing or empty:

Top-level required:

  • name
  • version
  • author
  • description
  • icon

Top-level optional:

  • preview (relative path to preview image shown in the package installer, e.g. "assets/preview.png")
  • excludeItems (array of file/folder path patterns to exclude from packaging)
  • addons (array of addon DLL names required by the widget)
  • setup (custom installer configuration object)
  • minimumNovadeskVersion (semver-style string, e.g. "0.9.11.0" — minimum Novadesk version required to run this widget; shown in the installer and checked at install time)

setup object:

  • setup.installDir
  • setup.startMenuFolder
  • setup.setupName
  • setup.setupIcon

excludeItems (Packaging Exclude List) ​

Use optional excludeItems in meta.json to skip files/folders from both installer and .ndpkg widget payload copies.

json
{
  "excludeItems": [
    "node_modules",
    ".git",
    "dist",
    "scripts/dev-only.js",
    "assets/raw"
  ]
}

Rules:

  • excludeItems must be an array of strings.
  • Entries are relative paths/pattern-like path prefixes from widget root.
  • dist is excluded by default during packaging.
  • Invalid excludeItems types cause nwm build validation failure.

setup Options ​

Supported installer options:

  • setup.createDesktopShortcut (boolean, default true)
  • setup.createStartupShortcut (boolean, default false)
  • setup.runOnStartup (boolean, default false)
  • setup.installDir (string, required)
  • setup.startMenuFolder (string, required)
  • setup.setupName (string, required; default is now {NAME}_Setup)
  • setup.setupIcon (string, required)
  • setup.enableUninstall (boolean, default true)
  • setup.launchAfterInstall (boolean, default false)

Example:

json
{
  "setup": {
    "createDesktopShortcut": true,
    "createStartupShortcut": false,
    "runOnStartup": false,
    "installDir": "%ProgramFiles%\\MyWidget",
    "startMenuFolder": "MyWidget",
    "setupName": "MyWidgetSetup",
    "setupIcon": "assets/icon.ico",
    "enableUninstall": true,
    "launchAfterInstall": false
  }
}

Addons (Detailed) ​

Addons are controlled by the optional addons array in your widget meta.json.

Example:

json
{
  "addons": ["InputBox", "NowPlaying", "CustomAddon.dll"]
}

Addon Name Rules in meta.json ​

  • Each addons entry must be a string.
  • You can provide either:
    • DLL file name (for example NowPlaying.dll)
    • or stem name without extension (for example NowPlaying)
  • Matching is case-insensitive.
  • Duplicate references to the same DLL are deduplicated during packaging.
  • If any requested addon cannot be found, nwm build fails.

Where nwm build Reads Addons From ​

nwm build resolves addon source path from the Novadesk installation mode:

  • Portable install: <NovadeskExeDirectory>/Addons
  • Standard install: %USERPROFILE%\\Documents\\Novadesk\\Addons

If no addons are requested, addon copying is skipped.

Setup EXE / ZIP Addon Inclusion ​

For setup/ZIP packaging, all requested addons are copied into staging Addons/ and bundled into installer payload files.

That means the setup installer installs requested addons together with the widget package files.

.ndpkg Addon Inclusion ​

For .ndpkg packaging, nwm build filters out default built-in addons and includes only non-default requested addons.

Default addon names treated as built-in include:

  • AppVolume / AppVolume.dll
  • AudioLevel / AudioLevel.dll
  • Brightness / Brightness.dll
  • Hotkey / Hotkey.dll
  • NowPlaying / NowPlaying.dll

The included addon file names are written to ndpkg.json:

json
{
  "addons": ["CustomAddon.dll"]
}

If no non-default addons remain after filtering, .ndpkg can still be valid with no addon files.

Addons in ndpkg_installer.exe ​

When opening a package, ndpkg_installer.exe:

  • Reads addon candidates from extracted Addons/ files.
  • Uses ndpkg.json.addons as a preferred order/filter signal.
  • Shows addon rows with status:
    • Add (not currently installed)
    • Replace (installed and package version is same/older/unknown comparison result)
    • Newer Version Found (installed addon version is newer than package addon)
  • Allows checkbox selection per addon before install.
  • Copies only checked addons into target Addons directory using overwrite behavior.

Addon Install Targets ​

Addon destination follows resolved install mode:

  • Portable Novadesk: <NovadeskFolder>/Addons
  • Standard Novadesk: %USERPROFILE%\\Documents\\Novadesk\\Addons

Installer Name Rules ​

  • Installer output name comes from setup.setupName.
  • If .exe is missing, nwm appends it automatically.

Examples:

  • setupName: "setup" -> dist/setup.exe
  • setupName: "MyWidgetSetup" -> dist/MyWidgetSetup.exe
  • setupName: "MyWidgetSetup.exe" -> dist/MyWidgetSetup.exe

Installer Stub Behavior ​

nwm uses installer_stub.exe as the base executable for the installer.

Lookup order:

  1. Next to nwm.exe
  2. Parent directory fallback
  3. Fallback to nwm.exe (with warning) if stub is not found

Install-Time Behavior ​

When the generated installer runs:

  • Installs files to setup.installDir (environment variables are expanded).
  • Creates Start Menu shortcut in setup.startMenuFolder.
  • Optionally creates Desktop shortcut.
  • Optionally creates Startup shortcut (createStartupShortcut or runOnStartup).
  • Optionally creates Uninstall.exe and uninstall registry entry.

.ndpkg Package Format ​

nwm build now also creates a widget package with .ndpkg extension.

Internally, .ndpkg is:

  1. A ZIP payload containing widget package files.
  2. A 16-byte footer appended at the end:
    • magic: NDPKG1
    • format version: 1

The installer validates this footer before extraction.

.ndpkg Contents ​

Typical package structure:

  • YourWidgetName_v1.0.0.0.ndpkg
    • ZIP payload)
    • ndpkg.json
    • preview.png optional extension depends on source
    • Widgets/
      • YourWidgetName/
        • index.js
        • meta.json
        • ui
        • assets
    • / optional
      • SomeAddon.dll

ndpkg.json is generated by nwm build and includes:

  • name (string)
  • version (string)
  • author (string)
  • addons (array of addon DLL names included in the package)

.ndpkg Installer Behavior ​

ndpkg_installer.exe:

  • Accepts .ndpkg path argument or opens a file picker.
  • Validates the NDPKG footer and extracts payload.
  • Requires ndpkg.json and Widgets/ to exist in the package.
  • Displays a preview image of the widget in the Widget Visuals pane if preview is specified in meta.json.
  • Installs to:
    • Portable Novadesk: <NovadeskFolder>/Widgets and <NovadeskFolder>/Addons
    • Standard Novadesk: %USERPROFILE%\\Documents\\Novadesk\\Widgets and ...\\Addons
  • Shows included addons and allows checkbox-based addon install selection.
  • Marks addon rows as Add/Replace/Newer Version Found based on installed DLL version info.
  • Uses an elevated fallback (manage_novadesk.exe --request-close) when admin-level close of Manage/Novadesk is required.

Preview Image Specifications ​

The installer displays your widget preview in the Widget Visuals section (324 × 266 px viewport, with an internal drawable area of 320 × 262 px).

The installer scales the image using cover mode (std::max(scaleX, scaleY) centered):

Spec Value Description
Aspect Ratio ~11 : 9 (1.22 : 1 or 32 : 26) Matches the preview viewport exactly to prevent cropping.
Recommended Resolution 640 × 524 px 2x HiDPI resolution for crisp rendering on high-DPI displays.
1:1 Resolution 320 × 262 px Exact viewport pixel dimension.
Supported Formats .png, .jpg, .jpeg, .bmp PNG is recommended for clarity and transparency.

Prevent Cropping

Because the installer centers and scales the image to cover the full preview box (object-fit: cover), any image with an aspect ratio significantly wider (e.g. 16:9) or taller (e.g. 1:1) will have its edges cropped. Keeping your preview image at or close to 640 × 524 px (or aspect ratio 1.22 : 1) ensures the entire image fits cleanly.

Notes ​

  • preview in meta.json specifies the relative path to your preview image (e.g., "preview": "assets/preview.png"). nwm build copies it into the root of the .ndpkg package.
  • icon is used for the built app executable (YourWidgetName.exe).
  • setup.setupIcon is used for the installer executable.
  • Unknown extra keys in setup are ignored.
  • createStartupShortcut and runOnStartup currently result in the same behavior (Startup shortcut creation).
  • launchAfterInstall is carried in installer metadata but is not currently acted on by the installer runtime.