Nucleus
Packaging & distribution

Building for Windows

Package a Nucleus app for Windows as an NSIS, MSI, MSIX/AppX, or Portable build and sign it for distribution.

In this tutorial, you'll package a Nucleus app for Windows in one or more of five formats — NSIS, NSIS Web, MSI, MSIX/AppX, and Portable — and sign the result for distribution.

Before you start

Windows packaging is part of the Nucleus Gradle plugin, so no extra dependency is required. You do need:

  • The Nucleus plugin applied to your build. It provides the windows { } block used below.
  • Windows Developer Mode enabled to build an AppX package locally (Settings → System → For developers). GitHub-hosted Windows runners already have it on.
  • A .pfx/.p12 certificate or Azure Artifact Signing credentials to sign a build.

Configure the Windows build

Add the formats you want to targetFormats(...), then configure the windows { } block:

build.gradle.kts
nucleus {
    application {
        nativeDistributions {
            targetFormats(
                TargetFormat.Nsis,
                TargetFormat.Msi,
                TargetFormat.AppX,
                TargetFormat.Portable,
            )

            windows {
                iconFile.set(project.file("icons/app.ico"))
                upgradeUuid = "d24e3b8d-3e9b-4cc7-a5d8-5e2d1f0c9f1b"
                perUserInstall = true
                menuGroup = "My Company"

                signing {
                    enabled = true
                    certificateFile.set(file("certs/certificate.pfx"))
                    certificatePassword = System.getenv("WIN_CSC_KEY_PASSWORD")
                    algorithm = SigningAlgorithm.Sha256
                    timestampServer = "http://timestamp.digicert.com"
                }
            }
        }
    }
}

The five Windows formats are:

  • TargetFormat.Nsis — the standard Windows installer.
  • TargetFormat.NsisWeb — an NSIS downloader stub that fetches the payload at install time.
  • TargetFormat.Msi — a Windows Installer package for enterprise deployment.
  • TargetFormat.AppX — an MSIX/AppX package for the Microsoft Store and sideloading.
  • TargetFormat.Portable — a single executable that runs without installation.

Customize the NSIS installer

Nucleus exposes the electron-builder NSIS options: one-click or assisted installs, per-user or per-machine placement, a language picker, custom header and sidebar bitmaps, a license dialog, and a script / includeScript escape hatch for custom NSIS sources.

windows {
    nsis {
        oneClick = false
        allowElevation = true
        perMachine = true
        allowToChangeInstallationDirectory = true
        createDesktopShortcut = true
        runAfterFinish = true

        multiLanguageInstaller = true
        installerLanguages = listOf("en_US", "fr_FR", "de_DE", "ja_JP")

        installerHeader.set(project.file("packaging/header.bmp"))
        installerSidebar.set(project.file("packaging/sidebar.bmp"))
        license.set(project.file("LICENSE"))
    }
}

Build an MSI for enterprise deployment

The MSI target is enabled by TargetFormat.Msi. Set upgradeUuid to a fixed value so Windows matches successor versions during an upgrade. Without a stable UUID, every new build is treated as a separate product.

Build an AppX or MSIX package

AppX targets produce an .appx (or a .msixbundle via CI). The Desktop Bridge runs with runFullTrust, so the app is not sandboxed in the Windows sense, but the format is accepted by the Microsoft Store and supports clean install and uninstall.

windows {
    appx {
        // Sideload identity — any CN that matches your signing certificate
        identityName = "MyCompany.MyApp"
        publisher = "CN=D541E802-6D30-446A-864E-2E8ABD2DAA5E"
        publisherDisplayName = "My Company"
        applicationId = "MyApp"

        languages = listOf("en-US", "fr-FR")
        backgroundColor = "#001F3F"
        storeLogo.set(project.file("packaging/appx/StoreLogo.png"))
        square44x44Logo.set(project.file("packaging/appx/Square44x44Logo.png"))
        square150x150Logo.set(project.file("packaging/appx/Square150x150Logo.png"))
        wide310x150Logo.set(project.file("packaging/appx/Wide310x150Logo.png"))

        // Store requires MinVersion > 10.0.17134.0
        minVersion = "10.0.17763.0"
        maxVersionTested = "10.0.22621.0"
    }
}

Developer Mode required for local AppX builds

Local AppX builds need Windows Developer Mode enabled (Settings → System → For developers). GitHub-hosted Windows runners already have it on.

Microsoft Store identity

For Microsoft Store submissions, identityName, publisher, and publisherDisplayName must match the values Partner Center assigned to your reservation; the Store rejects mismatches at upload time. publisher is the CN=<GUID> issued by Partner Center, not your local signing certificate's CN.

Enable Portable mode

TargetFormat.Portable produces a single executable that unpacks to a temporary directory at launch. No installer UI, no admin rights, no registry entries — useful for thumb-drive distribution.

Declare associations and URL protocols on nativeDistributions; they propagate into every Windows format:

nativeDistributions {
    protocol("MyApp", "myapp")  // myapp://… deep links
    fileAssociation(
        mimeType = "application/x-myapp",
        extension = "myapp",
        description = "MyApp Document",
    )
}

For a Windows-specific file icon, call windows.fileAssociation(...) instead.

Reference

The windows { } block exposes iconFile, packageName, console, dirChooser, perUserInstall, shortcut, menu, menuGroup, upgradeUuid, msiPackageVersion, and exePackageVersion, plus the sub-blocks nsis { }, appx { }, and signing { }. See the Gradle DSL reference for every property.

Notes

  • The MSI installer is built by electron-builder's WiX wrapper. For enterprise MSI customization beyond installation paths (custom dialogs, registry tweaks), use NSIS instead.
  • latest.yml (Windows update metadata) is generated for NSIS, MSI, and Portable. AppX is store-managed and has no auto-update YML.
  • WindowsJumpListManager.setProcessAppId() is called automatically on Windows during startup, so taskbar grouping and AUMID-aware notifications work without extra configuration.

What's next

  • Code signing — PFX and Azure Artifact Signing for Windows builds.
  • Publishing — push releases to GitHub, S3, or a generic server.
  • CI/CD — build and sign Windows packages on GitHub Actions.
  • Gradle DSL reference — the full nucleus { } configuration surface.