diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt
index b222a55776cf0b4e77f79d823dd9a233b1c7328b..68d3343000305dad5c0cd9805dba0ac1bb707b9d 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactItem.kt
@@ -38,21 +38,22 @@ data class ContactItem(
         avatar = avatar,
     )
 
-    fun updateTimestampAndUnread(timestamp: Long, read: Boolean): ContactItem =
+    fun updateTimestampAndUnread(timestamp: Long, read: Boolean) =
         copy(
             isEmpty = false,
             unread = if (read) unread else unread + 1,
             timestamp = max(timestamp, this.timestamp)
         )
 
-    fun updateIsConnected(c: Boolean): ContactItem {
-        return copy(isConnected = c)
-    }
+    fun updateIsConnected(c: Boolean) =
+        copy(isConnected = c)
 
-    fun updateAlias(a: String?): ContactItem {
-        return copy(alias = a)
-    }
+    fun updateAlias(a: String?) =
+        copy(alias = a)
 
-    fun updateFromMessagesRead(c: Int): ContactItem =
+    fun updateFromMessagesRead(c: Int) =
         copy(unread = unread - c)
+
+    fun updateAvatar(avatar: ImageBitmap?) =
+        copy(avatar = avatar)
 }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt
index 745a2addf65f7d0b124e73ed658bbd2ab93e5ac9..c2a334a8a92e66a639a6bd79fa7c972224c0125d 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactListViewModel.kt
@@ -17,6 +17,7 @@ import org.briarproject.briar.api.conversation.event.ConversationMessageTrackedE
 import org.briarproject.briar.api.identity.AuthorManager
 import org.briarproject.briar.desktop.conversation.ConversationMessagesReadEvent
 import org.briarproject.briar.desktop.threading.BriarExecutors
+import org.briarproject.briar.desktop.utils.ImageUtils
 import org.briarproject.briar.desktop.viewmodel.asState
 import javax.inject.Inject
 
@@ -27,7 +28,7 @@ constructor(
     authorManager: AuthorManager,
     conversationManager: ConversationManager,
     connectionRegistry: ConnectionRegistry,
-    attachmentReader: AttachmentReader,
+    private val attachmentReader: AttachmentReader,
     briarExecutors: BriarExecutors,
     lifecycleManager: LifecycleManager,
     db: TransactionManager,
@@ -97,7 +98,16 @@ constructor(
             }
             is AvatarUpdatedEvent -> {
                 LOG.info("received avatar update: ${e.attachmentHeader}")
-                // TODO: update avatar
+                if (e.attachmentHeader == null) {
+                    updateItem(e.contactId) { it.updateAvatar(null) }
+                } else {
+                    runOnDbThreadWithTransaction(true) { txn ->
+                        val image = ImageUtils.loadAvatar(txn, attachmentReader, e.attachmentHeader)
+                        txn.attach {
+                            updateItem(e.contactId) { it.updateAvatar(image) }
+                        }
+                    }
+                }
             }
         }
     }
diff --git a/src/main/kotlin/org/briarproject/briar/desktop/utils/ImageUtils.kt b/src/main/kotlin/org/briarproject/briar/desktop/utils/ImageUtils.kt
index a8a346ddaed28001629c5588ee76217df13fd5a1..50c28fbdc6ae506dd73190646cc3f49c201ef641 100644
--- a/src/main/kotlin/org/briarproject/briar/desktop/utils/ImageUtils.kt
+++ b/src/main/kotlin/org/briarproject/briar/desktop/utils/ImageUtils.kt
@@ -4,6 +4,7 @@ import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.res.loadImageBitmap
 import org.briarproject.bramble.api.contact.Contact
 import org.briarproject.bramble.api.db.Transaction
+import org.briarproject.briar.api.attachment.AttachmentHeader
 import org.briarproject.briar.api.attachment.AttachmentReader
 import org.briarproject.briar.api.identity.AuthorManager
 
@@ -13,13 +14,19 @@ object ImageUtils {
         authorManager: AuthorManager,
         attachmentReader: AttachmentReader,
         txn: Transaction,
-        contact: Contact
+        contact: Contact,
     ): ImageBitmap? {
         val authorInfo = authorManager.getAuthorInfo(txn, contact)
-        if (authorInfo.avatarHeader == null) {
-            return null
-        }
-        val attachment = attachmentReader.getAttachment(txn, authorInfo.avatarHeader)
+        val avatarHeader = authorInfo.avatarHeader ?: return null
+        return loadAvatar(txn, attachmentReader, avatarHeader)
+    }
+
+    fun loadAvatar(
+        txn: Transaction,
+        attachmentReader: AttachmentReader,
+        attachmentHeader: AttachmentHeader,
+    ): ImageBitmap? {
+        val attachment = attachmentReader.getAttachment(txn, attachmentHeader)
         attachment.stream.use {
             return loadImageBitmap(it)
         }