diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 84fca2d5342807b9d3a86ecc72577821a03c3b8b..6ef73b04c27eca562d490920fd9c4a188495620b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -39,116 +39,104 @@ ktlint:
       when: always
     - when: always
 
-b_jar:
+b_package_linux:
+  image: briar/ci-image-android:ubuntu-20-wine
   stage: build
   script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=nightly -x kaptKotlin packageUberJarForCurrentOS
-    - mv briar-desktop/build/compose/jars/Briar-*.jar ./briar-desktop.jar
-  artifacts:
-    paths:
-      - briar-desktop.jar
-    expire_in: 2 days
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "schedule"
-
-b_bullseye_deb:
-  stage: build
-  script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=nightly -x kaptKotlin packageDeb
-    - utils/finalize-deb.sh
-    - mv briar-desktop/build/compose/binaries/main/deb/briar-desktop.deb ./briar-desktop-debian-bullseye.deb
+    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=nightly
+      pinpitPackageDefaultUberJarForLinuxX64
+      pinpitPackageDefaultDebDebianBullseyeX64
+      pinpitPackageDefaultDebUbuntuBionicX64
+      pinpitPackageDefaultDebUbuntuFocalX64
+    - ls -lrth briar-desktop/build/pinpit/jars/Briar-linux-*.jar
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-18.04-x64-*.deb
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-20.04-x64-*.deb
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-debian-bullseye-x64-*.deb
+    - mv briar-desktop/build/pinpit/jars/Briar-linux-*.jar ./briar-desktop-linux.jar
+    - mv briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-18.04-x64-*.deb ./briar-desktop-ubuntu-18.04.deb
+    - mv briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-20.04-x64-*.deb ./briar-desktop-ubuntu-20.04.deb
+    - mv briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-debian-bullseye-x64-*.deb ./briar-desktop-debian-bullseye.deb
   artifacts:
     paths:
+      - briar-desktop-linux.jar
       - briar-desktop-debian-bullseye.deb
-    expire_in: 2 days
-  rules:
-    - if: $CI_PIPELINE_SOURCE == "schedule"
-
-b_20_ubuntu_deb:
-  image: briar/ci-image-android:ubuntu-20
-  stage: build
-  script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=nightly -x kaptKotlin packageDeb
-    - utils/finalize-deb.sh
-    - mv briar-desktop/build/compose/binaries/main/deb/briar-desktop.deb ./briar-desktop-ubuntu-20.04.deb
-  artifacts:
-    paths:
+      - briar-desktop-ubuntu-18.04.deb
       - briar-desktop-ubuntu-20.04.deb
     expire_in: 2 days
   rules:
     - if: $CI_PIPELINE_SOURCE == "schedule"
 
-b_18_ubuntu_deb:
-  image: briar/ci-image-android:ubuntu-18
+b_package_windows:
+  image: briar/ci-image-android:ubuntu-20-wine
   stage: build
   script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=nightly -x kaptKotlin packageDeb
-    - utils/finalize-deb.sh
-    - mv briar-desktop/build/compose/binaries/main/deb/briar-desktop.deb ./briar-desktop-ubuntu-18.04.deb
+    - wine --version
+    - wine uninstaller --list
+    - wget https://dl.winehq.org/wine/wine-mono/7.4.0/wine-mono-7.4.0-x86.msi
+    - wine msiexec /i wine-mono-7.4.0-x86.msi
+    - wine uninstaller --list
+    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=nightly
+      pinpitPackageDefaultUberJarForWindowsX64
+      pinpitPackageDefaultMsiX64
+    - ls -lrth briar-desktop/build/pinpit/jars/Briar-windows-*.jar
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/windows/x64/msi/Briar-x64-*.msi
+    - mv briar-desktop/build/pinpit/jars/Briar-windows-*.jar ./briar-desktop-windows.jar
+    - mv briar-desktop/build/pinpit/binaries/main-default/windows/x64/msi/Briar-x64-*.msi ./Briar-Desktop.msi
   artifacts:
     paths:
-      - briar-desktop-ubuntu-18.04.deb
+      - briar-desktop-windows.jar
+      - Briar-Desktop.msi
     expire_in: 2 days
   rules:
     - if: $CI_PIPELINE_SOURCE == "schedule"
 
-rb_jar:
+rb_package_linux:
+  image: briar/ci-image-android:ubuntu-20-wine
   stage: releasebuild
   script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=beta -x kaptKotlin packageUberJarForCurrentOS
