diff --git a/briar-desktop/build.gradle.kts b/briar-desktop/build.gradle.kts
index 602bf34c0da7ffe4e5b80a454ae330811f6957c9..ec450f55f9f73755ca79925cbe1df38abf9f4798 100644
--- a/briar-desktop/build.gradle.kts
+++ b/briar-desktop/build.gradle.kts
@@ -18,6 +18,7 @@
 
 @file:Suppress("HardCodedStringLiteral")
 
+import org.briarproject.briar.desktop.os.currentOS
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
@@ -77,11 +78,27 @@ buildData {
     windowsAumi = appName
 }
 
+val tor_version: String by rootProject.extra
+val obfs4proxy_version: String by rootProject.extra
+val snowflake_version: String by rootProject.extra
+
 dependencies {
     currentOs(compose.desktop.currentOs)
     windowsX64(compose.desktop.windows_x64)
     linuxX64(compose.desktop.linux_x64)
 
+    currentOs("org.briarproject:tor-${currentOS.id}:$tor_version")
+    currentOs("org.briarproject:obfs4proxy-${currentOS.id}:$obfs4proxy_version")
+    currentOs("org.briarproject:snowflake-${currentOS.id}:$snowflake_version")
+
+    linuxX64("org.briarproject:tor-linux:$tor_version")
+    linuxX64("org.briarproject:obfs4proxy-linux:$obfs4proxy_version")
+    linuxX64("org.briarproject:snowflake-linux:$snowflake_version")
+
+    windowsX64("org.briarproject:tor-windows:$tor_version")
+    windowsX64("org.briarproject:obfs4proxy-windows:$obfs4proxy_version")
+    windowsX64("org.briarproject:snowflake-windows:$snowflake_version")
+
     implementation(compose.materialIconsExtended)
     // needed to access Dispatchers.Swing for EventExecutor
     implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.6.4")
diff --git a/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/os/osUtils.kt b/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/os/osUtils.kt
new file mode 100644
index 0000000000000000000000000000000000000000..3dbe77365a23d5f0b27f1dbe638fa21a6894009d
--- /dev/null
+++ b/buildSrc/src/main/kotlin/org/briarproject/briar/desktop/os/osUtils.kt
@@ -0,0 +1,58 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2023 The Briar Project
+ *
+ * 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/>.
+ */
+
+package org.briarproject.briar.desktop.os
+
+enum class OS(val id: String) {
+    Linux("linux"),
+    Windows("windows"),
+    MacOS("macos")
+}
+
+enum class Arch(val id: String) {
+    X64("x64"),
+    Arm64("arm64")
+}
+
+data class Target(val os: OS, val arch: Arch) {
+    val id: String
+        get() = "${os.id}-${arch.id}"
+}
+
+val currentTarget by lazy {
+    Target(currentOS, currentArch)
+}
+
+val currentArch by lazy {
+    val osArch = System.getProperty("os.arch")
+    when (osArch) {
+        "x86_64", "amd64" -> Arch.X64
+        "aarch64" -> Arch.Arm64
+        else -> error("Unsupported OS arch: $osArch")
+    }
+}
+
+val currentOS: OS by lazy {
+    val os = System.getProperty("os.name")
+    when {
+        os.equals("Mac OS X", ignoreCase = true) -> OS.MacOS
+        os.startsWith("Win", ignoreCase = true) -> OS.Windows
+        os.startsWith("Linux", ignoreCase = true) -> OS.Linux
+        else -> error("Unknown OS name: $os")
+    }
+}