diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationScreen.kt
index 2666f779f86d8ae439b483a79932356db03d6b2b..50b275f76f3ab085c5b5643a0eace842578f3f95 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationScreen.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/RegistrationScreen.kt
@@ -1,6 +1,8 @@
 package org.briarproject.briar.desktop.login
 
+import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.requiredHeight
 import androidx.compose.foundation.text.KeyboardOptions
 import androidx.compose.material.InitialFocusState.AFTER_FIRST_FOCUSSED
 import androidx.compose.material.InitialFocusState.AFTER_FOCUS_LOST_ONCE
@@ -9,6 +11,7 @@ import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment.Companion.Center
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.FocusRequester
@@ -19,6 +22,7 @@ import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.ImeAction
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.text.input.PasswordVisualTransformation
+import androidx.compose.ui.unit.dp
 import org.briarproject.briar.desktop.login.RegistrationViewModel.State.CREATED
 import org.briarproject.briar.desktop.login.RegistrationViewModel.State.CREATING
 import org.briarproject.briar.desktop.login.RegistrationViewModel.State.INSERT_NICKNAME
@@ -113,6 +117,13 @@ fun PasswordForm(
     val initialFocusRequester = remember { FocusRequester() }
     val focusManager = LocalFocusManager.current
 
+    Box(
+        modifier = Modifier.fillMaxWidth().requiredHeight(24.dp),
+        contentAlignment = Center
+    ) {
+        if (password.isNotEmpty())
+            StrengthMeter(passwordStrength, Modifier.fillMaxWidth())
+    }
     OutlinedTextField(
         value = password,
         onValueChange = setPassword,
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt b/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt
new file mode 100644
index 0000000000000000000000000000000000000000..0207c290cff1312566acbcaae88847fb96b795d2
--- /dev/null
+++ b/src/main/kotlin/org/briarproject/briar/desktop/login/StrengthMeter.kt
@@ -0,0 +1,51 @@
+package org.briarproject.briar.desktop.login
+
+import androidx.compose.animation.animateColorAsState
+import androidx.compose.animation.core.animateFloatAsState
+import androidx.compose.material.LinearProgressIndicator
+import androidx.compose.material.ProgressIndicatorDefaults
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG
+import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK
+import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG
+import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK
+import org.briarproject.briar.desktop.utils.PreviewUtils.preview
+
+val RED = Color(255, 0, 0)
+val ORANGE = Color(255, 160, 0)
+val YELLOW = Color(255, 255, 0)
+val LIME = Color(180, 255, 0)
+val GREEN = Color(0, 255, 0)
+
+fun main() = preview(
+    "strength" to 0f
+) {
+    StrengthMeter(getFloatParameter("strength"))
+}
+
+@Composable
+fun StrengthMeter(
+    strength: Float,
+    modifier: Modifier = Modifier
+) {
+    val color = when {
+        strength < WEAK -> RED
+        strength < QUITE_WEAK -> ORANGE
+        strength < QUITE_STRONG -> YELLOW
+        strength < STRONG -> GREEN
+        else -> LIME
+    }
+    val animatedProgress by animateFloatAsState(
+        targetValue = strength,
+        animationSpec = ProgressIndicatorDefaults.ProgressAnimationSpec
+    )
+    val animatedColor by animateColorAsState(color)
+    LinearProgressIndicator(
+        progress = animatedProgress,
+        color = animatedColor,
+        modifier = modifier
+    )
+}
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
index 967b0e4bb606c32e9f123642e1f3ef23abc84569..032a405e1adba1dc4d28844a5e66655878bb8dbf 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/PreviewUtils.kt
@@ -64,6 +64,10 @@ object PreviewUtils {
 
         fun setLongParameter(name: String, value: Long) = setDatatype(name, value)
 
+        fun getFloatParameter(name: String) = getDatatype<Float>(name)
+
+        fun setFloatParameter(name: String, value: Float) = setDatatype(name, value)
+
         fun getRandomId() = random.nextBytes(UniqueId.LENGTH)
 
         @Composable
@@ -110,6 +114,11 @@ object PreviewUtils {
         BasicTextField(value.value.toString(), { value.value = it.toLong() })
     }
 
+    @Composable
+    private fun PreviewScope.addFloatParameter(name: String, initial: Float) = addParameter(name, initial) { value ->
+        BasicTextField(value.value.toString(), { value.value = it.toFloat() })
+    }
+
     /**
      * Open an interactive preview of the composable specified by [content].
      * All [parameters] passed to this function will be changeable on the fly.
@@ -132,6 +141,7 @@ object PreviewUtils {
                             is Boolean -> scope.addBooleanParameter(name, initial)
                             is Int -> scope.addIntParameter(name, initial)
                             is Long -> scope.addLongParameter(name, initial)
+                            is Float -> scope.addFloatParameter(name, initial)
                             else -> throw IllegalArgumentException("Type ${initial::class.simpleName} is not supported for previewing.")
                         }
                     }