-    - mv briar-desktop/build/compose/jars/Briar-*.jar ./briar-desktop.jar
-  artifacts:
-    paths:
-      - briar-desktop.jar
-    expire_in: 2 days
-  only:
-    - tags
-
-rb_bullseye_deb:
-  stage: releasebuild
-  script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=beta -x kaptKotlin packageDeb
-    - utils/finalize-deb.sh
-    - mv briar-desktop/build/compose/binaries/main/deb/briar-desktop.deb ./briar-desktop-debian-bullseye.deb
+    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=beta
+      pinpitPackageDefaultUberJarForLinuxX64
+      pinpitPackageDefaultDebDebianBullseyeX64
+      pinpitPackageDefaultDebUbuntuBionicX64
+      pinpitPackageDefaultDebUbuntuFocalX64
+    - ls -lrth briar-desktop/build/pinpit/jars/Briar-linux-*.jar
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-18.04-x64-*.deb
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-20.04-x64-*.deb
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-debian-bullseye-x64-*.deb
+    - mv briar-desktop/build/pinpit/jars/Briar-linux-*.jar ./briar-desktop-linux.jar
+    - mv briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-18.04-x64-*.deb ./briar-desktop-ubuntu-18.04.deb
+    - mv briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-ubuntu-20.04-x64-*.deb ./briar-desktop-ubuntu-20.04.deb
+    - mv briar-desktop/build/pinpit/binaries/main-default/linux/x64/deb/briar-desktop-debian-bullseye-x64-*.deb ./briar-desktop-debian-bullseye.deb
   artifacts:
     paths:
+      - briar-desktop-linux.jar
       - briar-desktop-debian-bullseye.deb
-    expire_in: 2 days
-  only:
-    - tags
-
-rb_20_ubuntu_deb:
-  image: briar/ci-image-android:ubuntu-20
-  stage: releasebuild
-  script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=beta -x kaptKotlin packageDeb
-    - utils/finalize-deb.sh
-    - mv briar-desktop/build/compose/binaries/main/deb/briar-desktop.deb ./briar-desktop-ubuntu-20.04.deb
-  artifacts:
-    paths:
+      - briar-desktop-ubuntu-18.04.deb
       - briar-desktop-ubuntu-20.04.deb
     expire_in: 2 days
   only:
     - tags
 
-rb_18_ubuntu_deb:
-  image: briar/ci-image-android:ubuntu-18
+rb_package_windows:
+  image: briar/ci-image-android:ubuntu-20-wine
   stage: releasebuild
   script:
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-11-openjdk-amd64 --no-daemon kaptKotlin
-    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=beta -x kaptKotlin packageDeb
-    - utils/finalize-deb.sh
-    - mv briar-desktop/build/compose/binaries/main/deb/briar-desktop.deb ./briar-desktop-ubuntu-18.04.deb
+    - wine --version
+    - wine uninstaller --list
+    - wget https://dl.winehq.org/wine/wine-mono/7.4.0/wine-mono-7.4.0-x86.msi
+    - wine msiexec /i wine-mono-7.4.0-x86.msi
+    - wine uninstaller --list
+    - ./gradlew -Dorg.gradle.java.home=/usr/lib/jvm/java-17-openjdk-amd64 --no-daemon -PbuildType=beta
+      pinpitPackageDefaultUberJarForWindowsX64
+      pinpitPackageDefaultMsiX64
+    - ls -lrth briar-desktop/build/pinpit/jars/Briar-windows-*.jar
+    - ls -lrth briar-desktop/build/pinpit/binaries/main-default/windows/x64/msi/Briar-x64-*.msi
+    - mv briar-desktop/build/pinpit/jars/Briar-windows-*.jar ./briar-desktop-windows.jar
+    - mv briar-desktop/build/pinpit/binaries/main-default/windows/x64/msi/Briar-x64-*.msi ./Briar-Desktop.msi
   artifacts:
     paths:
-      - briar-desktop-ubuntu-18.04.deb
+      - briar-desktop-windows.jar
+      - Briar-Desktop.msi
     expire_in: 2 days
   only:
     - tags
diff --git a/README.md b/README.md
index 2f7a24fe53bb7638e4f320d0eb6012583250c621..769d8685c9dfc372a9c8c0356d651c57a077862b 100644
--- a/README.md
+++ b/README.md
@@ -25,10 +25,12 @@ Each night a new build is compiled by Briar's GitLab CI.
 
 #### Self-contained Java .jar
 
