diff --git a/Resources/ScriptLoader.cs b/Resources/ScriptLoader.cs
index c30c0ed7..4393d722 100644
--- a/Resources/ScriptLoader.cs
+++ b/Resources/ScriptLoader.cs
@@ -7,63 +7,13 @@
 using TweetDuck.Core.Other;
 #if DEBUG
 using System.Diagnostics;
+using System.Reflection;
+using TweetDuck.Core;
+using TweetDuck.Plugins;
 #endif
 
 namespace TweetDuck.Resources{
     static class ScriptLoader{
-        private const string UrlPrefix = "td:";
-
-        #if DEBUG
-        private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../")));
-        private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp"));
-        private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "Resources", "PostBuild.ps1");
-        
-        // TODO figure out hotswap support for plugins and scripts/plugins.* files
-
-        static ScriptLoader(){
-            if (File.Exists(HotSwapRebuildScript)){
-                Debug.WriteLine("Activating resource hot swap");
-
-                ResetHotSwap();
-                Application.ApplicationExit += (sender, args) => ResetHotSwap();
-            }
-        }
-
-        public static void HotSwap(){
-            if (!File.Exists(HotSwapRebuildScript)){
-                Debug.WriteLine("Failed resource hot swap, missing rebuild script: "+HotSwapRebuildScript);
-                return;
-            }
-            
-            ResetHotSwap();
-            Directory.CreateDirectory(HotSwapTargetDir);
-
-            using(Process process = Process.Start(new ProcessStartInfo{
-                FileName = "powershell",
-                Arguments = $"-ExecutionPolicy Unrestricted -File \"{HotSwapRebuildScript}\" \"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"{Program.VersionTag}\"",
-                WindowStyle = ProcessWindowStyle.Hidden
-            })){
-                // ReSharper disable once PossibleNullReferenceException
-                if (!process.WaitForExit(8000)){
-                    Debug.WriteLine("Failed resource hot swap, script did not finish in time");
-                }
-                else if (process.ExitCode != 0){
-                    Debug.WriteLine("Failed resource hot swap, script exited with code "+process.ExitCode);
-                }
-            }
-        }
-
-        private static void ResetHotSwap(){
-            try{
-                Directory.Delete(HotSwapTargetDir, true);
-            }catch(DirectoryNotFoundException){}
-        }
-
-        private static string FixPathSlash(string path){
-            return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)+'\\';
-        }
-        #endif
-        
         public static string LoadResource(string name, bool silent = false, Control sync = null){
             try{
                 string path = Program.ScriptPath;
@@ -110,7 +60,7 @@ public static bool ExecuteFile(IFrame frame, string file, Control sync = null){
 
         public static void ExecuteScript(IFrame frame, string script, string identifier){
             if (script != null){
-                frame.ExecuteJavaScriptAsync(script, UrlPrefix+identifier, 1);
+                frame.ExecuteJavaScriptAsync(script, "td:"+identifier, 1);
             }
         }
 
@@ -130,5 +80,77 @@ private static void ShowLoadError(bool silent, Control sync, string message){
                 sync.InvokeSafe(() => FormMessage.Error("Resource Error", message, FormMessage.OK));
             }
         }
+        
+        #if DEBUG
+        private static readonly string HotSwapProjectRoot = FixPathSlash(Path.GetFullPath(Path.Combine(Program.ProgramPath, "../../../")));
+        private static readonly string HotSwapTargetDir = FixPathSlash(Path.Combine(HotSwapProjectRoot, "bin", "tmp"));
+        private static readonly string HotSwapRebuildScript = Path.Combine(HotSwapProjectRoot, "Resources", "PostBuild.ps1");
+
+        static ScriptLoader(){
+            if (File.Exists(HotSwapRebuildScript)){
+                Debug.WriteLine("Activating resource hot swap");
+
+                ResetHotSwap();
+                Application.ApplicationExit += (sender, args) => ResetHotSwap();
+            }
+        }
+
+        public static void HotSwap(){
+            if (!File.Exists(HotSwapRebuildScript)){
+                Debug.WriteLine("Failed resource hot swap, missing rebuild script: "+HotSwapRebuildScript);
+                return;
+            }
+            
+            ResetHotSwap();
+            Directory.CreateDirectory(HotSwapTargetDir);
+
+            using(Process process = Process.Start(new ProcessStartInfo{
+                FileName = "powershell",
+                Arguments = $"-ExecutionPolicy Unrestricted -File \"{HotSwapRebuildScript}\" \"{HotSwapTargetDir}\\\" \"{HotSwapProjectRoot}\\\" \"{Program.VersionTag}\"",
+                WindowStyle = ProcessWindowStyle.Hidden
+            })){
+                // ReSharper disable once PossibleNullReferenceException
+                if (!process.WaitForExit(8000)){
+                    Debug.WriteLine("Failed resource hot swap, script did not finish in time");
+                    return;
+                }
+                else if (process.ExitCode != 0){
+                    Debug.WriteLine("Failed resource hot swap, script exited with code "+process.ExitCode);
+                    return;
+                }
+            }
+
+            // Force update plugin manager setup scripts
+
+            string newPluginRoot = Path.Combine(HotSwapTargetDir, "plugins");
+            
+            const BindingFlags flagsInstance = BindingFlags.Instance | BindingFlags.NonPublic;
+            const BindingFlags flagsStatic = BindingFlags.Static | BindingFlags.NonPublic;
+
+            Type typePluginManager = typeof(PluginManager);
+            Type typeFormBrowser = typeof(FormBrowser);
+
+            // ReSharper disable PossibleNullReferenceException
+            object pluginSetupScripts = typePluginManager.GetMethod("LoadSetupScripts", flagsStatic).Invoke(null, new object[0]);
+            typePluginManager.GetField("PluginSetupScripts", flagsStatic).SetValue(null, pluginSetupScripts);
+            
+            object instPluginManager = typeFormBrowser.GetField("plugins", flagsInstance).GetValue(FormManager.TryFind<FormBrowser>());
+            typePluginManager.GetField("rootPath", flagsInstance).SetValue(instPluginManager, newPluginRoot);
+
+            Debug.WriteLine("Reloading hot swapped plugins...");
+            ((PluginManager)instPluginManager).Reload();
+            // ReSharper restore PossibleNullReferenceException
+        }
+
+        private static void ResetHotSwap(){
+            try{
+                Directory.Delete(HotSwapTargetDir, true);
+            }catch(DirectoryNotFoundException){}
+        }
+
+        private static string FixPathSlash(string path){
+            return path.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)+'\\';
+        }
+        #endif
     }
 }
diff --git a/Resources/Scripts/code.js b/Resources/Scripts/code.js
index 9b809acc..8aa6e3a7 100644
--- a/Resources/Scripts/code.js
+++ b/Resources/Scripts/code.js
@@ -1369,6 +1369,8 @@
       window.gc && window.gc();
       window.location.reload();
     });
+    
+    window.TDGF_reload = function(){}; // redefine to prevent reloading multiple times
   };
   
   if (window.TD_SESSION && window.TD_SESSION.gc){