diff --git a/app/build.gradle b/app/build.gradle
index 0785a4d60..8df6b0b7e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,6 +7,7 @@ plugins {
     alias libs.plugins.compose.compiler
     alias libs.plugins.dependency.analysis
     alias libs.plugins.kotlin.android
+    alias libs.plugins.androidx.navigation.safeargs
 }
 
 apply from: "$project.rootDir/automation/gradle/versionCode.gradle"
@@ -251,6 +252,8 @@ dependencies {
     implementation libs.androidx.recyclerview
     implementation libs.androidx.swiperefreshlayout
     implementation libs.androidx.work.runtime.ktx
+    implementation libs.androidx.navigation.fragment
+    implementation libs.androidx.navigation.ui
 
     implementation platform(libs.androidx.compose.bom)
     implementation libs.androidx.compose.foundation
diff --git a/app/src/main/java/org/mozilla/reference/browser/BrowserActivity.kt b/app/src/main/java/org/mozilla/reference/browser/BrowserActivity.kt
index b790eacf7..7511afe29 100644
--- a/app/src/main/java/org/mozilla/reference/browser/BrowserActivity.kt
+++ b/app/src/main/java/org/mozilla/reference/browser/BrowserActivity.kt
@@ -25,6 +25,7 @@ import mozilla.components.support.webextensions.WebExtensionPopupObserver
 import org.mozilla.reference.browser.addons.WebExtensionActionPopupActivity
 import org.mozilla.reference.browser.browser.BrowserFragment
 import org.mozilla.reference.browser.browser.CrashIntegration
+import org.mozilla.reference.browser.browser.MainContainerFragment
 import org.mozilla.reference.browser.ext.components
 import org.mozilla.reference.browser.ext.isCrashReportActive
 
@@ -33,6 +34,8 @@ import org.mozilla.reference.browser.ext.isCrashReportActive
  */
 open class BrowserActivity : AppCompatActivity() {
 
+    private val logger = Logger("BrowserActivity")
+
     private lateinit var crashIntegration: CrashIntegration
 
     private val sessionId: String?
@@ -46,7 +49,7 @@ open class BrowserActivity : AppCompatActivity() {
      * Returns a new instance of [BrowserFragment] to display.
      */
     open fun createBrowserFragment(sessionId: String?): Fragment =
-        BrowserFragment.create(sessionId)
+        MainContainerFragment.create(sessionId)
 
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
@@ -75,7 +78,9 @@ open class BrowserActivity : AppCompatActivity() {
     @Suppress("MissingSuperCall", "OVERRIDE_DEPRECATION")
     override fun onBackPressed() {
         supportFragmentManager.fragments.forEach {
+            logger.debug("onBackPressed fragment: $it")
             if (it is UserInteractionHandler && it.onBackPressed()) {
+                logger.debug("onBackPressed UserInteractionHandler: $it")
                 return
             }
         }
diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/reference/browser/browser/BaseBrowserFragment.kt
index 073bf5f60..48608da03 100644
--- a/app/src/main/java/org/mozilla/reference/browser/browser/BaseBrowserFragment.kt
+++ b/app/src/main/java/org/mozilla/reference/browser/browser/BaseBrowserFragment.kt
@@ -14,14 +14,11 @@ import android.view.ViewGroup
 import androidx.activity.result.ActivityResultLauncher
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.annotation.CallSuper
-import androidx.compose.ui.platform.ComposeView
 import androidx.coordinatorlayout.widget.CoordinatorLayout
 import androidx.fragment.app.Fragment
 import androidx.preference.PreferenceManager
 import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
 import mozilla.components.browser.state.selector.selectedTab
-import mozilla.components.browser.toolbar.BrowserToolbar
-import mozilla.components.compose.browser.toolbar.BrowserToolbar
 import mozilla.components.concept.engine.EngineView
 import mozilla.components.feature.app.links.AppLinksFeature
 import mozilla.components.feature.downloads.DownloadsFeature
@@ -45,7 +42,6 @@ import mozilla.components.support.base.log.logger.Logger
 import mozilla.components.support.ktx.android.view.enterImmersiveMode
 import mozilla.components.support.ktx.android.view.exitImmersiveMode
 import mozilla.components.ui.widgets.behavior.EngineViewClippingBehavior
-import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior
 import org.mozilla.reference.browser.BuildConfig
 import org.mozilla.reference.browser.R
 import org.mozilla.reference.browser.addons.WebExtensionPromptFeature
@@ -55,7 +51,6 @@ import org.mozilla.reference.browser.ext.requireComponents
 import org.mozilla.reference.browser.pip.PictureInPictureIntegration
 import org.mozilla.reference.browser.tabs.LastTabFeature
 import mozilla.components.ui.widgets.behavior.ToolbarPosition as MozacEngineBehaviorToolbarPosition
-import mozilla.components.ui.widgets.behavior.ViewPosition as MozacToolbarBehaviorToolbarPosition
 
 /**
  * Base fragment extended by [BrowserFragment] and [ExternalAppBrowserFragment].
@@ -64,7 +59,6 @@ import mozilla.components.ui.widgets.behavior.ViewPosition as MozacToolbarBehavi
  */
 abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, ActivityResultHandler {
     private val sessionFeature = ViewBoundFeatureWrapper<SessionFeature>()
-    private val toolbarIntegration = ViewBoundFeatureWrapper<ToolbarIntegration>()
     private val contextMenuIntegration = ViewBoundFeatureWrapper<ContextMenuIntegration>()
     private val downloadsFeature = ViewBoundFeatureWrapper<DownloadsFeature>()
     private val shareDownloadsFeature = ViewBoundFeatureWrapper<ShareDownloadFeature>()
@@ -84,9 +78,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
 
     private val engineView: EngineView
         get() = requireView().findViewById<View>(R.id.engineView) as EngineView
-    private val toolbar: BrowserToolbar
-        get() = requireView().findViewById(R.id.toolbar)
-    private val findInPageBar: FindInPageBar
+    protected val findInPageBar: FindInPageBar
         get() = requireView().findViewById(R.id.findInPageBar)
     private val swipeRefresh: SwipeRefreshLayout
         get() = requireView().findViewById(R.id.swipeRefresh)
@@ -94,8 +86,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
     private val backButtonHandler: List<ViewBoundFeatureWrapper<*>> = listOf(
         fullScreenFeature,
         findInPageIntegration,
-        toolbarIntegration,
-
+//        toolbarIntegration,
         sessionFeature,
         lastTabFeature,
     )
@@ -114,6 +105,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
     private lateinit var requestSitePermissionsLauncher: ActivityResultLauncher<Array<String>>
     private lateinit var requestPromptsPermissionsLauncher: ActivityResultLauncher<Array<String>>
 
+    private val logger = Logger("BaseBrowserFragment")
+
     override fun onCreate(savedInstanceState: Bundle?) {
         super.onCreate(savedInstanceState)
         requestDownloadPermissionsLauncher =
@@ -153,16 +146,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
             }
     }
 
-    final override fun onCreateView(
-        inflater: LayoutInflater,
-        container: ViewGroup?,
-        savedInstanceState: Bundle?,
-    ): View {
-        return inflater.inflate(R.layout.fragment_browser, container, false)
-    }
-
-    abstract val shouldUseComposeUI: Boolean
-
     @CallSuper
     @Suppress("LongMethod")
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@@ -180,28 +163,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
             view = view,
         )
 
-        (toolbar.layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
-            behavior = EngineViewScrollingBehavior(
-                view.context,
-                null,
-                MozacToolbarBehaviorToolbarPosition.BOTTOM,
-            )
-        }
-        toolbarIntegration.set(
-            feature = ToolbarIntegration(
-                requireContext(),
-                toolbar,
-                requireComponents.core.historyStorage,
-                requireComponents.core.store,
-                requireComponents.useCases.sessionUseCases,
-                requireComponents.useCases.tabsUseCases,
-                requireComponents.useCases.webAppUseCases,
-                sessionId,
-            ),
-            owner = this,
-            view = view,
-        )
-
         contextMenuIntegration.set(
             feature = ContextMenuIntegration(
                 requireContext(),
@@ -357,7 +318,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
                 context,
                 null,
                 swipeRefresh,
-                toolbar.height,
+                resources.getDimensionPixelSize(R.dimen.browser_toolbar_height),
                 MozacEngineBehaviorToolbarPosition.BOTTOM,
             )
         }
@@ -402,28 +363,21 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
                 view = view,
             )
         }
-
-        val composeView = view.findViewById<ComposeView>(R.id.compose_view)
-        if (shouldUseComposeUI) {
-            composeView.visibility = View.VISIBLE
-            composeView.setContent { BrowserToolbar() }
-
-            val params = swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams
-            params.topMargin = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
-            swipeRefresh.layoutParams = params
-        }
     }
 
     private fun fullScreenChanged(enabled: Boolean) {
         if (enabled) {
             activity?.enterImmersiveMode()
-            toolbar.visibility = View.GONE
             engineView.setDynamicToolbarMaxHeight(0)
         } else {
             activity?.exitImmersiveMode()
-            toolbar.visibility = View.VISIBLE
             engineView.setDynamicToolbarMaxHeight(resources.getDimensionPixelSize(R.dimen.browser_toolbar_height))
         }
+        parentFragment?.parentFragmentManager
+            ?.setFragmentResult(
+                BROWSER_TO_MAIN_FRAGMENT_RESULT_KEY,
+                Bundle().apply { putBoolean(FULL_SCREEN_MODE_CHANGED, enabled) }
+            )
     }
 
     private fun viewportFitChanged(viewportFit: Int) {
@@ -434,7 +388,10 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
 
     @CallSuper
     override fun onBackPressed(): Boolean {
-        return backButtonHandler.any { it.onBackPressed() }
+        logger.info("onBackPressed")
+        return backButtonHandler.any { it.onBackPressed() }.also {
+            logger.info("Was it handled by back button handlers? $it")
+        }
     }
 
     final override fun onHomePressed(): Boolean {
@@ -452,8 +409,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
     }
 
     companion object {
-        private const val SESSION_ID = "session_id"
-
         @JvmStatic
         protected fun Bundle.putSessionId(sessionId: String?) {
             putString(SESSION_ID, sessionId)
@@ -461,7 +416,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
     }
 
     override fun onActivityResult(requestCode: Int, data: Intent?, resultCode: Int): Boolean {
-        Logger.info(
+        logger.info(
             "Fragment onActivityResult received with " +
                 "requestCode: $requestCode, resultCode: $resultCode, data: $data",
         )
diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt
index ffbe5f6fa..087c8c94f 100644
--- a/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt
+++ b/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt
@@ -5,97 +5,44 @@
 package org.mozilla.reference.browser.browser
 
 import android.os.Bundle
+import android.view.LayoutInflater
 import android.view.View
-import androidx.preference.PreferenceManager
-import com.google.android.material.floatingactionbutton.FloatingActionButton
+import android.view.ViewGroup
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import kotlinx.coroutines.launch
 import mozilla.components.browser.thumbnails.BrowserThumbnails
-import mozilla.components.browser.toolbar.BrowserToolbar
 import mozilla.components.concept.engine.EngineView
-import mozilla.components.feature.awesomebar.AwesomeBarFeature
-import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider
-import mozilla.components.feature.readerview.view.ReaderViewControlsBar
-import mozilla.components.feature.syncedtabs.SyncedTabsStorageSuggestionProvider
-import mozilla.components.feature.tabs.WindowFeature
-import mozilla.components.feature.tabs.toolbar.TabsToolbarFeature
-import mozilla.components.feature.toolbar.WebExtensionToolbarFeature
-import mozilla.components.support.base.feature.UserInteractionHandler
 import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
+import mozilla.components.support.base.log.logger.Logger
 import org.mozilla.reference.browser.R
-import org.mozilla.reference.browser.ext.components
 import org.mozilla.reference.browser.ext.requireComponents
-import org.mozilla.reference.browser.search.AwesomeBarWrapper
-import org.mozilla.reference.browser.tabs.TabsTrayFragment
 
 /**
  * Fragment used for browsing the web within the main app.
  */
-class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
-    private val thumbnailsFeature = ViewBoundFeatureWrapper<BrowserThumbnails>()
-    private val readerViewFeature = ViewBoundFeatureWrapper<ReaderViewIntegration>()
-    private val webExtToolbarFeature = ViewBoundFeatureWrapper<WebExtensionToolbarFeature>()
-    private val windowFeature = ViewBoundFeatureWrapper<WindowFeature>()
+class BrowserFragment : BaseBrowserFragment() {
+
+    private val logger = Logger("BrowserFragment")
+    private val mainContainerViewModel: MainContainerViewModel by viewModels(
+        ownerProducer = { requireParentFragment().requireParentFragment() },
+    )
 
-    private val awesomeBar: AwesomeBarWrapper
-        get() = requireView().findViewById(R.id.awesomeBar)
-    private val toolbar: BrowserToolbar
-        get() = requireView().findViewById(R.id.toolbar)
+    private val thumbnailsFeature = ViewBoundFeatureWrapper<BrowserThumbnails>()
     private val engineView: EngineView
         get() = requireView().findViewById<View>(R.id.engineView) as EngineView
-    private val readerViewBar: ReaderViewControlsBar
-        get() = requireView().findViewById(R.id.readerViewBar)
-    private val readerViewAppearanceButton: FloatingActionButton
-        get() = requireView().findViewById(R.id.readerViewAppearanceButton)
 
-    override val shouldUseComposeUI: Boolean
-        get() = PreferenceManager.getDefaultSharedPreferences(requireContext()).getBoolean(
-            getString(R.string.pref_key_compose_ui),
-            false,
-        )
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?,
+    ): View = inflater.inflate(R.layout.fragment_browser, container, false)
 
-    @Suppress("LongMethod")
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
-        AwesomeBarFeature(awesomeBar, toolbar, engineView)
-            .addSearchProvider(
-                requireContext(),
-                requireComponents.core.store,
-                requireComponents.useCases.searchUseCases.defaultSearch,
-                fetchClient = requireComponents.core.client,
-                mode = SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS,
-                engine = requireComponents.core.engine,
-                limit = 5,
-                filterExactMatch = true,
-            )
-            .addSessionProvider(
-                resources,
-                requireComponents.core.store,
-                requireComponents.useCases.tabsUseCases.selectTab,
-            )
-            .addHistoryProvider(
-                requireComponents.core.historyStorage,
-                requireComponents.useCases.sessionUseCases.loadUrl,
-            )
-            .addClipboardProvider(requireContext(), requireComponents.useCases.sessionUseCases.loadUrl)
-
-        // We cannot really add a `addSyncedTabsProvider` to `AwesomeBarFeature` coz that would create
-        // a dependency on feature-syncedtabs (which depends on Sync).
-        awesomeBar.addProviders(
-            SyncedTabsStorageSuggestionProvider(
-                requireComponents.backgroundServices.syncedTabsStorage,
-                requireComponents.useCases.tabsUseCases.addTab,
-                requireComponents.core.icons,
-            ),
-        )
-
-        TabsToolbarFeature(
-            toolbar = toolbar,
-            sessionId = sessionId,
-            store = requireComponents.core.store,
-            showTabs = ::showTabs,
-            lifecycleOwner = this,
-        )
-
         thumbnailsFeature.set(
             feature = BrowserThumbnails(
                 requireContext(),
@@ -106,56 +53,17 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
             view = view,
         )
 
-        readerViewFeature.set(
-            feature = ReaderViewIntegration(
-                requireContext(),
-                requireComponents.core.engine,
-                requireComponents.core.store,
-                toolbar,
-                readerViewBar,
-                readerViewAppearanceButton,
-            ),
-            owner = this,
-            view = view,
-        )
-
-        webExtToolbarFeature.set(
-            feature = WebExtensionToolbarFeature(
-                toolbar,
-                requireContext().components.core.store,
-            ),
-            owner = this,
-            view = view,
-        )
-
-        windowFeature.set(
-            feature = WindowFeature(
-                store = requireComponents.core.store,
-                tabsUseCases = requireComponents.useCases.tabsUseCases,
-            ),
-            owner = this,
-            view = view,
-        )
-
-        engineView.setDynamicToolbarMaxHeight(resources.getDimensionPixelSize(R.dimen.browser_toolbar_height))
-    }
-
-    private fun showTabs() {
-        // For now we are performing manual fragment transactions here. Once we can use the new
-        // navigation support library we may want to pass navigation graphs around.
-        activity?.supportFragmentManager?.beginTransaction()?.apply {
-            replace(R.id.container, TabsTrayFragment())
-            commit()
-        }
-    }
+        val toolbarMaxHeight: Int = resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
+        engineView.setDynamicToolbarMaxHeight(toolbarMaxHeight)
 
-    override fun onBackPressed(): Boolean =
-        readerViewFeature.onBackPressed() || super.onBackPressed()
+        logger.debug("ToolbarMaxHeight: $toolbarMaxHeight")
 
-    companion object {
-        fun create(sessionId: String? = null) = BrowserFragment().apply {
-            arguments = Bundle().apply {
-                putSessionId(sessionId)
+        viewLifecycleOwner.lifecycleScope.launch {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                mainContainerViewModel.toolbarOffset.collect {
+                    logger.debug("Toolbar offset: $it")
+                    findInPageBar.translationY = -toolbarMaxHeight + it
+                }
             }
         }
     }
diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/ExternalAppBrowserFragment.kt b/app/src/main/java/org/mozilla/reference/browser/browser/ExternalAppBrowserFragment.kt
index a6ace260a..595123bc0 100644
--- a/app/src/main/java/org/mozilla/reference/browser/browser/ExternalAppBrowserFragment.kt
+++ b/app/src/main/java/org/mozilla/reference/browser/browser/ExternalAppBrowserFragment.kt
@@ -6,7 +6,10 @@ package org.mozilla.reference.browser.browser
 
 import android.net.Uri
 import android.os.Bundle
+import android.view.LayoutInflater
 import android.view.View
+import android.view.ViewGroup
+import androidx.coordinatorlayout.widget.CoordinatorLayout
 import androidx.core.view.isVisible
 import mozilla.components.browser.toolbar.BrowserToolbar
 import mozilla.components.concept.engine.EngineView
@@ -21,6 +24,8 @@ import mozilla.components.support.base.feature.UserInteractionHandler
 import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
 import mozilla.components.support.ktx.android.arch.lifecycle.addObservers
 import mozilla.components.support.utils.ext.getParcelableArrayListCompat
+import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior
+import mozilla.components.ui.widgets.behavior.ViewPosition
 import org.mozilla.reference.browser.R
 import org.mozilla.reference.browser.ext.requireComponents
 
@@ -31,8 +36,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
     private val customTabsIntegration = ViewBoundFeatureWrapper<CustomTabsIntegration>()
     private val windowFeature = ViewBoundFeatureWrapper<CustomTabWindowFeature>()
     private val hideToolbarFeature = ViewBoundFeatureWrapper<WebAppHideToolbarFeature>()
-
-    override val shouldUseComposeUI: Boolean = false
+    private val toolbarIntegration = ViewBoundFeatureWrapper<ToolbarIntegration>()
 
     private val toolbar: BrowserToolbar
         get() = requireView().findViewById(R.id.toolbar)
@@ -44,12 +48,40 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
     private val trustedScopes: List<Uri>
         get() = arguments?.getParcelableArrayListCompat(ARG_TRUSTED_SCOPES, Uri::class.java).orEmpty()
 
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?,
+    ): View = inflater.inflate(R.layout.fragment_external_browser, container, false)
+
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
         val manifest = this.manifest
         val sessionId = this.sessionId
 
+        (toolbar.layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
+            behavior = EngineViewScrollingBehavior(
+                view.context,
+                null,
+                ViewPosition.BOTTOM,
+            )
+        }
+        toolbarIntegration.set(
+            feature = ToolbarIntegration(
+                requireContext(),
+                toolbar,
+                requireComponents.core.historyStorage,
+                requireComponents.core.store,
+                requireComponents.useCases.sessionUseCases,
+                requireComponents.useCases.tabsUseCases,
+                requireComponents.useCases.webAppUseCases,
+                sessionId,
+            ),
+            owner = this,
+            view = view,
+        )
+
         customTabsIntegration.set(
             feature = CustomTabsIntegration(
                 requireContext(),
diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerBrowserConstants.kt b/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerBrowserConstants.kt
new file mode 100644
index 000000000..3a397b661
--- /dev/null
+++ b/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerBrowserConstants.kt
@@ -0,0 +1,9 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.reference.browser.browser
+
+internal const val SESSION_ID = "sessionId"
+internal const val BROWSER_TO_MAIN_FRAGMENT_RESULT_KEY = "BrowserToMainFragmentResultKey"
+internal const val FULL_SCREEN_MODE_CHANGED = "FullScreenModeChanged"
diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerFragment.kt b/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerFragment.kt
new file mode 100644
index 000000000..17e4c4b7b
--- /dev/null
+++ b/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerFragment.kt
@@ -0,0 +1,310 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.reference.browser.browser
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewTreeObserver.OnDrawListener
+import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.view.isVisible
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.navigation.fragment.NavHostFragment
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import kotlinx.coroutines.launch
+import mozilla.components.browser.toolbar.BrowserToolbar
+import mozilla.components.feature.awesomebar.AwesomeBarFeature
+import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider
+import mozilla.components.feature.readerview.view.ReaderViewControlsBar
+import mozilla.components.feature.syncedtabs.SyncedTabsStorageSuggestionProvider
+import mozilla.components.feature.tabs.toolbar.TabsToolbarFeature
+import mozilla.components.feature.toolbar.WebExtensionToolbarFeature
+import mozilla.components.support.base.feature.UserInteractionHandler
+import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
+import mozilla.components.support.base.log.logger.Logger
+import mozilla.components.ui.widgets.behavior.EngineViewScrollingBehavior
+import mozilla.components.ui.widgets.behavior.ViewPosition
+import org.mozilla.reference.browser.R
+import org.mozilla.reference.browser.ext.components
+import org.mozilla.reference.browser.ext.requireComponents
+import org.mozilla.reference.browser.search.AwesomeBarWrapper
+import org.mozilla.reference.browser.tabs.TabsTrayFragment
+
+/**
+ * The container fragment for the browser. This fragment is responsible for setting up the chrome,
+ * handling navigation events to transition between BrowserFragment and HomeFragment.
+ */
+class MainContainerFragment : Fragment(), UserInteractionHandler {
+
+    private val logger = Logger("MainContainerFragment")
+
+    private val viewModel by viewModels<MainContainerViewModel>(
+        factoryProducer = { MainContainerViewModel.Factory(requireComponents.core.store) },
+    )
+
+    // Views
+    private val awesomeBar: AwesomeBarWrapper
+        get() = requireView().findViewById(R.id.awesomeBar)
+    private val toolbar: BrowserToolbar
+        get() = requireView().findViewById(R.id.toolbar)
+    private val readerViewBar: ReaderViewControlsBar
+        get() = requireView().findViewById(R.id.readerViewBar)
+    private val readerViewAppearanceButton: FloatingActionButton
+        get() = requireView().findViewById(R.id.readerViewAppearanceButton)
+
+    // Features
+    private val webExtToolbarFeature = ViewBoundFeatureWrapper<WebExtensionToolbarFeature>()
+    private val toolbarIntegration = ViewBoundFeatureWrapper<ToolbarIntegration>()
+    private val readerViewFeature = ViewBoundFeatureWrapper<ReaderViewIntegration>()
+
+    private val backButtonHandlers: List<ViewBoundFeatureWrapper<*>> = listOf(
+        readerViewFeature,
+        toolbarIntegration,
+    )
+
+    private val translationYOnDrawFetcher by lazy {
+        TranslationYOnDrawFetcher(
+            toolbar,
+            onDraw = { offset -> viewModel.updateToolbarOffset(offset) }
+        )
+    }
+
+    private val sessionId: String? by lazy { arguments?.getString(SESSION_ID) }
+
+    private val navHost by lazy {
+        childFragmentManager.findFragmentById(R.id.container) as NavHostFragment
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?,
+    ): View = inflater.inflate(R.layout.fragment_main_container, container, false)
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        setupToolbar(view)
+        setupAwesomeBar()
+        setupTabsToolbarFeature()
+        setupWebExtToolbarFeature(view)
+        setupReaderMode(view)
+
+        setupFragmentResultListener()
+        observeNavigationEvents()
+    }
+
+    override fun onBackPressed(): Boolean {
+        logger.debug("onBackPressed")
+        // Checks if any of the features handled the back press
+        // and if any child fragments that are UserInteractionHandlers handled it
+        return backButtonHandlers.any { it.onBackPressed() } ||
+                navHost.childFragmentManager.fragments
+                    .filterIsInstance<UserInteractionHandler>()
+                    .any {
+                        it.onBackPressed()
+                    }
+    }
+
+    override fun onDestroyView() {
+        toolbar.viewTreeObserver.removeOnDrawListener(translationYOnDrawFetcher)
+        super.onDestroyView()
+    }
+
+    private fun setupToolbar(view: View) {
+        toolbar.viewTreeObserver.addOnDrawListener(translationYOnDrawFetcher)
+
+        //        toolbar.viewTreeObserver.addOnPreDrawListener {
+        //            val currentTranslationY = toolbar.translationY
+        //            viewModel.updateToolbarOffset(currentTranslationY)
+        //            logger.debug("onPreDraw: $currentTranslationY")
+        //            true
+        //        }
+
+        (toolbar.layoutParams as? CoordinatorLayout.LayoutParams)?.apply {
+            behavior = EngineViewScrollingBehavior(
+                view.context,
+                null,
+                ViewPosition.BOTTOM,
+            )
+        }
+
+        toolbarIntegration.set(
+            feature = ToolbarIntegration(
+                requireContext(),
+                toolbar,
+                requireComponents.core.historyStorage,
+                requireComponents.core.store,
+                requireComponents.useCases.sessionUseCases,
+                requireComponents.useCases.tabsUseCases,
+                requireComponents.useCases.webAppUseCases,
+                sessionId,
+            ),
+            owner = this,
+            view = view,
+        )
+    }
+
+    private fun setupAwesomeBar() {
+        // EngineView was passed to AwesomeBarFeature to update it's visibility,
+        // but it seems odd that awesome bar needs to know about engine view, think about decoupling this
+        // maybe using the same approach as Home/BrowserTab
+        AwesomeBarFeature(awesomeBar, toolbar, null)
+            .addSearchProvider(
+                requireContext(),
+                requireComponents.core.store,
+                requireComponents.useCases.searchUseCases.defaultSearch,
+                fetchClient = requireComponents.core.client,
+                mode = SearchSuggestionProvider.Mode.MULTIPLE_SUGGESTIONS,
+                engine = requireComponents.core.engine,
+                limit = 5,
+                filterExactMatch = true,
+            )
+            .addSessionProvider(
+                resources,
+                requireComponents.core.store,
+                requireComponents.useCases.tabsUseCases.selectTab,
+            )
+            .addHistoryProvider(
+                requireComponents.core.historyStorage,
+                requireComponents.useCases.sessionUseCases.loadUrl,
+            )
+            .addClipboardProvider(
+                requireContext(),
+                requireComponents.useCases.sessionUseCases.loadUrl
+            )
+
+        // We cannot really add a `addSyncedTabsProvider` to `AwesomeBarFeature` coz that would create
+        // a dependency on feature-syncedtabs (which depends on Sync).
+        awesomeBar.addProviders(
+            SyncedTabsStorageSuggestionProvider(
+                requireComponents.backgroundServices.syncedTabsStorage,
+                requireComponents.useCases.tabsUseCases.addTab,
+                requireComponents.core.icons,
+            ),
+        )
+    }
+
+    private fun setupTabsToolbarFeature() {
+        TabsToolbarFeature(
+            toolbar = toolbar,
+            sessionId = sessionId,
+            store = requireComponents.core.store,
+            showTabs = ::showTabs,
+            lifecycleOwner = this,
+        )
+    }
+
+    private fun setupWebExtToolbarFeature(view: View) {
+        webExtToolbarFeature.set(
+            feature = WebExtensionToolbarFeature(
+                toolbar,
+                requireContext().components.core.store,
+            ),
+            owner = this,
+            view = view,
+        )
+    }
+
+    private fun setupReaderMode(view: View) {
+        readerViewFeature.set(
+            feature = ReaderViewIntegration(
+                requireContext(),
+                requireComponents.core.engine,
+                requireComponents.core.store,
+                toolbar,
+                readerViewBar,
+                readerViewAppearanceButton,
+            ),
+            owner = this,
+            view = view,
+        )
+    }
+
+    private fun observeNavigationEvents() {
+        viewLifecycleOwner.lifecycleScope.launch {
+            repeatOnLifecycle(Lifecycle.State.STARTED) {
+                viewModel.navigationEvent.collect { event ->
+                    logger.debug("Navigation event: $event")
+                    logger.debug("Current destination: ${navHost.navController.currentDestination}")
+                    when (event) {
+                        MainContainerViewModel.NavigationEvent.BrowserTab -> {
+                            navHost.navController.navigate(R.id.browserFragment)
+                        }
+
+                        MainContainerViewModel.NavigationEvent.Home -> {
+                            navHost.navController.navigate(R.id.homeFragment)
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Fetches the translationY of the toolbar on every draw event.
+     *
+     * @param view The view whose translationY is to be fetched.
+     * @param onDraw The callback to be called on every draw event with the translationY.
+     */
+    class TranslationYOnDrawFetcher(
+        private val view: View,
+        private val onDraw: (Float) -> Unit,
+    ) : OnDrawListener {
+
+        private val logger: Logger = Logger("ToolbarOffsetListener")
+
+        override fun onDraw() {
+            val currentTranslationY = view.translationY
+            logger.debug("onDraw: $currentTranslationY")
+            onDraw(currentTranslationY)
+        }
+    }
+
+    private fun setupFragmentResultListener() {
+        childFragmentManager.setFragmentResultListener(
+            BROWSER_TO_MAIN_FRAGMENT_RESULT_KEY,
+            this,
+        ) { _, bundle ->
+            val isFullScreen = bundle.getBoolean(FULL_SCREEN_MODE_CHANGED, false)
+            toolbar.isVisible = !isFullScreen
+        }
+    }
+
+    private fun showTabs() {
+        // For now we are performing manual fragment transactions here. Once we can use the new
+        // navigation support library we may want to pass navigation graphs around.
+        activity?.supportFragmentManager?.beginTransaction()?.apply {
+            replace(R.id.container, TabsTrayFragment())
+            commit()
+        }
+    }
+
+    /**
+     * @see [MainContainerFragment]
+     */
+    companion object {
+        @JvmStatic
+        private fun Bundle.putSessionId(sessionId: String?) {
+            putString(SESSION_ID, sessionId)
+        }
+
+        /**
+         * Create a new instance of [MainContainerFragment].
+         *
+         * @param sessionId The session id to use for the browser.
+         */
+        fun create(sessionId: String? = null) = MainContainerFragment().apply {
+            arguments = Bundle().apply {
+                putSessionId(sessionId)
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerViewModel.kt b/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerViewModel.kt
new file mode 100644
index 000000000..eebae4df4
--- /dev/null
+++ b/app/src/main/java/org/mozilla/reference/browser/browser/MainContainerViewModel.kt
@@ -0,0 +1,108 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.reference.browser.browser
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+import mozilla.components.browser.state.selector.selectedTab
+import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.lib.state.ext.flow
+import mozilla.components.support.base.log.logger.Logger
+
+/**
+ * ViewModel for [MainContainerFragment]. Holds state that is shared between MainContainerFragment
+ * and it's children.
+ *
+ * @param browserStore The [BrowserStore] instance user to observe state.
+ */
+class MainContainerViewModel(
+    private val browserStore: BrowserStore,
+) : ViewModel() {
+
+    private val logger = Logger("MainContainerViewModel")
+
+    init {
+        logger.debug("MainContainerViewModel created")
+        observeSelectedTab()
+    }
+
+    private val _toolbarOffset = MutableStateFlow(0f)
+    val toolbarOffset: StateFlow<Float> = _toolbarOffset.asStateFlow()
+
+    private val _navigationEvent = MutableSharedFlow<NavigationEvent>()
+    val navigationEvent: SharedFlow<NavigationEvent> = _navigationEvent.asSharedFlow()
+
+    /**
+     * Update the toolbar offset state. Call when the toolbar offset changes. Children fragments
+     * can observe this state to update their UI based on the toolbar position.
+     *
+     * @param offset The new offset.
+     */
+    fun updateToolbarOffset(offset: Float) {
+        _toolbarOffset.update { offset }
+    }
+
+    private fun observeSelectedTab() {
+        viewModelScope.launch {
+            browserStore.flow()
+                .map { it.selectedTab }
+                .distinctUntilChanged()
+                .map { it?.content?.url }
+                .distinctUntilChanged()
+                .map {
+                    logger.debug("Selected tab url: $it")
+                    when (it) {
+                        null, "about:blank" -> NavigationEvent.Home
+                        else -> NavigationEvent.BrowserTab
+                    }
+                }
+                .collect {
+                    logger.debug("Navigation event: $it")
+                    _navigationEvent.emit(it)
+                }
+        }
+    }
+
+    /**
+     * Navigation events emitted by the ViewModel.
+     */
+    sealed interface NavigationEvent {
+        /**
+         * Navigation event for navigating to the browser tab.
+         */
+        data object BrowserTab : NavigationEvent
+
+        /**
+         * Navigation event for navigating to the home screen.
+         */
+        data object Home : NavigationEvent
+    }
+
+    /**
+     * Factory for creating [MainContainerViewModel].
+     *
+     * @param browserStore The [BrowserStore] instance used to create [MainContainerViewModel].
+     */
+    class Factory(
+        private val browserStore: BrowserStore,
+    ) : ViewModelProvider.Factory {
+
+        @Suppress("UNCHECKED_CAST")
+        override fun <T : ViewModel> create(modelClass: Class<T>): T {
+            return MainContainerViewModel(browserStore) as T
+        }
+    }
+}
diff --git a/app/src/main/java/org/mozilla/reference/browser/compose/ComposeFragment.kt b/app/src/main/java/org/mozilla/reference/browser/compose/ComposeFragment.kt
new file mode 100644
index 000000000..058d58873
--- /dev/null
+++ b/app/src/main/java/org/mozilla/reference/browser/compose/ComposeFragment.kt
@@ -0,0 +1,47 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.reference.browser.compose
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.ViewCompositionStrategy
+import androidx.fragment.app.Fragment
+
+/**
+ * Base class for fragments that use Compose UI and have a 1:1 relationship with a Composable, i.e
+ * Fragments that do not have [View]s and [ComposeView]s defined in the XML layout.
+ *
+ * The ViewCompositionStrategy is set to [ViewCompositionStrategy.DisposeOnLifecycleDestroyed],
+ * meaning that the [ComposeView] will be disposed when the Fragment's view is destroyed.
+ *
+ * Read more about [ViewCompositionStrategy] here:
+ * https://medium.com/androiddevelopers/viewcompositionstrategy-demystefied-276427152f34
+ * https://developer.android.com/develop/ui/compose/migrate/interoperability-apis/compose-in-views#composition-strategy
+ */
+abstract class ComposeFragment : Fragment() {
+
+    final override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?,
+    ): View = ComposeView(requireContext()).apply {
+        setViewCompositionStrategy(
+            strategy = ViewCompositionStrategy.DisposeOnLifecycleDestroyed(viewLifecycleOwner),
+        )
+        setContent {
+            UI()
+        }
+    }
+
+    /**
+     * The Composable UI for this fragment that will be set as the content of the [ComposeView].
+     */
+    @Composable
+    abstract fun UI()
+}
diff --git a/app/src/main/java/org/mozilla/reference/browser/home/HomeFragment.kt b/app/src/main/java/org/mozilla/reference/browser/home/HomeFragment.kt
new file mode 100644
index 000000000..e7d2d8d05
--- /dev/null
+++ b/app/src/main/java/org/mozilla/reference/browser/home/HomeFragment.kt
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.reference.browser.home
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import org.mozilla.reference.browser.compose.ComposeFragment
+
+/**
+ * Fragment containing functionality for Home Tab - Top Sites, Stories, etc.
+ */
+class HomeFragment : ComposeFragment() {
+
+    @Composable
+    override fun UI() {
+        MaterialTheme {
+            Surface(modifier = Modifier.fillMaxSize()) {
+                Column(
+                    modifier = Modifier.fillMaxSize(),
+                    verticalArrangement = Arrangement.Center,
+                    horizontalAlignment = Alignment.CenterHorizontally,
+                ) {
+                    Text(
+                        text = "This is the Home Tab",
+                    )
+                }
+            }
+        }
+    }
+}
diff --git a/app/src/main/java/org/mozilla/reference/browser/tabs/TabsTrayFragment.kt b/app/src/main/java/org/mozilla/reference/browser/tabs/TabsTrayFragment.kt
index 8cf044c66..f99f8fc53 100644
--- a/app/src/main/java/org/mozilla/reference/browser/tabs/TabsTrayFragment.kt
+++ b/app/src/main/java/org/mozilla/reference/browser/tabs/TabsTrayFragment.kt
@@ -22,8 +22,8 @@ import mozilla.components.browser.tabstray.ViewHolderProvider
 import mozilla.components.browser.thumbnails.loader.ThumbnailLoader
 import mozilla.components.feature.tabs.tabstray.TabsFeature
 import mozilla.components.support.base.feature.UserInteractionHandler
+import org.mozilla.reference.browser.browser.MainContainerFragment
 import org.mozilla.reference.browser.R
-import org.mozilla.reference.browser.browser.BrowserFragment
 import org.mozilla.reference.browser.ext.components
 import org.mozilla.reference.browser.ext.requireComponents
 
@@ -73,7 +73,7 @@ class TabsTrayFragment : Fragment(), UserInteractionHandler {
 
     private fun closeTabsTray() {
         activity?.supportFragmentManager?.beginTransaction()?.apply {
-            replace(R.id.container, BrowserFragment.create())
+            replace(R.id.container, MainContainerFragment.create())
             commit()
         }
     }
diff --git a/app/src/main/res/layout/fragment_browser.xml b/app/src/main/res/layout/fragment_browser.xml
index 30293e998..90a9ca3e5 100644
--- a/app/src/main/res/layout/fragment_browser.xml
+++ b/app/src/main/res/layout/fragment_browser.xml
@@ -2,7 +2,7 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<androidx.coordinatorlayout.widget.CoordinatorLayout
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:mozac="http://schemas.android.com/apk/res-auto"
@@ -11,15 +11,6 @@
     android:layout_height="match_parent"
     tools:context=".BrowserActivity">
 
-    <androidx.compose.ui.platform.ComposeView
-        android:id="@+id/compose_view"
-        android:layout_width="match_parent"
-        android:layout_gravity="top"
-        android:background="#ffffcc00"
-        android:layout_marginBottom="@dimen/browser_toolbar_height"
-        android:layout_height="@dimen/browser_toolbar_height"
-        android:visibility="gone" />
-
     <mozilla.components.ui.widgets.VerticalSwipeRefreshLayout
         android:id="@+id/swipeRefresh"
         android:layout_width="match_parent"
@@ -30,13 +21,6 @@
             android:layout_height="match_parent" />
     </mozilla.components.ui.widgets.VerticalSwipeRefreshLayout>
 
-    <org.mozilla.reference.browser.search.AwesomeBarWrapper
-        android:id="@+id/awesomeBar"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:padding="4dp"
-        android:visibility="gone" />
-
     <mozilla.components.feature.findinpage.view.FindInPageBar
         android:id="@+id/findInPageBar"
         android:layout_width="match_parent"
@@ -50,35 +34,4 @@
         android:visibility="gone"
         app:layout_behavior="org.mozilla.reference.browser.browser.FindInPageBarBehavior" />
 
-    <mozilla.components.browser.toolbar.BrowserToolbar
-        android:id="@+id/toolbar"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/browser_toolbar_height"
-        android:layout_gravity="bottom"
-        android:background="@color/toolbarBackgroundColor"
-        mozac:browserToolbarTrackingProtectionAndSecurityIndicatorSeparatorColor="@color/photonWhite"
-        mozac:browserToolbarSuggestionForegroundColor="@color/toolbarSuggestionForeground"
-        mozac:browserToolbarSuggestionBackgroundColor="@color/toolbarSuggestionBackground" />
-
-    <mozilla.components.feature.readerview.view.ReaderViewControlsBar
-        android:id="@+id/readerViewBar"
-        android:background="#FFFFFFFF"
-        android:elevation="10dp"
-        android:visibility="gone"
-        android:layout_gravity="bottom"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content" />
-
-    <com.google.android.material.floatingactionbutton.FloatingActionButton
-        android:id="@+id/readerViewAppearanceButton"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end|bottom"
-        android:src="@drawable/mozac_ic_font"
-        android:visibility="gone"
-        android:layout_marginRight="16dp"
-        android:layout_marginLeft="16dp"
-        android:layout_marginBottom="16dp"
-        app:layout_behavior="org.mozilla.reference.browser.browser.ReaderViewAppearanceButtonBehavior" />
-
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
+</FrameLayout>
diff --git a/app/src/main/res/layout/fragment_external_browser.xml b/app/src/main/res/layout/fragment_external_browser.xml
new file mode 100644
index 000000000..cdda39baa
--- /dev/null
+++ b/app/src/main/res/layout/fragment_external_browser.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:mozac="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".ExternalAppBrowserActivity">
+
+    <mozilla.components.ui.widgets.VerticalSwipeRefreshLayout
+        android:id="@+id/swipeRefresh"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <mozilla.components.concept.engine.EngineView
+            android:id="@+id/engineView"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent" />
+    </mozilla.components.ui.widgets.VerticalSwipeRefreshLayout>
+
+    <mozilla.components.feature.findinpage.view.FindInPageBar
+        android:id="@+id/findInPageBar"
+        android:layout_width="match_parent"
+        android:layout_height="56dp"
+        android:layout_gravity="bottom"
+        android:background="#000000"
+        mozac:findInPageQueryTextColor="#ffffff"
+        mozac:findInPageQueryHintTextColor="#dddddd"
+        mozac:findInPageResultCountTextColor="#ff88ff"
+        mozac:findInPageButtonsTint="#ff88ff"
+        android:visibility="gone"
+        app:layout_behavior="org.mozilla.reference.browser.browser.FindInPageBarBehavior" />
+
+    <mozilla.components.browser.toolbar.BrowserToolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/browser_toolbar_height"
+        android:layout_gravity="bottom"
+        android:background="@color/toolbarBackgroundColor"
+        mozac:browserToolbarTrackingProtectionAndSecurityIndicatorSeparatorColor="@color/photonWhite"
+        mozac:browserToolbarSuggestionForegroundColor="@color/toolbarSuggestionForeground"
+        mozac:browserToolbarSuggestionBackgroundColor="@color/toolbarSuggestionBackground" />
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/layout/fragment_main_container.xml b/app/src/main/res/layout/fragment_main_container.xml
new file mode 100644
index 000000000..e449bf767
--- /dev/null
+++ b/app/src/main/res/layout/fragment_main_container.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?><!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:mozac="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    tools:context=".BrowserActivity">
+
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/container"
+        android:name="androidx.navigation.fragment.NavHostFragment"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:navGraph="@navigation/main_container_nav_graph" />
+
+    <org.mozilla.reference.browser.search.AwesomeBarWrapper
+        android:id="@+id/awesomeBar"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="4dp"
+        android:visibility="gone" />
+
+    <mozilla.components.browser.toolbar.BrowserToolbar
+        android:id="@+id/toolbar"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/browser_toolbar_height"
+        android:layout_gravity="bottom"
+        android:background="@color/toolbarBackgroundColor"
+        mozac:browserToolbarSuggestionBackgroundColor="@color/toolbarSuggestionBackground"
+        mozac:browserToolbarSuggestionForegroundColor="@color/toolbarSuggestionForeground"
+        mozac:browserToolbarTrackingProtectionAndSecurityIndicatorSeparatorColor="@color/photonWhite" />
+
+    <mozilla.components.feature.readerview.view.ReaderViewControlsBar
+        android:id="@+id/readerViewBar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom"
+        android:background="#FFFFFFFF"
+        android:elevation="10dp"
+        android:visibility="gone" />
+
+    <com.google.android.material.floatingactionbutton.FloatingActionButton
+        android:id="@+id/readerViewAppearanceButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="end|bottom"
+        android:layout_marginLeft="16dp"
+        android:layout_marginRight="16dp"
+        android:layout_marginBottom="16dp"
+        android:src="@drawable/mozac_ic_font"
+        android:visibility="gone"
+        app:layout_behavior="org.mozilla.reference.browser.browser.ReaderViewAppearanceButtonBehavior"
+        tools:ignore="ContentDescription" />
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/app/src/main/res/navigation/main_container_nav_graph.xml b/app/src/main/res/navigation/main_container_nav_graph.xml
new file mode 100644
index 000000000..1bcaea893
--- /dev/null
+++ b/app/src/main/res/navigation/main_container_nav_graph.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<navigation xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/main_container_nav_graph"
+    app:startDestination="@id/homeFragment">
+
+    <fragment
+        android:id="@+id/browserFragment"
+        android:name="org.mozilla.reference.browser.browser.BrowserFragment"
+        android:label="BrowserFragment"
+        tools:layout="@layout/fragment_browser" />
+
+    <fragment
+        android:id="@+id/homeFragment"
+        android:name="org.mozilla.reference.browser.home.HomeFragment"
+        android:label="HomeFragment" />
+
+</navigation>
diff --git a/build.gradle b/build.gradle
index 270950cc0..ca77310e9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -32,6 +32,7 @@ plugins {
     alias libs.plugins.dependency.analysis
     alias libs.plugins.detekt
     alias libs.plugins.kotlin.android apply false
+    alias libs.plugins.androidx.navigation.safeargs apply false
 }
 
 allprojects {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index ec102ad9d..7977b4374 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -28,6 +28,7 @@ androidx-preference = "1.2.1"
 androidx-recyclerview = "1.3.2"
 androidx-swiperefreshlayout = "1.1.0"
 androidx-work = "2.10.0"
+androidx-navigation = "2.8.5"
 
 # AndroidX Testing
 androidx-test-core = "1.6.1"
@@ -74,6 +75,8 @@ androidx-preference-ktx = { group = "androidx.preference", name = "preference-kt
 androidx-recyclerview = { group = "androidx.recyclerview", name = "recyclerview", version.ref = "androidx-recyclerview" }
 androidx-swiperefreshlayout = { group = "androidx.swiperefreshlayout", name = "swiperefreshlayout", version.ref = "androidx-swiperefreshlayout" }
 androidx-work-runtime-ktx = { group = "androidx.work", name = "work-runtime-ktx", version.ref = "androidx-work" }
+androidx-navigation-fragment = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "androidx-navigation" }
+androidx-navigation-ui = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "androidx-navigation" }
 
 # AndroidX Compose
 androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "androidx-composeBom" }
@@ -187,3 +190,4 @@ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "
 dependency-analysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependency-analysis" }
 detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
 kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+androidx-navigation-safeargs = { id = "androidx.navigation.safeargs", version.ref = "androidx-navigation" }