-The simplest way is to
-[download the nightly briar-desktop.jar](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop.jar?job=b_jar)
+The simplest way is to download the nightly
+[briar-desktop-linux.jar](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-linux.jar?job=b_package_linux)
+or
+[briar-desktop-windows.jar](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-windows.jar?job=b_package_windows)
 and execute it from the command-line with
-`java -jar briar-desktop.jar`.
+`java -jar briar-desktop-linux.jar` or `java -jar briar-desktop-windows.jar` respectively.
 Note that you need at least version 17 of the Java Runtime Environment.
 
 #### Self-contained .deb
@@ -36,15 +38,20 @@ Note that you need at least version 17 of the Java Runtime Environment.
 For Debian- and Ubuntu-based Linux distributions, a set of .deb files is available.
 Depending on which version of Debian/Ubuntu your OS is based on,
 you can choose the right .deb file:
-* [Ubuntu 20.04](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-ubuntu-20.04.deb?job=b_20_ubuntu_deb)
-* [Debian stable (bullseye)](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-debian-bullseye.deb?job=b_bullseye_deb)
-* [Ubuntu 18.04](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-ubuntu-18.04.deb?job=b_18_ubuntu_deb)
+* [Ubuntu 20.04](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-ubuntu-20.04.deb?job=b_package_linux)
+* [Debian stable (bullseye)](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-debian-bullseye.deb?job=b_package_linux)
+* [Ubuntu 18.04](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/briar-desktop-ubuntu-18.04.deb?job=b_package_linux)
 
 Here are some examples of popular distributions and their respective .deb file:
 * Ubuntu 20.04 and compatible: Linux Mint 20.X (Ulyana, Ulyssa, Uma, Una), elementaryOS 6.X (Odin, Jólnir), Trisquel 10 (Nabia)
 * Debian stable (bullseye) and compatible: MX Linux MX-21
 * Ubuntu 18.04 and compatible: Linux Mint 19.X (Tara, Tessa, Tina, Tricia), elementaryOS 5.X (Juno, Hera), Trisquel 9 (Etiona)
 
+#### Windows installer .msi
+
+For Windows, an .msi installer package is available:
+* [Windows MSI](https://code.briarproject.org/briar/briar-desktop/-/jobs/artifacts/main/raw/Briar-Desktop.msi?job=b_package_windows)
+
 ## Developers
 
 ### Download Source Code
@@ -79,24 +86,25 @@ composable functions without parameters which are annotated with `@Preview`.
 
 In order to build and run the application from the command line, execute this:
 
-    ./gradlew run
+    ./gradlew pinpitRun
 
 You can specify arguments to the app using the `--args` option of the
 Gradle task. For example to show the usage info:
 
-    ./gradlew run --args="--help"
+    ./gradlew pinpitRun --args="--help"
 
 To specify a different data directory and enable the debug output:
 
-    ./gradlew run --args="--debug --data-dir=/tmp/briar-tmp"
+    ./gradlew pinpitRun --args="--debug --data-dir=/tmp/briar-tmp"
 
-In case you want to build a self-contained Debian package, note that you need at least JDK 17 and that you might need to install `binutils` and `fakeroot` before running the respective task:
+In case you want to build a self-contained Debian packages and an MSI installer,
+note that you need at least JDK 17:
 
-    ./gradlew packageDeb
+    ./gradlew pinpitPackageDefault
 
 If you want to use the JDKs downloaded by Intellij IDEA, you can for example specify the path like this:
 
-    ./gradlew packageDeb -Dorg.gradle.java.home=$HOME/.jdks/openjdk-17.0.2
+    ./gradlew pinpitPackageDefault -Dorg.gradle.java.home=$HOME/.jdks/openjdk-17.0.2
 
 Take a look at [_.gitlab-ci.yml_](.gitlab-ci.yml) if you have problems with Kotlin and JDK 17.
 
diff --git a/briar-desktop/build.gradle.kts b/briar-desktop/build.gradle.kts
index 333d26e32223cf2d8aecfdffbc4f263848373eb1..1e1d42036ee2015286bd87f7e6674b1b9c115bf6 100644
--- a/briar-desktop/build.gradle.kts
+++ b/briar-desktop/build.gradle.kts
@@ -18,24 +18,59 @@
 
 @file:Suppress("HardCodedStringLiteral")
 
-import org.jetbrains.compose.desktop.application.dsl.TargetFormat
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
     kotlin("jvm") version "1.7.20"
     kotlin("kapt") version "1.7.20"
     id("org.jetbrains.compose") version "1.2.1"
+    id("de.mobanisto.pinpit") version "0.3.0"
     id("java")
     id("idea")
     id("org.jlleitschuh.gradle.ktlint") version "10.1.0"
     id("org.briarproject.briar.desktop.build-data-gradle-plugin")
 }
 
