diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt
index b406225863b6cba88c3750adfea1aa4201ddf8ac..8256634c1bda95b34816c0a59b2a1a1f09e81b96 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/DesktopModule.kt
@@ -55,8 +55,11 @@ import org.briarproject.briar.desktop.attachment.media.ImageCompressorImpl
 import org.briarproject.briar.desktop.notification.NotificationProvider
 import org.briarproject.briar.desktop.notification.StubNotificationProvider
 import org.briarproject.briar.desktop.notification.linux.LibnotifyNotificationProvider
+import org.briarproject.briar.desktop.settings.Configuration
+import org.briarproject.briar.desktop.settings.ConfigurationImpl
 import org.briarproject.briar.desktop.settings.UnencryptedSettings
 import org.briarproject.briar.desktop.settings.UnencryptedSettingsImpl
+import org.briarproject.briar.desktop.settings.UnencryptedSettingsReadOnly
 import org.briarproject.briar.desktop.threading.BriarExecutors
 import org.briarproject.briar.desktop.threading.BriarExecutorsImpl
 import org.briarproject.briar.desktop.threading.UiExecutor
@@ -109,6 +112,11 @@ internal class DesktopModule(
     @Singleton
     fun provideUnencryptedSettings(settings: UnencryptedSettingsImpl): UnencryptedSettings = settings
 
+    @Provides
+    @Singleton
+    // provide [UnencryptedSettings] singleton itself as provided above to use same object
+    fun provideUnencryptedSettingsReadOnly(settings: UnencryptedSettings): UnencryptedSettingsReadOnly = settings
+
     @Provides
     @Singleton
     @EventExecutor
@@ -171,6 +179,10 @@ internal class DesktopModule(
         override fun shouldEnableTransportSettings() = false
     }
 
+    @Provides
+    @Singleton
+    fun provideConfiguration(configuration: ConfigurationImpl): Configuration = configuration
+
     @Provides
     @Singleton
     internal fun provideImageCompressor(imageCompressor: ImageCompressorImpl): ImageCompressor {
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt
index ea43f749768fa41a83b47a2abb38e302db061dc8..77a8d96e3d66c4b470ad135465ee45dd681468fa 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/contact/ContactDropDown.kt
@@ -35,8 +35,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.unit.dp
 import org.briarproject.briar.desktop.contact.ContactDropDown.State
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
-import org.briarproject.briar.desktop.utils.getCoreFeatureFlags
-import org.briarproject.briar.desktop.utils.getDesktopFeatureFlags
+import org.briarproject.briar.desktop.utils.getConfiguration
 
 class ContactDropDown {
     enum class State {
@@ -56,8 +55,7 @@ fun ContactDropDown(
     onChangeAlias: () -> Unit,
     onDeleteContact: () -> Unit,
 ) {
-    val coreFeatureFlags = getCoreFeatureFlags()
-    val desktopFeatureFlags = getDesktopFeatureFlags()
+    val configuration = getConfiguration()
 
     val close = { setState(State.CLOSED) }
 
@@ -68,7 +66,7 @@ fun ContactDropDown(
         DropdownMenuItem(onClick = { close(); onMakeIntroduction() }) {
             Text(i18n("contacts.dropdown.introduction"), style = MaterialTheme.typography.body2)
         }
-        if (coreFeatureFlags.shouldEnableDisappearingMessages()) {
+        if (configuration.shouldEnableDisappearingMessages()) {
             DropdownMenuItem(onClick = {}) {
                 Text(i18n("contacts.dropdown.disappearing"), style = MaterialTheme.typography.body2)
             }
@@ -76,7 +74,7 @@ fun ContactDropDown(
         DropdownMenuItem(onClick = { close(); onDeleteAllMessages() }) {
             Text(i18n("contacts.dropdown.delete.all"), style = MaterialTheme.typography.body2)
         }
-        if (desktopFeatureFlags.shouldEnableTransportSettings()) {
+        if (configuration.shouldEnableTransportSettings()) {
             DropdownMenuItem(onClick = { setState(State.CONNECTION) }) {
                 Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
                     Text(
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
index a9c17ba486bdb89c157ad0bce81c9b44d809599c..513d76f55973edf25459214ee3bd2ff2d254ed3f 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/navigation/BriarSidebar.kt
@@ -28,6 +28,14 @@ import androidx.compose.foundation.selection.selectableGroup
 import androidx.compose.material.IconButton
 import androidx.compose.material.MaterialTheme
 import androidx.compose.material.Surface
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ChromeReaderMode
+import androidx.compose.material.icons.filled.Contacts
+import androidx.compose.material.icons.filled.Forum
+import androidx.compose.material.icons.filled.Group
+import androidx.compose.material.icons.filled.Info
+import androidx.compose.material.icons.filled.Settings
+import androidx.compose.material.icons.filled.WifiTethering
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
@@ -38,7 +46,7 @@ import org.briarproject.briar.desktop.contact.ProfileCircle
 import org.briarproject.briar.desktop.theme.sidebarSurface
 import org.briarproject.briar.desktop.ui.UiMode
 import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n
-import org.briarproject.briar.desktop.utils.getDesktopFeatureFlags
+import org.briarproject.briar.desktop.utils.getConfiguration
 
 val SIDEBAR_WIDTH = 56.dp
 
@@ -69,33 +77,27 @@ fun BriarSidebar(
                 account?.let { ProfileCircle(size = 45.dp, it.id.bytes) }
             }
             val modes = buildList {
-                add(UiMode.CONTACTS)
-                val featureFlags = getDesktopFeatureFlags()
-                if (featureFlags.shouldEnablePrivateGroups()) add(UiMode.GROUPS)
-                if (featureFlags.shouldEnableForums()) add(UiMode.FORUMS)
-                if (featureFlags.shouldEnableBlogs()) add(UiMode.BLOGS)
+                add(Pair(UiMode.CONTACTS, Icons.Filled.Contacts))
+                val configuration = getConfiguration()
+                if (configuration.shouldEnablePrivateGroups()) add(Pair(UiMode.GROUPS, Icons.Filled.Group))
+                if (configuration.shouldEnableForums()) add(Pair(UiMode.FORUMS, Icons.Filled.Forum))
+                if (configuration.shouldEnableBlogs()) add(Pair(UiMode.BLOGS, Icons.Filled.ChromeReaderMode))
             }
-            modes.forEach { mode ->
-                BriarSidebarButton(
-                    currentMode = uiMode,
-                    mode = mode,
-                    setUiMode = setUiMode,
-                )
+            modes.forEach { (mode, icon) ->
+                displayButton(uiMode, mode, icon)
             }
         }
         Column(verticalArrangement = Arrangement.Bottom) {
             val modes = buildList {
-                val featureFlags = getDesktopFeatureFlags()
-                if (featureFlags.shouldEnableTransportSettings()) add(UiMode.TRANSPORTS)
-                add(UiMode.SETTINGS)
-                add(UiMode.ABOUT)
-            }
-            modes.forEach { mode ->
-                BriarSidebarButton(
-                    currentMode = uiMode,
-                    mode = mode,
-                    setUiMode = setUiMode,
+                val configuration = getConfiguration()
+                if (configuration.shouldEnableTransportSettings()) add(
+                    Pair(UiMode.TRANSPORTS, Icons.Filled.WifiTethering)
                 )
+                add(Pair(UiMode.SETTINGS, Icons.Filled.Settings))
+                add(Pair(UiMode.ABOUT, Icons.Filled.Info))
+            }
+            modes.forEach { (mode, icon) ->
+                displayButton(uiMode, mode, icon)
             }
         }
     }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt
new file mode 100644
index 0000000000000000000000000000000000000000..aa042a5aa487757435932848e0a9db245c9525cb
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/Configuration.kt
@@ -0,0 +1,24 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 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.settings
+
+import org.briarproject.bramble.api.FeatureFlags
+import org.briarproject.briar.desktop.DesktopFeatureFlags
+
+interface Configuration : UnencryptedSettingsReadOnly, FeatureFlags, DesktopFeatureFlags
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt
new file mode 100644
index 0000000000000000000000000000000000000000..db7eabe9d80537dfa2efa114c5105d4aad78e913
--- /dev/null
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/ConfigurationImpl.kt
@@ -0,0 +1,33 @@
+/*
+ * Briar Desktop
+ * Copyright (C) 2021-2022 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.settings
+
+import org.briarproject.bramble.api.FeatureFlags
+import org.briarproject.briar.desktop.DesktopFeatureFlags
+import javax.inject.Inject
+
+class ConfigurationImpl
+@Inject internal constructor(
+    unencryptedSettings: UnencryptedSettingsReadOnly,
+    featureFlags: FeatureFlags,
+    desktopFeatureFlags: DesktopFeatureFlags,
+) : Configuration,
+    UnencryptedSettingsReadOnly by unencryptedSettings,
+    FeatureFlags by featureFlags,
+    DesktopFeatureFlags by desktopFeatureFlags
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/UnencryptedSettings.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/UnencryptedSettings.kt
index 0f12e8d35146807953f4a420b4d46563d7351c4c..650ed7e3dbe31f63909379d3ae4c8730123f93a5 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/UnencryptedSettings.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/settings/UnencryptedSettings.kt
@@ -21,7 +21,14 @@ package org.briarproject.briar.desktop.settings
 import org.briarproject.briar.desktop.viewmodel.SingleStateEvent
 import java.util.Locale
 
-interface UnencryptedSettings {
+interface UnencryptedSettingsReadOnly {
+    val theme: UnencryptedSettings.Theme
+    val language: UnencryptedSettings.Language
+
+    val invalidateScreen: SingleStateEvent<Unit>
+}
+
+interface UnencryptedSettings : UnencryptedSettingsReadOnly {
 
     enum class Theme { AUTO, LIGHT, DARK }
 
@@ -38,8 +45,8 @@ interface UnencryptedSettings {
             else Locale.forLanguageTag(name.replace('_', '-'))
     }
 
-    var theme: Theme
-    var language: Language
+    override var theme: Theme
+    override var language: Language
 
-    val invalidateScreen: SingleStateEvent<Unit>
+    override val invalidateScreen: SingleStateEvent<Unit>
 }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
index 771eb54199f66ade28f329aca9a22a7cd4aff519..772973ce264e6a913d3ae780eb3a211f745a6329 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/ui/BriarUi.kt
@@ -40,20 +40,18 @@ import androidx.compose.ui.platform.PlatformLocalization
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.window.FrameWindowScope
 import androidx.compose.ui.window.Window
-import org.briarproject.bramble.api.FeatureFlags
 import org.briarproject.bramble.api.event.EventBus
 import org.briarproject.bramble.api.event.EventListener
 import org.briarproject.bramble.api.lifecycle.LifecycleManager
 import org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING
 import org.briarproject.bramble.api.lifecycle.event.LifecycleEvent
 import org.briarproject.briar.api.conversation.event.ConversationMessageReceivedEvent
-import org.briarproject.briar.desktop.DesktopFeatureFlags
 import org.briarproject.briar.desktop.conversation.ConversationMessagesReadEvent
 import org.briarproject.briar.desktop.expiration.ExpirationBanner
 import org.briarproject.briar.desktop.login.ErrorScreen
 import org.briarproject.briar.desktop.login.StartupScreen
 import org.briarproject.briar.desktop.notification.NotificationProvider
-import org.briarproject.briar.desktop.settings.UnencryptedSettings
+import org.briarproject.briar.desktop.settings.Configuration
 import org.briarproject.briar.desktop.settings.UnencryptedSettings.Theme.AUTO
 import org.briarproject.briar.desktop.settings.UnencryptedSettings.Theme.DARK
 import org.briarproject.briar.desktop.theme.BriarTheme
@@ -85,8 +83,7 @@ interface BriarUi {
 
 val LocalWindowScope = staticCompositionLocalOf<FrameWindowScope?> { null }
 val LocalViewModelProvider = staticCompositionLocalOf<ViewModelProvider?> { null }
-val LocalCoreFeatureFlags = staticCompositionLocalOf<FeatureFlags?> { null }
-val LocalDesktopFeatureFlags = staticCompositionLocalOf<DesktopFeatureFlags?> { null }
+val LocalConfiguration = staticCompositionLocalOf<Configuration?> { null }
 
 @Immutable
 @Singleton
@@ -96,9 +93,7 @@ constructor(
     private val lifecycleManager: LifecycleManager,
     private val eventBus: EventBus,
     private val viewModelProvider: ViewModelProvider,
-    private val unencryptedSettings: UnencryptedSettings,
-    private val featureFlags: FeatureFlags,
-    private val desktopFeatureFlags: DesktopFeatureFlags,
+    private val configuration: Configuration,
     private val notificationProvider: NotificationProvider,
 ) : BriarUi {
 
@@ -147,6 +142,7 @@ constructor(
                     when (e) {
                         is LifecycleEvent ->
                             if (e.lifecycleState == RUNNING) screenState = MAIN
+
                         is ConversationMessageReceivedEvent<*> -> {
                             messageCount++
                             if (!focusState.focused) {
@@ -154,6 +150,7 @@ constructor(
                                 notificationProvider.notifyPrivateMessages(messageCount)
                             }
                         }
+
                         is ConversationMessagesReadEvent -> {
                             messageCount -= e.count
                             if (messageCount < 0) messageCount = 0
@@ -187,18 +184,17 @@ constructor(
                 LocalWindowScope provides this,
                 LocalWindowFocusState provides focusState,
                 LocalViewModelProvider provides viewModelProvider,
-                LocalCoreFeatureFlags provides featureFlags,
-                LocalDesktopFeatureFlags provides desktopFeatureFlags,
+                LocalConfiguration provides configuration,
                 LocalLocalization provides platformLocalization,
             ) {
                 // invalidate whole application window in case the theme or language setting is changed
-                unencryptedSettings.invalidateScreen.react {
+                configuration.invalidateScreen.react {
                     window.title = i18n("main.title")
                     return@CompositionLocalProvider
                 }
 
-                val isDarkTheme = unencryptedSettings.theme == DARK ||
-                    (unencryptedSettings.theme == AUTO && isSystemInDarkTheme())
+                val isDarkTheme = configuration.theme == DARK ||
+                    (configuration.theme == AUTO && isSystemInDarkTheme())
                 BriarTheme(isDarkTheme) {
                     Column(Modifier.fillMaxSize()) {
                         ExpirationBanner { screenState = EXPIRED; stop() }
diff --git a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/LocalCompositionProviderUtils.kt
similarity index 65%
rename from briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt
rename to briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/LocalCompositionProviderUtils.kt
index fafde86be2153b515347264fa185ddc58dc6fd66..c3dbf00efd0b7a4260c73f3ab644f8350d84dc64 100644
--- a/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/FeatureFlagUtils.kt
+++ b/briar-desktop/src/main/kotlin/org/briarproject/briar/desktop/utils/LocalCompositionProviderUtils.kt
@@ -19,15 +19,9 @@
 package org.briarproject.briar.desktop.utils
 
 import androidx.compose.runtime.Composable
-import org.briarproject.briar.desktop.ui.LocalCoreFeatureFlags
-import org.briarproject.briar.desktop.ui.LocalDesktopFeatureFlags
+import org.briarproject.briar.desktop.ui.LocalConfiguration
 
 @Composable
-fun getCoreFeatureFlags() = checkNotNull(LocalCoreFeatureFlags.current) {
-    "No FeatureFlags was provided via LocalCoreFeatureFlags" // NON-NLS
-}
-
-@Composable
-fun getDesktopFeatureFlags() = checkNotNull(LocalDesktopFeatureFlags.current) {
-    "No DesktopFeatureFlags was provided via LocalDesktopFeatureFlags" // NON-NLS
+fun getConfiguration() = checkNotNull(LocalConfiguration.current) {
+    "No configuration was provided via LocalConfiguration" // NON-NLS
 }
diff --git a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt
index 6fb2ca9fbc30cdd8a11ff89cd067b97838e173d4..84250542eccd0512a5e1bd50ac1308f8b0ffaa65 100644
--- a/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt
+++ b/briar-desktop/src/test/kotlin/org/briarproject/briar/desktop/DesktopTestModule.kt
@@ -56,8 +56,11 @@ import org.briarproject.briar.desktop.attachment.media.ImageCompressorImpl
 import org.briarproject.briar.desktop.notification.NotificationProvider
 import org.briarproject.briar.desktop.notification.StubNotificationProvider
 import org.briarproject.briar.desktop.notification.linux.LibnotifyNotificationProvider
+import org.briarproject.briar.desktop.settings.Configuration
+import org.briarproject.briar.desktop.settings.ConfigurationImpl
 import org.briarproject.briar.desktop.settings.UnencryptedSettings
 import org.briarproject.briar.desktop.settings.UnencryptedSettingsImpl
+import org.briarproject.briar.desktop.settings.UnencryptedSettingsReadOnly
 import org.briarproject.briar.desktop.testdata.DeterministicTestDataCreator
 import org.briarproject.briar.desktop.testdata.DeterministicTestDataCreatorImpl
 import org.briarproject.briar.desktop.testdata.TestAvatarCreatorImpl
@@ -111,6 +114,11 @@ internal class DesktopTestModule(
         return DesktopDatabaseConfig(dbDir, keyDir)
     }
 
+    @Provides
+    @Singleton
+    // provide [UnencryptedSettings] singleton itself as provided above to use same object
+    fun provideUnencryptedSettingsReadOnly(settings: UnencryptedSettings): UnencryptedSettingsReadOnly = settings
+
     @Provides
     @Singleton
     fun provideUnencryptedSettings(settings: UnencryptedSettingsImpl): UnencryptedSettings = settings
@@ -177,6 +185,10 @@ internal class DesktopTestModule(
         override fun shouldEnableTransportSettings() = false
     }
 
+    @Provides
+    @Singleton
+    fun provideConfiguration(configuration: ConfigurationImpl): Configuration = configuration
+
     @Provides
     @Singleton
     internal fun provideImageCompressor(imageCompressor: ImageCompressorImpl): ImageCompressor {