diff --git a/codegen/CMakeLists.txt b/codegen/CMakeLists.txt
index d80255d8..7609b209 100644
--- a/codegen/CMakeLists.txt
+++ b/codegen/CMakeLists.txt
@@ -4,8 +4,8 @@ project(Codegen LANGUAGES C CXX)
 set(CMAKE_CXX_STANDARD 17)
 
 add_subdirectory(Broma)
-add_subdirectory(../fmt ${CMAKE_CURRENT_BINARY_DIR}/fmt)
-add_subdirectory(../filesystem ${CMAKE_CURRENT_BINARY_DIR}/fs)
+add_subdirectory(../loader/include/Geode/external/fmt ${CMAKE_CURRENT_BINARY_DIR}/fmt)
+add_subdirectory(../loader/include/Geode/external/filesystem ${CMAKE_CURRENT_BINARY_DIR}/fs)
 
 file(GLOB SOURCES
 	${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
diff --git a/loader/launcher/windows/Bootstrapper.cpp b/loader/launcher/windows/Bootstrapper.cpp
index 26603796..593601a1 100644
--- a/loader/launcher/windows/Bootstrapper.cpp
+++ b/loader/launcher/windows/Bootstrapper.cpp
@@ -1,6 +1,6 @@
 #include <Windows.h>
 #include <iostream>
-#include "../../../filesystem/fs/filesystem.hpp"
+#include <fs/filesystem.hpp>
 
 void showError(std::string const& error) {
 	MessageBoxA(nullptr, error.c_str(), "Error Loading Geode", MB_ICONERROR);
diff --git a/loader/launcher/windows/CMakeLists.txt b/loader/launcher/windows/CMakeLists.txt
index 2604930f..03fa4a5e 100644
--- a/loader/launcher/windows/CMakeLists.txt
+++ b/loader/launcher/windows/CMakeLists.txt
@@ -39,3 +39,4 @@ set_target_properties(Bootstrapper PROPERTIES
 	RUNTIME_OUTPUT_DIRECTORY "${GEODE_BIN_PATH}/nightly"
 	ARCHIVE_OUTPUT_DIRECTORY "${GEODE_BIN_PATH}/nightly"
 )
+target_link_libraries(Bootstrapper PUBLIC filesystem)
diff --git a/loader/src/hooks/LoadingLayer.cpp b/loader/src/hooks/LoadingLayer.cpp
index 33e2fd6f..b40300a2 100644
--- a/loader/src/hooks/LoadingLayer.cpp
+++ b/loader/src/hooks/LoadingLayer.cpp
@@ -4,6 +4,7 @@
 USE_GEODE_NAMESPACE();
 
 #include <Geode/modify/LoadingLayer.hpp>
+#include <fmt/format.h>
 
 struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
     bool m_updatingResources;
@@ -18,8 +19,7 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
         auto count = Loader::get()->getAllMods().size();
 
         auto label = CCLabelBMFont::create(
-            CCString::createWithFormat("Geode: Loaded %lu mods", static_cast<unsigned long>(count))
-                ->getCString(),
+            fmt::format("Geode: Loaded {} mods", count).c_str(),
             "goldFont.fnt"
         );
         label->setPosition(winSize.width / 2, 30.f);
diff --git a/loader/src/hooks/MessageBoxFix.cpp b/loader/src/hooks/MessageBoxFix.cpp
index f35d7d2e..8540ecbf 100644
--- a/loader/src/hooks/MessageBoxFix.cpp
+++ b/loader/src/hooks/MessageBoxFix.cpp
@@ -1,6 +1,10 @@
+
+#include <Geode/DefaultInclude.hpp>
+
 #ifdef GEODE_IS_WINDOWS
-    #include <Geode/loader/Mod.hpp>
-    #include <Geode/modify/InternalMacros.hpp>
+
+#include <Geode/modify/InternalMacros.hpp>
+#include <Geode/loader/Mod.hpp>
 
 USE_GEODE_NAMESPACE();
 using geode::core::meta::x86::Thiscall;
@@ -15,12 +19,11 @@ static void __cdecl fixedErrorHandler(int code, char const* description) {
     log::critical("GLFW Error {}: {}", code, description);
     MessageBoxA(
         nullptr,
-        CCString::createWithFormat(
-            "GLFWError #%d: %s\nPlease contact the "
+        fmt::format(
+            "GLFWError #{}: {}\nPlease contact the "
             "Geode Development Team for more information.",
             code, description
-        )
-            ->getCString(),
+        ).c_str(),
         "OpenGL Error", MB_ICONERROR
     );
 }
diff --git a/loader/src/ui/internal/info/ModInfoLayer.cpp b/loader/src/ui/internal/info/ModInfoLayer.cpp
index ea9ae553..dc8ea7d8 100644
--- a/loader/src/ui/internal/info/ModInfoLayer.cpp
+++ b/loader/src/ui/internal/info/ModInfoLayer.cpp
@@ -758,7 +758,7 @@ CCNode* ModInfoLayer::createLogoSpr(Mod* mod, CCSize const& size) {
     }
     else {
         spr = CCSprite::create(
-            CCString::createWithFormat("%s/logo.png", mod->getID().c_str())->getCString()
+            fmt::format("{}/logo.png", mod->getID()).c_str()
         );
     }
     if (!spr) spr = CCSprite::createWithSpriteFrameName("no-logo.png"_spr);
diff --git a/loader/src/ui/nodes/BasedButtonSprite.cpp b/loader/src/ui/nodes/BasedButtonSprite.cpp
index e2e49068..b2e4dc56 100644
--- a/loader/src/ui/nodes/BasedButtonSprite.cpp
+++ b/loader/src/ui/nodes/BasedButtonSprite.cpp
@@ -1,12 +1,12 @@
 #include <Geode/ui/BasedButtonSprite.hpp>
+#include <Geode/loader/Mod.hpp>
 
 USE_GEODE_NAMESPACE();
 
 bool BasedButtonSprite::init(CCNode* ontop, int type, int size, int color) {
     if (!CCSprite::initWithSpriteFrameName(Mod::get()->expandSpriteName(
-            CCString::createWithFormat("GEODE_blank%02d_%02d_%02d.png", type, size, color)
-                ->getCString()
-        )))
+        fmt::format("GEODE_blank%02d_%02d_%02d.png", type, size, color).c_str()
+    )))
         return false;
 
     m_type = type;