diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
index 56b251f19db7a0e3f15fa6482e894c87d001bdb1..f38ba877a1e73d63b59bf9e87d39ac35eb28b58a 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHost.cs
@@ -1,10 +1,9 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Diagnostics;
 using System.Reflection.Metadata;
-using System.Text.Json;
 using Microsoft.AspNetCore.Components.Lifetime;
-using Microsoft.AspNetCore.Components.Web;
 using Microsoft.AspNetCore.Components.Web.Infrastructure;
 using Microsoft.AspNetCore.Components.WebAssembly.HotReload;
 using Microsoft.AspNetCore.Components.WebAssembly.Infrastructure;
@@ -12,7 +11,6 @@ using Microsoft.AspNetCore.Components.WebAssembly.Rendering;
 using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Logging;
-using Microsoft.JSInterop;
 
 namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
 {
@@ -27,7 +25,6 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
         private readonly IConfiguration _configuration;
         private readonly RootComponentMappingCollection _rootComponents;
         private readonly string? _persistedState;
-        private readonly JsonSerializerOptions _jsonOptions;
 
         // NOTE: the host is disposable because it OWNs references to disposable things.
         //
@@ -46,8 +43,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
             WebAssemblyHostBuilder builder,
             IServiceProvider services,
             AsyncServiceScope scope,
-            string? persistedState,
-            JsonSerializerOptions jsonOptions)
+            string? persistedState)
         {
             // To ensure JS-invoked methods don't get linked out, have a reference to their enclosing types
             GC.KeepAlive(typeof(JSInteropMethods));
@@ -57,7 +53,6 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
             _configuration = builder.Configuration;
             _rootComponents = builder.RootComponents;
             _persistedState = persistedState;
-            _jsonOptions = jsonOptions;
         }
 
         /// <summary>
diff --git a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
index 921e317810edc7ae4e574df9dedc84681a364cd9..9f0a7a7aa7c552c81f6c618e68710fe2faf6ebc4 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/Hosting/WebAssemblyHostBuilder.cs
@@ -43,7 +43,6 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
         {
             // We don't use the args for anything right now, but we want to accept them
             // here so that it shows up this way in the project templates.
-            args ??= Array.Empty<string>();
             var jsRuntime = DefaultWebAssemblyJSRuntime.Instance;
             var builder = new WebAssemblyHostBuilder(
                 jsRuntime,
@@ -241,7 +240,7 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
             var services = _createServiceProvider();
             var scope = services.GetRequiredService<IServiceScopeFactory>().CreateAsyncScope();
 
-            return new WebAssemblyHost(this, services, scope, _persistedState, _jsonOptions);
+            return new WebAssemblyHost(this, services, scope, _persistedState);
         }
 
         internal void InitializeDefaultServices()
diff --git a/src/Components/WebAssembly/WebAssembly/src/HotReload/HotReloadAgent.cs b/src/Components/WebAssembly/WebAssembly/src/HotReload/HotReloadAgent.cs
index f67f66cd19fce6398c759c1937977dd6d65c5888..db2817a9542341df422e5ca5d090b9a642938593 100644
--- a/src/Components/WebAssembly/WebAssembly/src/HotReload/HotReloadAgent.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/HotReload/HotReloadAgent.cs
@@ -1,7 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-// Based on the implementation in https://raw.githubusercontent.com/dotnet/sdk/4eaeb44f850903af2e0da8d74b7796f9df11c29d/src/BuiltInTools/DotNetDeltaApplier/HotReloadAgent.cs
+// Based on the implementation in https://raw.githubusercontent.com/dotnet/sdk/4a0473b29bfd4c7bdda6080d821788ee6d50c86b/src/BuiltInTools/DotNetDeltaApplier/HotReloadAgent.cs
 
 using System;
 using System.Collections.Concurrent;
@@ -187,8 +187,6 @@ namespace Microsoft.Extensions.HotReload
                 _handlerActions ??= GetMetadataUpdateHandlerActions();
                 var handlerActions = _handlerActions;
 
-                // TODO: Get types to pass in
-                Type[]? updatedTypes = null;
 
                 for (var i = 0; i < deltas.Count; i++)
                 {
@@ -206,6 +204,8 @@ namespace Microsoft.Extensions.HotReload
                     cachedDeltas.Add(item);
                 }
 
+                Type[]? updatedTypes = GetMetadataUpdateTypes(deltas);
+
                 handlerActions.ClearCache.ForEach(a => a(updatedTypes));
                 handlerActions.UpdateApplication.ForEach(a => a(updatedTypes));
 
@@ -217,6 +217,34 @@ namespace Microsoft.Extensions.HotReload
             }
         }
 