+// We need to create separate Gradle configurations for Pinpit here. For each supported
+// target platform (OS+arch) we need one configuration in order to set the right native
+// Compose  dependency on it in the dependencies {} stanza below. The names need to be
+// exactly like this because Pinpit currently uses hardcoded configuration names when
+// deciding which configuration to use for packaging for each target platform.
+
+val currentOs: Configuration by configurations.creating {
+    extendsFrom(configurations.implementation.get())
+}
+
+val windowsX64: Configuration by configurations.creating {
+    extendsFrom(configurations.implementation.get())
+}
+
+val linuxX64: Configuration by configurations.creating {
+    extendsFrom(configurations.implementation.get())
+}
+
+sourceSets {
+    main {
+        java {
+            compileClasspath = currentOs
+            runtimeClasspath = currentOs
+        }
+    }
+    test {
+        java {
+            compileClasspath += currentOs
+            runtimeClasspath += currentOs
+        }
+    }
+}
+
 val versionCode = "0.3.1"
 val buildType = if (project.hasProperty("buildType")) project.properties["buildType"] else "snapshot"
 group = "app.briar.desktop"
 version = "$versionCode-$buildType"
+val appVendor = "The Briar Project"
 val appName = "Briar"
+val appDescription = "Secure messaging, anywhere"
 
 buildData {
     packageName = "org.briarproject.briar.desktop"
@@ -43,7 +78,10 @@ buildData {
 }
 
 dependencies {
-    implementation(compose.desktop.currentOs)
+    currentOs(compose.desktop.currentOs)
+    windowsX64(compose.desktop.windows_x64)
+    linuxX64(compose.desktop.linux_x64)
+
     implementation(compose.materialIconsExtended)
     // needed to access Dispatchers.Swing for EventExecutor
     implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.6.4")
@@ -97,20 +135,22 @@ tasks.jar {
     exclude("META-INF/BC2048KE.RSA", "META-INF/BC2048KE.SF", "META-INF/BC2048KE.DSA")
 }
 
-compose.desktop {
+pinpit.desktop {
     application {
         mainClass = "org.briarproject.briar.desktop.MainKt"
         nativeDistributions {
-            targetFormats(TargetFormat.Msi, TargetFormat.Exe, TargetFormat.Deb, TargetFormat.Rpm)
+            jvmVendor = "adoptium"
+            jvmVersion = "17.0.5+8"
+
             packageName = appName
-            description = "Secure messaging, anywhere"
-            vendor = "The Briar Project"
-            copyright = "2021-2022 The Briar Project"
+            packageVersion = version.toString()
+            description = appDescription
+            vendor = appVendor
+            copyright = "2021-2023 $appVendor"
             licenseFile.set(project.file("LICENSE.txt"))
             appResourcesRootDir.set(project.layout.projectDirectory.dir("src/appResources"))
-            // As described at https://github.com/JetBrains/compose-jb/tree/master/tutorials/Native_distributions_and_local_execution#configuring-included-jdk-modules
-            // the Gradle plugin does not automatically determine necessary JDK modules to ship
-            // so that we need to define required modules here:
+            // The required JDK modules to ship along with the distribution cannot easily
+            // be determined automatically, so it's necessary to specify them manually here:
             modules("java.sql")
             modules("java.naming")
             modules("jdk.localedata")
@@ -123,15 +163,60 @@ compose.desktop {
                 // rpm versions may not contain hyphens, so use underscore
                 rpmPackageVersion = "${versionCode}_$buildType"
                 iconFile.set(project.file("src/main/resources/images/logo_circle.png"))
+                debPreInst.set(project.file("src/packagingResources/linux/deb/preinst"))
+                debPostInst.set(project.file("src/packagingResources/linux/deb/postinst"))
+                debPreRm.set(project.file("src/packagingResources/linux/deb/prerm"))
+                debCopyright.set(project.file("src/packagingResources/linux/deb/copyright"))
+                debLauncher.set(project.file("src/packagingResources/linux/launcher.desktop"))
                 debMaintainer = "contact@briarproject.org"
                 appCategory = "comm"
-                menuGroup = "Network;Chat;InstantMessaging;"
+                // The packages mentioned in the depends() call can be found by running
+                // `./gradlew pinpitSuggestDebDependencies` on the respective target system.
+                // This uses a combination of `ldd` and `dpkg -S` on each `.so` file shipped with the app
+                // to find out which other shared libraries this depends on and which Debian package
+                // provides it.
+                deb("UbuntuFocalX64") {
+                    qualifier = "ubuntu-20.04"
+                    arch = "x64"
+                    depends(
+                        "libc6", "libexpat1", "libgcc-s1", "libpcre3", "libuuid1", "xdg-utils",
+                        "zlib1g", "libnotify4"
+                    )
+                }
+                deb("UbuntuBionicX64") {
+                    qualifier = "ubuntu-18.04"
+                    arch = "x64"
+                    depends(
+                        "libasound2", "libc6", "libexpat1", "libfontconfig1", "libfreetype6", "libgcc1",
+                        "libglib2.0-0", "libgraphite2-3", "libharfbuzz0b", "libjpeg-turbo8", "liblcms2-2",
+                        "libpcre3", "libpng16-16", "libstdc++6", "xdg-utils", "zlib1g", "libnotify4"
+                    )
+                }
+                deb("DebianBullseyeX64") {
+                    qualifier = "debian-bullseye"
+                    arch = "x64"
+                    depends(
+                        "libasound2", "libbrotli1", "libc6", "libexpat1", "libfontconfig1", "libfreetype6",
+                        "libgcc-s1", "libglib2.0-0", "libgraphite2-3", "libharfbuzz0b", "libjpeg62-turbo",
+                        "liblcms2-2", "libpcre3", "libpng16-16", "libstdc++6", "libuuid1", "xdg-utils", "zlib1g",
+                        "libnotify4"
+                    )
+                }
             }
             windows {
+                dirChooser = true
+                shortcut = true
                 iconFile.set(project.file("src/main/resources/images/logo_circle.ico"))
+                aumid = appName
                 upgradeUuid = "cc8b40f7-f190-4cea-bfec-ceb9ef85df09"
                 // Windows doesn't support things like 'nightly' or 'release'. Only numeric versions are acceptable
                 packageVersion = versionCode
+                mainExeFileDescription = "$appName - $appDescription"
+                msi {
+                    arch = "x64"
+                    bitmapBanner.set(project.file("src/packagingResources/windows/banner.bmp"))
+                    bitmapDialog.set(project.file("src/packagingResources/windows/dialog.bmp"))
+                }
             }
         }
     }
diff --git a/briar-desktop/src/packagingResources/linux/deb/copyright b/briar-desktop/src/packagingResources/linux/deb/copyright
new file mode 100644
index 0000000000000000000000000000000000000000..d972b0c698c4c5c2f06e4b6351f7a80bee411d85
--- /dev/null
+++ b/briar-desktop/src/packagingResources/linux/deb/copyright
@@ -0,0 +1,19 @@
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+
+Files: *
+Copyright: 2021-2023 The Briar Project
+License: AGPL-3+
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
diff --git a/briar-desktop/src/packagingResources/linux/postinst b/briar-desktop/src/packagingResources/linux/deb/postinst
similarity index 100%
rename from briar-desktop/src/packagingResources/linux/postinst
rename to briar-desktop/src/packagingResources/linux/deb/postinst
diff --git a/briar-desktop/src/packagingResources/linux/preinst b/briar-desktop/src/packagingResources/linux/deb/preinst
similarity index 100%
rename from briar-desktop/src/packagingResources/linux/preinst
rename to briar-desktop/src/packagingResources/linux/deb/preinst
diff --git a/briar-desktop/src/packagingResources/linux/prerm b/briar-desktop/src/packagingResources/linux/deb/prerm
similarity index 100%
rename from briar-desktop/src/packagingResources/linux/prerm
rename to briar-desktop/src/packagingResources/linux/deb/prerm
diff --git a/briar-desktop/src/packagingResources/linux/launcher.desktop b/briar-desktop/src/packagingResources/linux/launcher.desktop
new file mode 100644
index 0000000000000000000000000000000000000000..9692b6cd96323d8249d56a61b9f174bf5a6e6bcd
--- /dev/null
+++ b/briar-desktop/src/packagingResources/linux/launcher.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Briar
+Comment=Secure messaging, anywhere
+Exec=/opt/briar-desktop/bin/Briar
+Icon=/opt/briar-desktop/lib/Briar.png
+Terminal=false
+Type=Application
+Categories=Network;Chat;InstantMessaging;
+MimeType=
diff --git a/briar-desktop/src/packagingResources/windows/.gitignore b/briar-desktop/src/packagingResources/windows/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..caa3110f57e54e4510a92dec0a14956d40212260
--- /dev/null
+++ b/briar-desktop/src/packagingResources/windows/.gitignore
@@ -0,0 +1,2 @@
+banner.png
+dialog.png
diff --git a/briar-desktop/src/packagingResources/windows/banner.bmp b/briar-desktop/src/packagingResources/windows/banner.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..bb8d61eed7af07697aaab5f7e95c931f8790dc38
Binary files /dev/null and b/briar-desktop/src/packagingResources/windows/banner.bmp differ
diff --git a/briar-desktop/src/packagingResources/windows/banner.svg b/briar-desktop/src/packagingResources/windows/banner.svg
new file mode 100644
index 0000000000000000000000000000000000000000..d08db597ca83b19a547a931931ddaccef2cd2c85
--- /dev/null
+++ b/briar-desktop/src/packagingResources/windows/banner.svg
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="svg2"
+   sodipodi:docname="banner.svg"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
+   width="493"
+   height="58"
+   inkscape:export-filename="banner.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <metadata
+     id="metadata10">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6" />
+  <sodipodi:namedview
+     id="namedview4"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="1.1091666"
+     inkscape:cx="86.214987"
+     inkscape:cy="61.330774"
+     inkscape:window-width="1680"
+     inkscape:window-height="981"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     width="493px" />
+  <style
+     id="style3"
+     type="text/css">
+	.st0{fill:#FFFFFF;}
+	.st1{display:none;fill:#87C214;}
+	.st2{fill:#87C214;}
+	.st3{display:none;fill:#FFFFFF;}
+	.st4{fill:#95D220;}
+	.st5{display:none;fill:#95D220;}
+</style>
+  <g
+     id="g838"
+     transform="matrix(0.21053343,0,0,0.21053343,427.40936,-6.2122037)"
+     style="stroke-width:4.74983931">
+    <g
+       id="g1059"
+       style="stroke-width:4.74983931">
+      <path
+         style="fill:#87c214;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path15"
+         d="m 94.299994,145.70001 v 119.5 c 0,9.7 7.899996,17.7 17.699996,17.7 h 8.3 c 9.7,0 17.7,-8 17.7,-17.7 v -119.5 z"
+         class="st2" />
+      <path
+         style="fill:#87c214;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path17"
+         d="m 137.99999,88.000006 v -22.5 c 0,-9.7 -8,-17.7 -17.7,-17.7 h -8.3 c -9.7,0 -17.699996,8 -17.699996,17.7 v 22.5 z"
+         class="st2" />
+      <path
+         style="fill:#87c214;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path25"
+         d="M 234.99999,185.00001 V 65.500006 c 0,-9.7 -7.9,-17.7 -17.7,-17.7 h -8.3 c -9.7,0 -17.7,8 -17.7,17.7 V 185.00001 Z"
+         class="st2" />
+      <path
+         style="fill:#87c214;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path29"
+         d="m 191.29999,242.70001 v 22.5 c 0,9.7 8,17.7 17.7,17.7 h 8.3 c 9.7,0 17.7,-8 17.7,-17.7 v -22.5 z"
+         class="st2" />
+      <path
+         style="fill:#95d220;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path37"
+         d="m 87.299994,192.00001 h -22.5 c -9.7,0 -17.7,7.9 -17.7,17.7 v 8.3 c 0,9.7 7.9,17.7 17.7,17.7 h 22.5 z"
+         class="st4" />
+      <path
+         style="fill:#95d220;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path41"
+         d="m 264.49999,192.00001 h -119.5 v 43.7 h 119.5 c 9.7,0 17.7,-8 17.7,-17.7 v -8.3 c -0.1,-9.7 -8,-17.7 -17.7,-17.7 z"
+         class="st4" />
+      <path
+         style="fill:#95d220;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path51"
+         d="M 184.29999,95.000006 H 64.799994 c -9.7,0 -17.7,7.900004 -17.7,17.700004 v 8.3 c 0,9.7 7.9,17.7 17.7,17.7 H 184.29999 Z"
+         class="st4" />
+      <path
+         style="fill:#95d220;stroke-width:4.74983931"
+         inkscape:connector-curvature="0"
+         id="path53"
+         d="m 264.49999,95.000006 h -22.5 v 43.700004 h 22.5 c 9.7,0 17.7,-7.9 17.7,-17.7 v -8.3 c -0.1,-9.7 -8,-17.700004 -17.7,-17.700004 z"
+         class="st4" />
+    </g>
+  </g>
+</svg>
diff --git a/briar-desktop/src/packagingResources/windows/convert.sh b/briar-desktop/src/packagingResources/windows/convert.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5cf4467d987628bc90e6b80d75c04a5572086991
--- /dev/null
+++ b/briar-desktop/src/packagingResources/windows/convert.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+inkscape -C -e banner.png banner.svg
+inkscape -C -e dialog.png dialog.svg
+
+convert banner.png banner.bmp
+convert dialog.png dialog.bmp
diff --git a/briar-desktop/src/packagingResources/windows/dialog.bmp b/briar-desktop/src/packagingResources/windows/dialog.bmp
new file mode 100644
index 0000000000000000000000000000000000000000..bb764d1cb2d6daca36101a5b186da564769a833d
Binary files /dev/null and b/briar-desktop/src/packagingResources/windows/dialog.bmp differ
diff --git a/briar-desktop/src/packagingResources/windows/dialog.svg b/briar-desktop/src/packagingResources/windows/dialog.svg
new file mode 100644
index 0000000000000000000000000000000000000000..94b7a0e41b7ae8f471aa91815edab3c80c7d8f43
--- /dev/null
+++ b/briar-desktop/src/packagingResources/windows/dialog.svg
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="svg2"
+   sodipodi:docname="dialog.svg"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
+   width="493"
+   height="312"
+   inkscape:export-filename="dialog.png"
+   inkscape:export-xdpi="96"
+   inkscape:export-ydpi="96">
+  <metadata
+     id="metadata13">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6">
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient1123">
+      <stop
+         style="stop-color:#0044aa;stop-opacity:1;"
+         offset="0"
+         id="stop1119" />
+      <stop
+         style="stop-color:#79f344;stop-opacity:1"
+         offset="1"
+         id="stop1121" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient1123"
+       id="linearGradient1125"
+       x1="434.21234"
+       y1="27.777527"
+       x2="487.01492"
+       y2="27.777527"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-345.06367,-2.4622972)" />
+  </defs>
+  <sodipodi:namedview
+     id="namedview4"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="0.55458332"
+     inkscape:cx="-336.80909"
+     inkscape:cy="233.53699"
+     inkscape:window-width="1680"
+     inkscape:window-height="981"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2"
+     width="493px"
+     inkscape:snap-page="true"
+     inkscape:snap-global="false" />
+  <path
+     sodipodi:type="star"
+     style="fill:url(#linearGradient1125);fill-opacity:1"
+     id="path957"
+     inkscape:flatsided="false"
+     sodipodi:sides="5"
+     sodipodi:cx="115.33324"
+     sodipodi:cy="27.759957"
+     sodipodi:r1="27.768814"
+     sodipodi:r2="13.884408"
+     sodipodi:arg1="0.96773607"
+     sodipodi:arg2="1.5960546"
+     inkscape:rounded="0"
+     inkscape:randomized="0"
+     d="M 131.08275,50.630457 114.98258,41.639936 98.448966,49.806009 102.02423,31.715609 89.148668,18.514665 107.45848,16.324705 116.03455,-2.1839437e-7 123.77537,16.736929 l 18.17587,3.111722 -13.52572,12.533951 z"
+     inkscape:transform-center-x="-0.21671913"
+     inkscape:transform-center-y="-2.4447277" />
+  <rect
+     style="fill:#2e3d4f;stroke-width:0.83427;fill-opacity:1"
+     id="rect859"
+     width="164"
+     height="312"
+     x="0"
+     y="0" />
+  <style
+     id="style3"
+     type="text/css">
+	.st0{fill:#FFFFFF;}
+	.st1{display:none;fill:#87C214;}
+	.st2{fill:#87C214;}
+	.st3{display:none;fill:#FFFFFF;}
+	.st4{fill:#95D220;}
+	.st5{display:none;fill:#95D220;}
+</style>
+  <g
+     id="g844"
+     transform="matrix(0.22810234,0,0,0.22810234,78.267585,8.31882)"
+     style="stroke-width:4.38399696">
+    <g
+       id="g1059"
+       style="stroke-width:4.38399696">
+      <path
+         style="fill:#87c214;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path15"
+         d="m 94.299994,145.70001 v 119.5 c 0,9.7 7.899996,17.7 17.699996,17.7 h 8.3 c 9.7,0 17.7,-8 17.7,-17.7 v -119.5 z"
+         class="st2" />
+      <path
+         style="fill:#87c214;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path17"
+         d="m 137.99999,88.000006 v -22.5 c 0,-9.7 -8,-17.7 -17.7,-17.7 h -8.3 c -9.7,0 -17.699996,8 -17.699996,17.7 v 22.5 z"
+         class="st2" />
+      <path
+         style="fill:#87c214;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path25"
+         d="M 234.99999,185.00001 V 65.500006 c 0,-9.7 -7.9,-17.7 -17.7,-17.7 h -8.3 c -9.7,0 -17.7,8 -17.7,17.7 V 185.00001 Z"
+         class="st2" />
+      <path
+         style="fill:#87c214;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path29"
+         d="m 191.29999,242.70001 v 22.5 c 0,9.7 8,17.7 17.7,17.7 h 8.3 c 9.7,0 17.7,-8 17.7,-17.7 v -22.5 z"
+         class="st2" />
+      <path
+         style="fill:#95d220;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path37"
+         d="m 87.299994,192.00001 h -22.5 c -9.7,0 -17.7,7.9 -17.7,17.7 v 8.3 c 0,9.7 7.9,17.7 17.7,17.7 h 22.5 z"
+         class="st4" />
+      <path
+         style="fill:#95d220;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path41"
+         d="m 264.49999,192.00001 h -119.5 v 43.7 h 119.5 c 9.7,0 17.7,-8 17.7,-17.7 v -8.3 c -0.1,-9.7 -8,-17.7 -17.7,-17.7 z"
+         class="st4" />
+      <path
+         style="fill:#95d220;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path51"
+         d="M 184.29999,95.000006 H 64.799994 c -9.7,0 -17.7,7.900004 -17.7,17.700004 v 8.3 c 0,9.7 7.9,17.7 17.7,17.7 H 184.29999 Z"
+         class="st4" />
+      <path
+         style="fill:#95d220;stroke-width:4.38399696"
+         inkscape:connector-curvature="0"
+         id="path53"
+         d="m 264.49999,95.000006 h -22.5 v 43.700004 h 22.5 c 9.7,0 17.7,-7.9 17.7,-17.7 v -8.3 c -0.1,-9.7 -8,-17.700004 -17.7,-17.700004 z"
+         class="st4" />
+    </g>
+  </g>
+</svg>
diff --git a/gradle.properties b/gradle.properties
index 7a18ef373c772af5bd1beba73847a9c2e757da31..1983578fc366d687731660ae3916242b98c49ced 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,3 +1,2 @@
 kotlin.code.style=official
-org.gradle.jvmargs=--add-opens=java.base/java.io=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
 org.gradle.jvmargs=-Xmx2g
diff --git a/utils/finalize-deb.sh b/utils/finalize-deb.sh
deleted file mode 100755
index 511448c6f8f78129139377baafc71bab8dfd1fa8..0000000000000000000000000000000000000000
--- a/utils/finalize-deb.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-
-# A script for manually adding files to the produced .deb files.
-# https://unix.stackexchange.com/a/138190
-
-set -ex
-
-DIR=$(dirname $0)
-REPO="$DIR/.."
-
-cd "$REPO/briar-desktop/build/compose/binaries/main/deb"
-
-cp ./briar-desktop_*.deb briar-desktop.original.deb
-
-fakeroot sh -c '
-  mkdir tmp
-  dpkg-deb -R briar-desktop.original.deb tmp
-  cp ../../../../../src/packagingResources/linux/postinst tmp/DEBIAN/postinst
-  cp ../../../../../src/packagingResources/linux/preinst tmp/DEBIAN/preinst
-  cp ../../../../../src/packagingResources/linux/prerm tmp/DEBIAN/prerm
-  sed -i "/Depends:/s/$/, libnotify4/" tmp/DEBIAN/control
-  dpkg-deb -b tmp briar-desktop.deb
-  rm -r tmp
-'