+        private Type[] GetMetadataUpdateTypes(IReadOnlyList<UpdateDelta> deltas)
+        {
+            List<Type>? types = null;
+
+            foreach (var delta in deltas)
+            {
+                var assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(assembly => TryGetModuleId(assembly) is Guid moduleId && moduleId == delta.ModuleId);
+                if (assembly is null)
+                {
+                    continue;
+                }
+
+                var assemblyTypes = assembly.GetTypes();
+
+                foreach (var updatedType in delta.UpdatedTypes ?? Array.Empty<int>())
+                {
+                    var type = assemblyTypes.FirstOrDefault(t => t.MetadataToken == updatedType);
+                    if (type != null)
+                    {
+                        types ??= new();
+                        types.Add(type);
+                    }
+                }
+            }
+
+            return types?.ToArray() ?? Type.EmptyTypes;
+        }
+
         public void ApplyDeltas(Assembly assembly, IReadOnlyList<UpdateDelta> deltas)
         {
             try
diff --git a/src/Components/WebAssembly/WebAssembly/src/HotReload/UpdateDelta.cs b/src/Components/WebAssembly/WebAssembly/src/HotReload/UpdateDelta.cs
index 7c1d5c634279aad5c1d503889312d6ec2e8ad00a..8d0dd1fb56eb184328faecfb423fd2db0a411329 100644
--- a/src/Components/WebAssembly/WebAssembly/src/HotReload/UpdateDelta.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/HotReload/UpdateDelta.cs
@@ -1,8 +1,6 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System;
-
 namespace Microsoft.Extensions.HotReload
 {
     internal sealed class UpdateDelta
@@ -12,5 +10,7 @@ namespace Microsoft.Extensions.HotReload
         public byte[] MetadataDelta { get; set; } = default!;
 
         public byte[] ILDelta { get; set; } = default!;
+
+        public int[]? UpdatedTypes { get; set; }
     }
 }
diff --git a/src/Components/WebAssembly/WebAssembly/src/HotReload/WebAssemblyHotReload.cs b/src/Components/WebAssembly/WebAssembly/src/HotReload/WebAssemblyHotReload.cs
index 68088b5c6c27b30e19e47b431730d4fc758eba98..271ea4cf638cf8d705147d493b57e0c4e54ee98a 100644
--- a/src/Components/WebAssembly/WebAssembly/src/HotReload/WebAssemblyHotReload.cs
+++ b/src/Components/WebAssembly/WebAssembly/src/HotReload/WebAssemblyHotReload.cs
@@ -1,11 +1,9 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
-using System;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Reflection;
-using System.Threading.Tasks;
 using Microsoft.AspNetCore.Components.WebAssembly.Services;
 using Microsoft.Extensions.HotReload;
 using Microsoft.JSInterop;
@@ -27,16 +25,10 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.HotReload
 
         internal static async Task InitializeAsync()
         {
-            // Determine if we're running under a hot reload environment (e.g. dotnet-watch).
-            // It's insufficient to know it the app can be hot reloaded (HotReloadFeature.IsSupported),
-            // since the hot-reload agent might be unavailable.
-            if (Environment.GetEnvironmentVariable("DOTNET_MODIFIABLE_ASSEMBLIES") != "debug")
-            {
-                return;
-            }
-
             _hotReloadAgent = new HotReloadAgent(m => Debug.WriteLine(m));
 
+            // Attempt to read previously applied hot reload deltas. dotnet-watch and VS will serve the script that can provide results from local-storage and
+            // the injected middleware if present.
             var jsObjectReference = (IJSUnmarshalledObjectReference)(await DefaultWebAssemblyJSRuntime.Instance.InvokeAsync<IJSObjectReference>("import", "./_framework/blazor-hotreload.js"));
             await jsObjectReference.InvokeUnmarshalled<Task<int>>("receiveHotReload");
         }