From ba95ee54abf4905d38f3563881a1643f102993b3 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Tue, 21 Mar 2023 20:14:46 -0300
Subject: [PATCH] Revert "Use source generated json serializers in order to
 improve code trimming (#4094)" (#4576)

This reverts commit 4ce4299ca2a6b11332f2341c69f40efd7205282f.
---
 .editorconfig                                 |   4 -
 ARMeilleure/Decoders/IOpCode32Exception.cs    |   9 +-
 Ryujinx.Ava/Common/Locale/LocaleManager.cs    |   2 +-
 Ryujinx.Ava/Modules/Updater/Updater.cs        |  24 +-
 Ryujinx.Ava/UI/Models/Amiibo.cs               |  72 ++++
 .../UI/ViewModels/AboutWindowViewModel.cs     |   2 +-
 .../UI/ViewModels/AmiiboWindowViewModel.cs    |  35 +-
 .../ViewModels/ControllerSettingsViewModel.cs |   9 +-
 .../DownloadableContentManagerViewModel.cs    |  10 +-
 .../UI/ViewModels/TitleUpdateViewModel.cs     | 360 +++++++++---------
 .../UI/Views/Main/MainMenuBarView.axaml.cs    |   2 +-
 Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs  |   6 +-
 .../UI/Windows/TitleUpdateWindow.axaml.cs     |   3 +
 .../Configuration/AspectRatioExtensions.cs    |   6 +-
 .../Configuration/BackendThreading.cs         |   6 +-
 ...ownloadableContentJsonSerializerContext.cs |  11 -
 .../Configuration/GraphicsBackend.cs          |   6 +-
 .../Configuration/GraphicsDebugLevel.cs       |   4 -
 .../JsonMotionConfigControllerConverter.cs    |  13 +-
 .../Motion/MotionConfigController.cs          |   5 +-
 .../MotionConfigJsonSerializerContext.cs      |  12 -
 .../Motion/MotionInputBackendType.cs          |   6 +-
 .../Configuration/Hid/ControllerType.cs       |   5 +-
 .../Configuration/Hid/InputBackendType.cs     |   6 +-
 .../Configuration/Hid/InputConfig.cs          |   2 -
 .../Hid/InputConfigJsonSerializerContext.cs   |  14 -
 .../Hid/JsonInputConfigConverter.cs           |  13 +-
 .../Configuration/Hid/PlayerIndex.cs          |   4 -
 .../Configuration/MemoryManagerMode.cs        |   6 +-
 ...itleUpdateMetadataJsonSerializerContext.cs |  10 -
 .../Logging/Formatters/DefaultLogFormatter.cs |  54 ++-
 .../Formatters/DynamicObjectFormatter.cs      |  84 ----
 Ryujinx.Common/Logging/LogClass.cs            |   4 -
 Ryujinx.Common/Logging/LogEventArgs.cs        |  10 +-
 Ryujinx.Common/Logging/LogEventArgsJson.cs    |  30 --
 .../Logging/LogEventJsonSerializerContext.cs  |   9 -
 Ryujinx.Common/Logging/LogLevel.cs            |   4 -
 .../Logging/Targets/JsonLogTarget.cs          |  12 +-
 Ryujinx.Common/Utilities/CommonJsonContext.cs |  11 -
 Ryujinx.Common/Utilities/JsonHelper.cs        | 122 +++---
 .../Utilities/TypedStringEnumConverter.cs     |  34 --
 Ryujinx.HLE/HOS/ApplicationLoader.cs          |  12 +-
 .../Account/Acc/AccountSaveDataManager.cs     |  30 +-
 .../Acc/ProfilesJsonSerializerContext.cs      |  11 -
 .../Account/Acc/Types/AccountState.cs         |   4 -
 .../Account/Acc/Types/ProfilesJson.cs         |  10 -
 .../Account/Acc/Types/UserProfileJson.cs      |  12 -
 .../Nfc/Nfp/AmiiboJsonSerializerContext.cs    |  10 -
 .../HOS/Services/Nfc/Nfp/VirtualAmiibo.cs     |  10 +-
 Ryujinx.Headless.SDL2/Program.cs              |   7 +-
 .../App/ApplicationJsonSerializerContext.cs   |  10 -
 Ryujinx.Ui.Common/App/ApplicationLibrary.cs   |  14 +-
 .../Configuration/AudioBackend.cs             |   6 +-
 .../Configuration/ConfigurationFileFormat.cs  |  12 +-
 .../ConfigurationFileFormatSettings.cs        |   9 -
 .../ConfigurationJsonSerializerContext.cs     |  10 -
 .../Configuration/ConfigurationState.cs       |   5 +-
 .../Configuration/System/Language.cs          |   6 +-
 .../Configuration/System/Region.cs            |   6 +-
 Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs  |  57 ---
 .../Models/Amiibo/AmiiboApiGamesSwitch.cs     |  15 -
 .../Models/Amiibo/AmiiboApiUsage.cs           |  12 -
 Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs |  14 -
 .../Amiibo/AmiiboJsonSerializerContext.cs     |   9 -
 .../Github/GithubReleaseAssetJsonResponse.cs  |   9 -
 .../Github/GithubReleasesJsonResponse.cs      |  10 -
 .../GithubReleasesJsonSerializerContext.cs    |   9 -
 Ryujinx/Modules/Updater/Updater.cs            |  26 +-
 Ryujinx/Ui/Windows/AboutWindow.cs             |   2 +-
 Ryujinx/Ui/Windows/AmiiboWindow.cs            |  65 +++-
 Ryujinx/Ui/Windows/ControllerWindow.cs        |  11 +-
 Ryujinx/Ui/Windows/DlcWindow.cs               |  15 +-
 Ryujinx/Ui/Windows/TitleUpdateWindow.cs       |  15 +-
 73 files changed, 608 insertions(+), 886 deletions(-)
 create mode 100644 Ryujinx.Ava/UI/Models/Amiibo.cs
 delete mode 100644 Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs
 delete mode 100644 Ryujinx.Common/Logging/LogEventArgsJson.cs
 delete mode 100644 Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Common/Utilities/CommonJsonContext.cs
 delete mode 100644 Ryujinx.Common/Utilities/TypedStringEnumConverter.cs
 delete mode 100644 Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs
 delete mode 100644 Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs
 delete mode 100644 Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs
 delete mode 100644 Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs
 delete mode 100644 Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs
 delete mode 100644 Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs

diff --git a/.editorconfig b/.editorconfig
index 8a3054287..9e00e3bae 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -63,10 +63,6 @@ dotnet_code_quality_unused_parameters = all:suggestion
 
 #### C# Coding Conventions ####
 
-# Namespace preferences
-csharp_style_namespace_declarations = block_scoped:warning
-resharper_csharp_namespace_body = block_scoped
-
 # var preferences
 csharp_style_var_elsewhere = false:silent
 csharp_style_var_for_built_in_types = false:silent
diff --git a/ARMeilleure/Decoders/IOpCode32Exception.cs b/ARMeilleure/Decoders/IOpCode32Exception.cs
index 8f0fb81a0..82819bddd 100644
--- a/ARMeilleure/Decoders/IOpCode32Exception.cs
+++ b/ARMeilleure/Decoders/IOpCode32Exception.cs
@@ -1,7 +1,6 @@
-namespace ARMeilleure.Decoders
+namespace ARMeilleure.Decoders;
+
+interface IOpCode32Exception
 {
-    interface IOpCode32Exception
-    {
-        int Id { get; }
-    }
+    int Id { get; }
 }
\ No newline at end of file
diff --git a/Ryujinx.Ava/Common/Locale/LocaleManager.cs b/Ryujinx.Ava/Common/Locale/LocaleManager.cs
index 464ab780d..1374bfee1 100644
--- a/Ryujinx.Ava/Common/Locale/LocaleManager.cs
+++ b/Ryujinx.Ava/Common/Locale/LocaleManager.cs
@@ -130,7 +130,7 @@ namespace Ryujinx.Ava.Common.Locale
         {
             var    localeStrings = new Dictionary<LocaleKeys, string>();
             string languageJson  = EmbeddedResources.ReadAllText($"Ryujinx.Ava/Assets/Locales/{languageCode}.json");
-            var    strings       = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary);
+            var    strings       = JsonHelper.Deserialize<Dictionary<string, string>>(languageJson);
 
             foreach (var item in strings)
             {
diff --git a/Ryujinx.Ava/Modules/Updater/Updater.cs b/Ryujinx.Ava/Modules/Updater/Updater.cs
index c58575284..e89abd1da 100644
--- a/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/Ryujinx.Ava/Modules/Updater/Updater.cs
@@ -4,14 +4,13 @@ using FluentAvalonia.UI.Controls;
 using ICSharpCode.SharpZipLib.GZip;
 using ICSharpCode.SharpZipLib.Tar;
 using ICSharpCode.SharpZipLib.Zip;
+using Newtonsoft.Json.Linq;
 using Ryujinx.Ava;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.UI.Helpers;
 using Ryujinx.Common;
 using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
 using Ryujinx.Ui.Common.Helper;
-using Ryujinx.Ui.Common.Models.Github;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
@@ -32,7 +31,6 @@ namespace Ryujinx.Modules
     internal static class Updater
     {
         private const string GitHubApiURL = "https://api.github.com";
-        private static readonly GithubReleasesJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
 
         private static readonly string HomeDir          = AppDomain.CurrentDomain.BaseDirectory;
         private static readonly string UpdateDir        = Path.Combine(Path.GetTempPath(), "Ryujinx", "update");
@@ -101,16 +99,22 @@ namespace Ryujinx.Modules
 
                 string  buildInfoURL = $"{GitHubApiURL}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
                 string  fetchedJson  = await jsonClient.GetStringAsync(buildInfoURL);
-                var fetched = JsonHelper.Deserialize(fetchedJson, SerializerContext.GithubReleasesJsonResponse);
-                _buildVer = fetched.Name;
+                JObject jsonRoot     = JObject.Parse(fetchedJson);
+                JToken  assets       = jsonRoot["assets"];
 
-                foreach (var asset in fetched.Assets)
+                _buildVer = (string)jsonRoot["name"];
+
+                foreach (JToken asset in assets)
                 {
-                    if (asset.Name.StartsWith("test-ava-ryujinx") && asset.Name.EndsWith(_platformExt))
-                    {
-                        _buildUrl = asset.BrowserDownloadUrl;
+                    string assetName   = (string)asset["name"];
+                    string assetState  = (string)asset["state"];
+                    string downloadURL = (string)asset["browser_download_url"];
 
-                        if (asset.State != "uploaded")
+                    if (assetName.StartsWith("test-ava-ryujinx") && assetName.EndsWith(_platformExt))
+                    {
+                        _buildUrl = downloadURL;
+
+                        if (assetState != "uploaded")
                         {
                             if (showVersionUpToDate)
                             {
diff --git a/Ryujinx.Ava/UI/Models/Amiibo.cs b/Ryujinx.Ava/UI/Models/Amiibo.cs
new file mode 100644
index 000000000..d0ccafd08
--- /dev/null
+++ b/Ryujinx.Ava/UI/Models/Amiibo.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace Ryujinx.Ava.UI.Models
+{
+    public class Amiibo
+    {
+        public struct AmiiboJson
+        {
+            [JsonPropertyName("amiibo")] public List<AmiiboApi> Amiibo { get; set; }
+            [JsonPropertyName("lastUpdated")] public DateTime LastUpdated { get; set; }
+        }
+
+        public struct AmiiboApi
+        {
+            [JsonPropertyName("name")] public string Name { get; set; }
+            [JsonPropertyName("head")] public string Head { get; set; }
+            [JsonPropertyName("tail")] public string Tail { get; set; }
+            [JsonPropertyName("image")] public string Image { get; set; }
+            [JsonPropertyName("amiiboSeries")] public string AmiiboSeries { get; set; }
+            [JsonPropertyName("character")] public string Character { get; set; }
+            [JsonPropertyName("gameSeries")] public string GameSeries { get; set; }
+            [JsonPropertyName("type")] public string Type { get; set; }
+
+            [JsonPropertyName("release")] public Dictionary<string, string> Release { get; set; }
+
+            [JsonPropertyName("gamesSwitch")] public List<AmiiboApiGamesSwitch> GamesSwitch { get; set; }
+
+            public override string ToString()
+            {
+                return Name;
+            }
+
+            public string GetId()
+            {
+                return Head + Tail;
+            }
+
+            public override bool Equals(object obj)
+            {
+                if (obj is AmiiboApi amiibo)
+                {
+                    return amiibo.Head + amiibo.Tail == Head + Tail;
+                }
+
+                return false;
+            }
+
+            public override int GetHashCode()
+            {
+                return base.GetHashCode();
+            }
+        }
+
+        public class AmiiboApiGamesSwitch
+        {
+            [JsonPropertyName("amiiboUsage")] public List<AmiiboApiUsage> AmiiboUsage { get; set; }
+
+            [JsonPropertyName("gameID")] public List<string> GameId { get; set; }
+
+            [JsonPropertyName("gameName")] public string GameName { get; set; }
+        }
+
+        public class AmiiboApiUsage
+        {
+            [JsonPropertyName("Usage")] public string Usage { get; set; }
+
+            [JsonPropertyName("write")] public bool Write { get; set; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs b/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
index 9b5422adf..872c1a37f 100644
--- a/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/AboutWindowViewModel.cs
@@ -122,7 +122,7 @@ namespace Ryujinx.Ava.UI.ViewModels
             {
                 string patreonJsonString = await httpClient.GetStringAsync("https://patreon.ryujinx.org/");
 
-                Supporters = string.Join(", ", JsonHelper.Deserialize(patreonJsonString, CommonJsonContext.Default.StringArray) + "\n\n");
+                Supporters = string.Join(", ", JsonHelper.Deserialize<string[]>(patreonJsonString)) + "\n\n";
             }
             catch
             {
diff --git a/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs b/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
index 090c13a97..5311318c5 100644
--- a/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/AmiiboWindowViewModel.cs
@@ -4,11 +4,11 @@ using Avalonia.Media.Imaging;
 using Avalonia.Threading;
 using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.Models;
 using Ryujinx.Ava.UI.Windows;
 using Ryujinx.Common;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Utilities;
-using Ryujinx.Ui.Common.Models.Amiibo;
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
@@ -17,7 +17,6 @@ using System.Linq;
 using System.Net.Http;
 using System.Text;
 using System.Threading.Tasks;
-using AmiiboJsonSerializerContext = Ryujinx.Ui.Common.Models.Amiibo.AmiiboJsonSerializerContext;
 
 namespace Ryujinx.Ava.UI.ViewModels
 {
@@ -32,8 +31,8 @@ namespace Ryujinx.Ava.UI.ViewModels
         private readonly StyleableWindow _owner;
 
         private Bitmap _amiiboImage;
-        private List<AmiiboApi> _amiiboList;
-        private AvaloniaList<AmiiboApi> _amiibos;
+        private List<Amiibo.AmiiboApi> _amiiboList;
+        private AvaloniaList<Amiibo.AmiiboApi> _amiibos;
         private ObservableCollection<string> _amiiboSeries;
 
         private int _amiiboSelectedIndex;
@@ -42,8 +41,6 @@ namespace Ryujinx.Ava.UI.ViewModels
         private bool _showAllAmiibo;
         private bool _useRandomUuid;
         private string _usage;
-        
-        private static readonly AmiiboJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
 
         public AmiiboWindowViewModel(StyleableWindow owner, string lastScannedAmiiboId, string titleId)
         {
@@ -55,9 +52,9 @@ namespace Ryujinx.Ava.UI.ViewModels
             Directory.CreateDirectory(Path.Join(AppDataManager.BaseDirPath, "system", "amiibo"));
 
             _amiiboJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "amiibo", "Amiibo.json");
-            _amiiboList = new List<AmiiboApi>();
+            _amiiboList = new List<Amiibo.AmiiboApi>();
             _amiiboSeries = new ObservableCollection<string>();
-            _amiibos = new AvaloniaList<AmiiboApi>();
+            _amiibos = new AvaloniaList<Amiibo.AmiiboApi>();
 
             _amiiboLogoBytes = EmbeddedResources.Read("Ryujinx.Ui.Common/Resources/Logo_Amiibo.png");
 
@@ -97,7 +94,7 @@ namespace Ryujinx.Ava.UI.ViewModels
             }
         }
 
-        public AvaloniaList<AmiiboApi> AmiiboList
+        public AvaloniaList<Amiibo.AmiiboApi> AmiiboList
         {
             get => _amiibos;
             set
@@ -190,9 +187,9 @@ namespace Ryujinx.Ava.UI.ViewModels
 
             if (File.Exists(_amiiboJsonPath))
             {
-                amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath);
+                amiiboJsonString = File.ReadAllText(_amiiboJsonPath);
 
-                if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).LastUpdated))
+                if (await NeedsUpdate(JsonHelper.Deserialize<Amiibo.AmiiboJson>(amiiboJsonString).LastUpdated))
                 {
                     amiiboJsonString = await DownloadAmiiboJson();
                 }
@@ -209,7 +206,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                 }
             }
 
-            _amiiboList = JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).Amiibo;
+            _amiiboList = JsonHelper.Deserialize<Amiibo.AmiiboJson>(amiiboJsonString).Amiibo;
             _amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
 
             ParseAmiiboData();
@@ -226,7 +223,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                 {
                     if (!ShowAllAmiibo)
                     {
-                        foreach (AmiiboApiGamesSwitch game in _amiiboList[i].GamesSwitch)
+                        foreach (Amiibo.AmiiboApiGamesSwitch game in _amiiboList[i].GamesSwitch)
                         {
                             if (game != null)
                             {
@@ -258,7 +255,7 @@ namespace Ryujinx.Ava.UI.ViewModels
 
         private void SelectLastScannedAmiibo()
         {
-            AmiiboApi scanned = _amiiboList.FirstOrDefault(amiibo => amiibo.GetId() == LastScannedAmiiboId);
+            Amiibo.AmiiboApi scanned = _amiiboList.FirstOrDefault(amiibo => amiibo.GetId() == LastScannedAmiiboId);
 
             SeriesSelectedIndex = AmiiboSeries.IndexOf(scanned.AmiiboSeries);
             AmiiboSelectedIndex = AmiiboList.IndexOf(scanned);
@@ -273,7 +270,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                 return;
             }
 
-            List<AmiiboApi> amiiboSortedList = _amiiboList
+            List<Amiibo.AmiiboApi> amiiboSortedList = _amiiboList
                 .Where(amiibo => amiibo.AmiiboSeries == _amiiboSeries[SeriesSelectedIndex])
                 .OrderBy(amiibo => amiibo.Name).ToList();
 
@@ -283,7 +280,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                 {
                     if (!_showAllAmiibo)
                     {
-                        foreach (AmiiboApiGamesSwitch game in amiiboSortedList[i].GamesSwitch)
+                        foreach (Amiibo.AmiiboApiGamesSwitch game in amiiboSortedList[i].GamesSwitch)
                         {
                             if (game != null)
                             {
@@ -317,7 +314,7 @@ namespace Ryujinx.Ava.UI.ViewModels
                 return;
             }
 
-            AmiiboApi selected = _amiibos[_amiiboSelectedIndex];
+            Amiibo.AmiiboApi selected = _amiibos[_amiiboSelectedIndex];
 
             string imageUrl = _amiiboList.FirstOrDefault(amiibo => amiibo.Equals(selected)).Image;
 
@@ -329,11 +326,11 @@ namespace Ryujinx.Ava.UI.ViewModels
                 {
                     bool writable = false;
 
-                    foreach (AmiiboApiGamesSwitch item in _amiiboList[i].GamesSwitch)
+                    foreach (Amiibo.AmiiboApiGamesSwitch item in _amiiboList[i].GamesSwitch)
                     {
                         if (item.GameId.Contains(TitleId))
                         {
-                            foreach (AmiiboApiUsage usageItem in item.AmiiboUsage)
+                            foreach (Amiibo.AmiiboApiUsage usageItem in item.AmiiboUsage)
                             {
                                 usageString += Environment.NewLine +
                                                $"- {usageItem.Usage.Replace("/", Environment.NewLine + "-")}";
diff --git a/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs b/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs
index dd261b103..35256b3b5 100644
--- a/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/ControllerSettingsViewModel.cs
@@ -51,8 +51,6 @@ namespace Ryujinx.Ava.UI.ViewModels
         private bool _isLoaded;
         private readonly UserControl _owner;
 
-        private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         public IGamepadDriver AvaloniaKeyboardDriver { get; }
         public IGamepad SelectedGamepad { get; private set; }
 
@@ -708,7 +706,10 @@ namespace Ryujinx.Ava.UI.ViewModels
 
                 try
                 {
-                    config = JsonHelper.DeserializeFromFile(path, SerializerContext.InputConfig);
+                    using (Stream stream = File.OpenRead(path))
+                    {
+                        config = JsonHelper.Deserialize<InputConfig>(stream);
+                    }
                 }
                 catch (JsonException) { }
                 catch (InvalidOperationException)
@@ -774,7 +775,7 @@ namespace Ryujinx.Ava.UI.ViewModels
 
                     config.ControllerType = Controllers[_controller].Type;
 
-                    string jsonString = JsonHelper.Serialize(config, SerializerContext.InputConfig);
+                    string jsonString = JsonHelper.Serialize(config, true);
 
                     await File.WriteAllTextAsync(path, jsonString);
 
diff --git a/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs b/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
index 1d7da9a40..e5e4f66b5 100644
--- a/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/DownloadableContentManagerViewModel.cs
@@ -21,6 +21,7 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Text;
 using System.Threading.Tasks;
 using Path = System.IO.Path;
 
@@ -40,8 +41,6 @@ namespace Ryujinx.Ava.UI.ViewModels
         private ulong _titleId;
         private string _titleName;
 
-        private static readonly DownloadableContentJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         public AvaloniaList<DownloadableContentModel> DownloadableContents
         {
             get => _downloadableContents;
@@ -101,7 +100,7 @@ namespace Ryujinx.Ava.UI.ViewModels
 
             try
             {
-                _downloadableContentContainerList = JsonHelper.DeserializeFromFile(_downloadableContentJsonPath, SerializerContext.ListDownloadableContentContainer);
+                _downloadableContentContainerList = JsonHelper.DeserializeFromFile<List<DownloadableContentContainer>>(_downloadableContentJsonPath);
             }
             catch
             {
@@ -331,7 +330,10 @@ namespace Ryujinx.Ava.UI.ViewModels
                 _downloadableContentContainerList.Add(container);
             }
 
-            JsonHelper.SerializeToFile(_downloadableContentJsonPath, _downloadableContentContainerList, SerializerContext.ListDownloadableContentContainer);
+            using (FileStream downloadableContentJsonStream = File.Create(_downloadableContentJsonPath, 4096, FileOptions.WriteThrough))
+            {
+                downloadableContentJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_downloadableContentContainerList, true)));
+            }
         }
 
     }
diff --git a/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs b/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
index ed5b5eacf..dd9e1b961 100644
--- a/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
+++ b/Ryujinx.Ava/UI/ViewModels/TitleUpdateViewModel.cs
@@ -25,228 +25,226 @@ using System.Text;
 using Path = System.IO.Path;
 using SpanHelpers = LibHac.Common.SpanHelpers;
 
-namespace Ryujinx.Ava.UI.ViewModels
+namespace Ryujinx.Ava.UI.ViewModels;
+
+public class TitleUpdateViewModel : BaseModel
 {
-    public class TitleUpdateViewModel : BaseModel
+    public TitleUpdateMetadata _titleUpdateWindowData;
+    public readonly string     _titleUpdateJsonPath;
+    private VirtualFileSystem  _virtualFileSystem { get; }
+    private ulong              _titleId           { get; }
+    private string             _titleName         { get; }
+
+    private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
+    private AvaloniaList<object> _views = new();
+    private object _selectedUpdate;
+
+    public AvaloniaList<TitleUpdateModel> TitleUpdates
     {
-        public TitleUpdateMetadata _titleUpdateWindowData;
-        public readonly string     _titleUpdateJsonPath;
-        private VirtualFileSystem  _virtualFileSystem { get; }
-        private ulong              _titleId           { get; }
-        private string             _titleName         { get; }
-
-        private AvaloniaList<TitleUpdateModel> _titleUpdates = new();
-        private AvaloniaList<object> _views = new();
-        private object _selectedUpdate;
-    
-        private static readonly TitleUpdateMetadataJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
-        public AvaloniaList<TitleUpdateModel> TitleUpdates
+        get => _titleUpdates;
+        set
         {
-            get => _titleUpdates;
-            set
-            {
-                _titleUpdates = value;
-                OnPropertyChanged();
-            }
+            _titleUpdates = value;
+            OnPropertyChanged();
         }
+    }
 
-        public AvaloniaList<object> Views
+    public AvaloniaList<object> Views
+    {
+        get => _views;
+        set
         {
-            get => _views;
-            set
-            {
-                _views = value;
-                OnPropertyChanged();
-            }
+            _views = value;
+            OnPropertyChanged();
         }
+    }
 
-        public object SelectedUpdate
+    public object SelectedUpdate
+    {
+        get => _selectedUpdate;
+        set
         {
-            get => _selectedUpdate;
-            set
-            {
-                _selectedUpdate = value;
-                OnPropertyChanged();
-            }
+            _selectedUpdate = value;
+            OnPropertyChanged();
         }
+    }
 
-        public TitleUpdateViewModel(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
+    public TitleUpdateViewModel(VirtualFileSystem virtualFileSystem, ulong titleId, string titleName)
+    {
+        _virtualFileSystem = virtualFileSystem;
+
+        _titleId   = titleId;
+        _titleName = titleName;
+
+        _titleUpdateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "updates.json");
+
+        try
         {
-            _virtualFileSystem = virtualFileSystem;
-
-            _titleId   = titleId;
-            _titleName = titleName;
-
-            _titleUpdateJsonPath = Path.Combine(AppDataManager.GamesDirPath, titleId.ToString("x16"), "updates.json");
-
-            try
-            {
-                _titleUpdateWindowData = JsonHelper.DeserializeFromFile(_titleUpdateJsonPath, SerializerContext.TitleUpdateMetadata);
-            }
-            catch
-            {
-                Logger.Warning?.Print(LogClass.Application, $"Failed to deserialize title update data for {_titleId} at {_titleUpdateJsonPath}");
-
-                _titleUpdateWindowData = new TitleUpdateMetadata
-                {
-                    Selected = "",
-                    Paths    = new List<string>()
-                };
-
-                Save();
-            }
-
-            LoadUpdates();
+            _titleUpdateWindowData = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(_titleUpdateJsonPath);
         }
-
-        private void LoadUpdates()
+        catch
         {
-            foreach (string path in _titleUpdateWindowData.Paths)
+            Logger.Warning?.Print(LogClass.Application, $"Failed to deserialize title update data for {_titleId} at {_titleUpdateJsonPath}");
+
+            _titleUpdateWindowData = new TitleUpdateMetadata
             {
-                AddUpdate(path);
-            }
+                Selected = "",
+                Paths    = new List<string>()
+            };
 
-            TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected, null);
-
-            SelectedUpdate = selected;
-
-            // NOTE: Save the list again to remove leftovers.
             Save();
-            SortUpdates();
         }
 
-        public void SortUpdates()
+        LoadUpdates();
+    }
+
+    private void LoadUpdates()
+    {
+        foreach (string path in _titleUpdateWindowData.Paths)
         {
-            var list = TitleUpdates.ToList();
+            AddUpdate(path);
+        }
 
-            list.Sort((first, second) =>
+        TitleUpdateModel selected = TitleUpdates.FirstOrDefault(x => x.Path == _titleUpdateWindowData.Selected, null);
+
+        SelectedUpdate = selected;
+
+        // NOTE: Save the list again to remove leftovers.
+        Save();
+
+        SortUpdates();
+    }
+
+    public void SortUpdates()
+    {
+        var list = TitleUpdates.ToList();
+
+        list.Sort((first, second) =>
+        {
+            if (string.IsNullOrEmpty(first.Control.DisplayVersionString.ToString()))
             {
-                if (string.IsNullOrEmpty(first.Control.DisplayVersionString.ToString()))
-                {
-                    return -1;
-                }
-                else if (string.IsNullOrEmpty(second.Control.DisplayVersionString.ToString()))
-                {
-                    return 1;
-                }
+                return -1;
+            }
+            else if (string.IsNullOrEmpty(second.Control.DisplayVersionString.ToString()))
+            {
+                return 1;
+            }
 
-                return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
-            });
+            return Version.Parse(first.Control.DisplayVersionString.ToString()).CompareTo(Version.Parse(second.Control.DisplayVersionString.ToString())) * -1;
+        });
 
-            Views.Clear();
-            Views.Add(new BaseModel());
-            Views.AddRange(list);
+        Views.Clear();
+        Views.Add(new BaseModel());
+        Views.AddRange(list);
 
-            if (SelectedUpdate == null)
+        if (SelectedUpdate == null)
+        {
+            SelectedUpdate = Views[0];
+        }
+        else if (!TitleUpdates.Contains(SelectedUpdate))
+        {
+            if (Views.Count > 1)
+            {
+                SelectedUpdate = Views[1];
+            }
+            else
             {
                 SelectedUpdate = Views[0];
             }
-            else if (!TitleUpdates.Contains(SelectedUpdate))
+        }
+    }
+
+    private void AddUpdate(string path)
+    {
+        if (File.Exists(path) && TitleUpdates.All(x => x.Path != path))
+        {
+            using FileStream file = new(path, FileMode.Open, FileAccess.Read);
+
+            try
             {
-                if (Views.Count > 1)
+                (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(_virtualFileSystem, new PartitionFileSystem(file.AsStorage()), _titleId.ToString("x16"), 0);
+
+                if (controlNca != null && patchNca != null)
                 {
-                    SelectedUpdate = Views[1];
+                    ApplicationControlProperty controlData = new();
+
+                    using UniqueRef<IFile> nacpFile = new();
+
+                    controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
+                    nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
+
+                    TitleUpdates.Add(new TitleUpdateModel(controlData, path));
                 }
                 else
-                {
-                    SelectedUpdate = Views[0];
-                }
-            }
-        }
-
-        private void AddUpdate(string path)
-        {
-            if (File.Exists(path) && TitleUpdates.All(x => x.Path != path))
-            {
-                using FileStream file = new(path, FileMode.Open, FileAccess.Read);
-
-                try
-                {
-                    (Nca patchNca, Nca controlNca) = ApplicationLoader.GetGameUpdateDataFromPartition(_virtualFileSystem, new PartitionFileSystem(file.AsStorage()), _titleId.ToString("x16"), 0);
-
-                    if (controlNca != null && patchNca != null)
-                    {
-                        ApplicationControlProperty controlData = new();
-
-                        using UniqueRef<IFile> nacpFile = new();
-
-                        controlNca.OpenFileSystem(NcaSectionType.Data, IntegrityCheckLevel.None).OpenFile(ref nacpFile.Ref, "/control.nacp".ToU8Span(), OpenMode.Read).ThrowIfFailure();
-                        nacpFile.Get.Read(out _, 0, SpanHelpers.AsByteSpan(ref controlData), ReadOption.None).ThrowIfFailure();
-
-                        TitleUpdates.Add(new TitleUpdateModel(controlData, path));
-                    }
-                    else
-                    {
-                        Dispatcher.UIThread.Post(async () =>
-                        {
-                            await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUpdateAddUpdateErrorMessage]);
-                        });
-                    }
-                }
-                catch (Exception ex)
                 {
                     Dispatcher.UIThread.Post(async () =>
                     {
-                        await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogLoadNcaErrorMessage, ex.Message, path));
+                        await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance[LocaleKeys.DialogUpdateAddUpdateErrorMessage]);
                     });
                 }
             }
-        }
-
-        public void RemoveUpdate(TitleUpdateModel update)
-        {
-            TitleUpdates.Remove(update);
-
-            SortUpdates();
-        }
-
-        public async void Add()
-        {
-            OpenFileDialog dialog = new()
+            catch (Exception ex)
             {
-                Title         = LocaleManager.Instance[LocaleKeys.SelectUpdateDialogTitle],
-                AllowMultiple = true
-            };
-
-            dialog.Filters.Add(new FileDialogFilter
-            {
-                Name       = "NSP",
-                Extensions = { "nsp" }
-            });
-
-            if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
-            {
-                string[] files = await dialog.ShowAsync(desktop.MainWindow);
-
-                if (files != null)
+                Dispatcher.UIThread.Post(async () =>
                 {
-                    foreach (string file in files)
-                    {
-                        AddUpdate(file);
-                    }
-                }
+                    await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogLoadNcaErrorMessage, ex.Message, path));
+                });
             }
-
-            SortUpdates();
-        }
-
-        public void Save()
-        {
-            _titleUpdateWindowData.Paths.Clear();
-            _titleUpdateWindowData.Selected = "";
-
-            foreach (TitleUpdateModel update in TitleUpdates)
-            {
-                _titleUpdateWindowData.Paths.Add(update.Path);
-
-                if (update == SelectedUpdate)
-                {
-                    _titleUpdateWindowData.Selected = update.Path;
-                }
-            }
-
-            JsonHelper.SerializeToFile(_titleUpdateJsonPath, _titleUpdateWindowData, SerializerContext.TitleUpdateMetadata);
         }
     }
+
+    public void RemoveUpdate(TitleUpdateModel update)
+    {
+        TitleUpdates.Remove(update);
+
+        SortUpdates();
+    }
+
+    public async void Add()
+    {
+        OpenFileDialog dialog = new()
+        {
+            Title         = LocaleManager.Instance[LocaleKeys.SelectUpdateDialogTitle],
+            AllowMultiple = true
+        };
+
+        dialog.Filters.Add(new FileDialogFilter
+        {
+            Name       = "NSP",
+            Extensions = { "nsp" }
+        });
+
+        if (Avalonia.Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+        {
+            string[] files = await dialog.ShowAsync(desktop.MainWindow);
+
+            if (files != null)
+            {
+                foreach (string file in files)
+                {
+                    AddUpdate(file);
+                }
+            }
+        }
+
+        SortUpdates();
+    }
+
+    public void Save()
+    {
+        _titleUpdateWindowData.Paths.Clear();
+        _titleUpdateWindowData.Selected = "";
+
+        foreach (TitleUpdateModel update in TitleUpdates)
+        {
+            _titleUpdateWindowData.Paths.Add(update.Path);
+
+            if (update == SelectedUpdate)
+            {
+                _titleUpdateWindowData.Selected = update.Path;
+            }
+        }
+
+        File.WriteAllBytes(_titleUpdateJsonPath, Encoding.UTF8.GetBytes(JsonHelper.Serialize(_titleUpdateWindowData, true)));
+    }
 }
\ No newline at end of file
diff --git a/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
index 51c71c378..1c6f4265c 100644
--- a/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
+++ b/Ryujinx.Ava/UI/Views/Main/MainMenuBarView.axaml.cs
@@ -42,7 +42,7 @@ namespace Ryujinx.Ava.UI.Views.Main
             {
                 string languageCode = Path.GetFileNameWithoutExtension(locale).Split('.').Last();
                 string languageJson = EmbeddedResources.ReadAllText($"{localePath}/{languageCode}{localeExt}");
-                var    strings      = JsonHelper.Deserialize(languageJson, CommonJsonContext.Default.StringDictionary);
+                var    strings      = JsonHelper.Deserialize<Dictionary<string, string>>(languageJson);
 
                 if (!strings.TryGetValue("Language", out string languageName))
                 {
diff --git a/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs b/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs
index 206d0a7ea..5368a1333 100644
--- a/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs
+++ b/Ryujinx.Ava/UI/Windows/AmiiboWindow.axaml.cs
@@ -1,7 +1,7 @@
 using Avalonia.Interactivity;
 using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.UI.Models;
 using Ryujinx.Ava.UI.ViewModels;
-using Ryujinx.Ui.Common.Models.Amiibo;
 
 namespace Ryujinx.Ava.UI.Windows
 {
@@ -35,14 +35,14 @@ namespace Ryujinx.Ava.UI.Windows
         }
 
         public bool IsScanned { get; set; }
-        public AmiiboApi ScannedAmiibo { get; set; }
+        public Amiibo.AmiiboApi ScannedAmiibo { get; set; }
         public AmiiboWindowViewModel ViewModel { get; set; }
 
         private void ScanButton_Click(object sender, RoutedEventArgs e)
         {
             if (ViewModel.AmiiboSelectedIndex > -1)
             {
-                AmiiboApi amiibo = ViewModel.AmiiboList[ViewModel.AmiiboSelectedIndex];
+                Amiibo.AmiiboApi amiibo = ViewModel.AmiiboList[ViewModel.AmiiboSelectedIndex];
                 ScannedAmiibo = amiibo;
                 IsScanned = true;
                 Close();
diff --git a/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs b/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
index 153ce95d2..1b50c46f3 100644
--- a/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
+++ b/Ryujinx.Ava/UI/Windows/TitleUpdateWindow.axaml.cs
@@ -6,8 +6,11 @@ using Ryujinx.Ava.Common.Locale;
 using Ryujinx.Ava.UI.Helpers;
 using Ryujinx.Ava.UI.Models;
 using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Common.Utilities;
 using Ryujinx.HLE.FileSystem;
 using Ryujinx.Ui.Common.Helper;
+using System.IO;
+using System.Text;
 using System.Threading.Tasks;
 using Button = Avalonia.Controls.Button;
 
diff --git a/Ryujinx.Common/Configuration/AspectRatioExtensions.cs b/Ryujinx.Common/Configuration/AspectRatioExtensions.cs
index 5e97ed19c..3d0be88e9 100644
--- a/Ryujinx.Common/Configuration/AspectRatioExtensions.cs
+++ b/Ryujinx.Common/Configuration/AspectRatioExtensions.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration
+namespace Ryujinx.Common.Configuration
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<AspectRatio>))]
     public enum AspectRatio
     {
         Fixed4x3,
diff --git a/Ryujinx.Common/Configuration/BackendThreading.cs b/Ryujinx.Common/Configuration/BackendThreading.cs
index 8833b3f07..cfc089146 100644
--- a/Ryujinx.Common/Configuration/BackendThreading.cs
+++ b/Ryujinx.Common/Configuration/BackendThreading.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration
+namespace Ryujinx.Common.Configuration
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<BackendThreading>))]
     public enum BackendThreading
     {
         Auto,
diff --git a/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs b/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs
deleted file mode 100644
index 132c45a44..000000000
--- a/Ryujinx.Common/Configuration/DownloadableContentJsonSerializerContext.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(List<DownloadableContentContainer>))]
-    public partial class DownloadableContentJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/GraphicsBackend.cs b/Ryujinx.Common/Configuration/GraphicsBackend.cs
index d74dd6e19..26e4a28a9 100644
--- a/Ryujinx.Common/Configuration/GraphicsBackend.cs
+++ b/Ryujinx.Common/Configuration/GraphicsBackend.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration
+namespace Ryujinx.Common.Configuration
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))]
     public enum GraphicsBackend
     {
         Vulkan,
diff --git a/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs b/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
index ad12302a6..556af689a 100644
--- a/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
+++ b/Ryujinx.Common/Configuration/GraphicsDebugLevel.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
 namespace Ryujinx.Common.Configuration
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<GraphicsDebugLevel>))]
     public enum GraphicsDebugLevel
     {
         None,
diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs
index 2b9e0af42..d1c2e4e81 100644
--- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs
+++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/JsonMotionConfigControllerConverter.cs
@@ -1,5 +1,4 @@
-using Ryujinx.Common.Utilities;
-using System;
+using System;
 using System.Text.Json;
 using System.Text.Json.Serialization;
 
@@ -7,8 +6,6 @@ namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
 {
     class JsonMotionConfigControllerConverter : JsonConverter<MotionConfigController>
     {
-        private static readonly MotionConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         private static MotionInputBackendType GetMotionInputBackendType(ref Utf8JsonReader reader)
         {
             // Temporary reader to get the backend type
@@ -55,8 +52,8 @@ namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
 
             return motionBackendType switch
             {
-                MotionInputBackendType.GamepadDriver => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardMotionConfigController),
-                MotionInputBackendType.CemuHook => JsonSerializer.Deserialize(ref reader, SerializerContext.CemuHookMotionConfigController),
+                MotionInputBackendType.GamepadDriver => (MotionConfigController)JsonSerializer.Deserialize(ref reader, typeof(StandardMotionConfigController), options),
+                MotionInputBackendType.CemuHook => (MotionConfigController)JsonSerializer.Deserialize(ref reader, typeof(CemuHookMotionConfigController), options),
                 _ => throw new InvalidOperationException($"Unknown backend type {motionBackendType}"),
             };
         }
@@ -66,10 +63,10 @@ namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
             switch (value.MotionBackend)
             {
                 case MotionInputBackendType.GamepadDriver:
-                    JsonSerializer.Serialize(writer, value as StandardMotionConfigController, SerializerContext.StandardMotionConfigController);
+                    JsonSerializer.Serialize(writer, value as StandardMotionConfigController, options);
                     break;
                 case MotionInputBackendType.CemuHook:
-                    JsonSerializer.Serialize(writer, value as CemuHookMotionConfigController, SerializerContext.CemuHookMotionConfigController);
+                    JsonSerializer.Serialize(writer, value as CemuHookMotionConfigController, options);
                     break;
                 default:
                     throw new ArgumentException($"Unknown motion backend type {value.MotionBackend}");
diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs
index 7636aa414..832aae0d1 100644
--- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs
+++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigController.cs
@@ -1,8 +1,5 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
+namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
 {
-    [JsonConverter(typeof(JsonMotionConfigControllerConverter))]
     public class MotionConfigController
     {
         public MotionInputBackendType MotionBackend { get; set; }
diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs
deleted file mode 100644
index 5cd9e452b..000000000
--- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionConfigJsonSerializerContext.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(MotionConfigController))]
-    [JsonSerializable(typeof(CemuHookMotionConfigController))]
-    [JsonSerializable(typeof(StandardMotionConfigController))]
-    public partial class MotionConfigJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs
index c65510478..45d654edc 100644
--- a/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs
+++ b/Ryujinx.Common/Configuration/Hid/Controller/Motion/MotionInputBackendType.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
+namespace Ryujinx.Common.Configuration.Hid.Controller.Motion
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<MotionInputBackendType>))]
     public enum MotionInputBackendType : byte
     {
         Invalid,
diff --git a/Ryujinx.Common/Configuration/Hid/ControllerType.cs b/Ryujinx.Common/Configuration/Hid/ControllerType.cs
index 70f811c89..0ad01bbb6 100644
--- a/Ryujinx.Common/Configuration/Hid/ControllerType.cs
+++ b/Ryujinx.Common/Configuration/Hid/ControllerType.cs
@@ -1,12 +1,9 @@
-using Ryujinx.Common.Utilities;
 using System;
-using System.Text.Json.Serialization;
 
 namespace Ryujinx.Common.Configuration.Hid
 {
-    // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
     [Flags]
-    [JsonConverter(typeof(TypedStringEnumConverter<ControllerType>))]
+    // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
     public enum ControllerType : int
     {
         None,
diff --git a/Ryujinx.Common/Configuration/Hid/InputBackendType.cs b/Ryujinx.Common/Configuration/Hid/InputBackendType.cs
index 1db3f5703..9e944f9e8 100644
--- a/Ryujinx.Common/Configuration/Hid/InputBackendType.cs
+++ b/Ryujinx.Common/Configuration/Hid/InputBackendType.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration.Hid
+namespace Ryujinx.Common.Configuration.Hid
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<InputBackendType>))]
     public enum InputBackendType
     {
         Invalid,
diff --git a/Ryujinx.Common/Configuration/Hid/InputConfig.cs b/Ryujinx.Common/Configuration/Hid/InputConfig.cs
index 16c8f8e32..3364e35fa 100644
--- a/Ryujinx.Common/Configuration/Hid/InputConfig.cs
+++ b/Ryujinx.Common/Configuration/Hid/InputConfig.cs
@@ -1,10 +1,8 @@
 using System.ComponentModel;
 using System.Runtime.CompilerServices;
-using System.Text.Json.Serialization;
 
 namespace Ryujinx.Common.Configuration.Hid
 {
-    [JsonConverter(typeof(JsonInputConfigConverter))]
     public class InputConfig : INotifyPropertyChanged
     {
         /// <summary>
diff --git a/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs b/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs
deleted file mode 100644
index 254c4feb4..000000000
--- a/Ryujinx.Common/Configuration/Hid/InputConfigJsonSerializerContext.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using Ryujinx.Common.Configuration.Hid.Controller;
-using Ryujinx.Common.Configuration.Hid.Keyboard;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration.Hid
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(InputConfig))]
-    [JsonSerializable(typeof(StandardKeyboardInputConfig))]
-    [JsonSerializable(typeof(StandardControllerInputConfig))]
-    public partial class InputConfigJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs b/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs
index 08bbcbf17..7223ad451 100644
--- a/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs
+++ b/Ryujinx.Common/Configuration/Hid/JsonInputConfigConverter.cs
@@ -1,16 +1,13 @@
 using Ryujinx.Common.Configuration.Hid.Controller;
 using Ryujinx.Common.Configuration.Hid.Keyboard;
-using Ryujinx.Common.Utilities;
 using System;
 using System.Text.Json;
 using System.Text.Json.Serialization;
 
 namespace Ryujinx.Common.Configuration.Hid
 {
-    public class JsonInputConfigConverter : JsonConverter<InputConfig>
+    class JsonInputConfigConverter : JsonConverter<InputConfig>
     {
-        private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         private static InputBackendType GetInputBackendType(ref Utf8JsonReader reader)
         {
             // Temporary reader to get the backend type
@@ -57,8 +54,8 @@ namespace Ryujinx.Common.Configuration.Hid
 
             return backendType switch
             {
-                InputBackendType.WindowKeyboard => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardKeyboardInputConfig),
-                InputBackendType.GamepadSDL2 => JsonSerializer.Deserialize(ref reader, SerializerContext.StandardControllerInputConfig),
+                InputBackendType.WindowKeyboard => (InputConfig)JsonSerializer.Deserialize(ref reader, typeof(StandardKeyboardInputConfig), options),
+                InputBackendType.GamepadSDL2 => (InputConfig)JsonSerializer.Deserialize(ref reader, typeof(StandardControllerInputConfig), options),
                 _ => throw new InvalidOperationException($"Unknown backend type {backendType}"),
             };
         }
@@ -68,10 +65,10 @@ namespace Ryujinx.Common.Configuration.Hid
             switch (value.Backend)
             {
                 case InputBackendType.WindowKeyboard:
-                    JsonSerializer.Serialize(writer, value as StandardKeyboardInputConfig, SerializerContext.StandardKeyboardInputConfig);
+                    JsonSerializer.Serialize(writer, value as StandardKeyboardInputConfig, options);
                     break;
                 case InputBackendType.GamepadSDL2:
-                    JsonSerializer.Serialize(writer, value as StandardControllerInputConfig, SerializerContext.StandardControllerInputConfig);
+                    JsonSerializer.Serialize(writer, value as StandardControllerInputConfig, options);
                     break;
                 default:
                     throw new ArgumentException($"Unknown backend type {value.Backend}");
diff --git a/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs b/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
index dd6495d4d..2e34cb96c 100644
--- a/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
+++ b/Ryujinx.Common/Configuration/Hid/PlayerIndex.cs
@@ -1,10 +1,6 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
 namespace Ryujinx.Common.Configuration.Hid
 {
     // This enum was duplicated from Ryujinx.HLE.HOS.Services.Hid.PlayerIndex and should be kept identical
-    [JsonConverter(typeof(TypedStringEnumConverter<PlayerIndex>))]
     public enum PlayerIndex : int
     {
         Player1  = 0,
diff --git a/Ryujinx.Common/Configuration/MemoryManagerMode.cs b/Ryujinx.Common/Configuration/MemoryManagerMode.cs
index f10fd6f1b..ad6c2a346 100644
--- a/Ryujinx.Common/Configuration/MemoryManagerMode.cs
+++ b/Ryujinx.Common/Configuration/MemoryManagerMode.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration
+namespace Ryujinx.Common.Configuration
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<MemoryManagerMode>))]
     public enum MemoryManagerMode : byte
     {
         SoftwarePageTable,
diff --git a/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs b/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs
deleted file mode 100644
index 5b661b878..000000000
--- a/Ryujinx.Common/Configuration/TitleUpdateMetadataJsonSerializerContext.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Configuration
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(TitleUpdateMetadata))]
-    public partial class TitleUpdateMetadataJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs b/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs
index 28a7d5461..b9a08323e 100644
--- a/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs
+++ b/Ryujinx.Common/Logging/Formatters/DefaultLogFormatter.cs
@@ -1,20 +1,22 @@
-using System.Text;
+using System;
+using System.Reflection;
+using System.Text;
 
 namespace Ryujinx.Common.Logging
 {
     internal class DefaultLogFormatter : ILogFormatter
     {
-        private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>();
+        private static readonly ObjectPool<StringBuilder> _stringBuilderPool = SharedPools.Default<StringBuilder>();
 
         public string Format(LogEventArgs args)
         {
-            StringBuilder sb = StringBuilderPool.Allocate();
+            StringBuilder sb = _stringBuilderPool.Allocate();
 
             try
             {
                 sb.Clear();
 
-                sb.Append($@"{args.Time:hh\:mm\:ss\.fff}");
+                sb.AppendFormat(@"{0:hh\:mm\:ss\.fff}", args.Time);
                 sb.Append($" |{args.Level.ToString()[0]}| ");
 
                 if (args.ThreadName != null)
@@ -25,17 +27,53 @@ namespace Ryujinx.Common.Logging
 
                 sb.Append(args.Message);
 
-                if (args.Data is not null)
+                if (args.Data != null)
                 {
-                    sb.Append(' ');
-                    DynamicObjectFormatter.Format(sb, args.Data);
+                    PropertyInfo[] props = args.Data.GetType().GetProperties();
+
+                    sb.Append(" {");
+
+                    foreach (var prop in props)
+                    {
+                        sb.Append(prop.Name);
+                        sb.Append(": ");
+
+                        if (typeof(Array).IsAssignableFrom(prop.PropertyType))
+                        {
+                            Array array = (Array)prop.GetValue(args.Data);
+                            foreach (var item in array)
+                            {
+                                sb.Append(item.ToString());
+                                sb.Append(", ");
+                            }
+
+                            if (array.Length > 0)
+                            {
+                                sb.Remove(sb.Length - 2, 2);
+                            }
+                        }
+                        else
+                        {
+                            sb.Append(prop.GetValue(args.Data));
+                        }
+
+                        sb.Append(" ; ");
+                    }
+
+                    // We remove the final ';' from the string
+                    if (props.Length > 0)
+                    {
+                        sb.Remove(sb.Length - 3, 3);
+                    }
+
+                    sb.Append('}');
                 }
 
                 return sb.ToString();
             }
             finally
             {
-                StringBuilderPool.Release(sb);
+                _stringBuilderPool.Release(sb);
             }
         }
     }
diff --git a/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs b/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs
deleted file mode 100644
index 5f15cc2a6..000000000
--- a/Ryujinx.Common/Logging/Formatters/DynamicObjectFormatter.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-#nullable enable
-using System;
-using System.Reflection;
-using System.Text;
-
-namespace Ryujinx.Common.Logging
-{
-    internal class DynamicObjectFormatter
-    {
-        private static readonly ObjectPool<StringBuilder> StringBuilderPool = SharedPools.Default<StringBuilder>();
-
-        public static string? Format(object? dynamicObject)
-        {
-            if (dynamicObject is null)
-            {
-                return null;
-            }
-
-            StringBuilder sb = StringBuilderPool.Allocate();
-            
-            try
-            {
-                Format(sb, dynamicObject);
-
-                return sb.ToString();
-            }
-            finally
-            {
-                StringBuilderPool.Release(sb);
-            }
-        }
-
-        public static void Format(StringBuilder sb, object? dynamicObject)
-        {
-            if (dynamicObject is null)
-            {
-                return;
-            }
-
-            PropertyInfo[] props = dynamicObject.GetType().GetProperties();
-
-            sb.Append('{');
-
-            foreach (var prop in props)
-            {
-                sb.Append(prop.Name);
-                sb.Append(": ");
-
-                if (typeof(Array).IsAssignableFrom(prop.PropertyType))
-                {
-                    Array? array = (Array?) prop.GetValue(dynamicObject);
-
-                    if (array is not null)
-                    {
-                        foreach (var item in array)
-                        {
-                            sb.Append(item);
-                            sb.Append(", ");
-                        }
-
-                        if (array.Length > 0)
-                        {
-                            sb.Remove(sb.Length - 2, 2);
-                        }
-                    }
-                }
-                else
-                {
-                    sb.Append(prop.GetValue(dynamicObject));
-                }
-
-                sb.Append(" ; ");
-            }
-
-            // We remove the final ';' from the string
-            if (props.Length > 0)
-            {
-                sb.Remove(sb.Length - 3, 3);
-            }
-
-            sb.Append('}');
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Logging/LogClass.cs b/Ryujinx.Common/Logging/LogClass.cs
index e62676cd3..7e53c972b 100644
--- a/Ryujinx.Common/Logging/LogClass.cs
+++ b/Ryujinx.Common/Logging/LogClass.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
 namespace Ryujinx.Common.Logging
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<LogClass>))]
     public enum LogClass
     {
         Application,
diff --git a/Ryujinx.Common/Logging/LogEventArgs.cs b/Ryujinx.Common/Logging/LogEventArgs.cs
index a27af7809..511c8e6e2 100644
--- a/Ryujinx.Common/Logging/LogEventArgs.cs
+++ b/Ryujinx.Common/Logging/LogEventArgs.cs
@@ -11,7 +11,15 @@ namespace Ryujinx.Common.Logging
         public readonly string Message;
         public readonly object Data;
 
-        public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message, object data = null)
+        public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message)
+        {
+            Level      = level;
+            Time       = time;
+            ThreadName = threadName;
+            Message    = message;
+        }
+
+        public LogEventArgs(LogLevel level, TimeSpan time, string threadName, string message, object data)
         {
             Level      = level;
             Time       = time;
diff --git a/Ryujinx.Common/Logging/LogEventArgsJson.cs b/Ryujinx.Common/Logging/LogEventArgsJson.cs
deleted file mode 100644
index 425b97662..000000000
--- a/Ryujinx.Common/Logging/LogEventArgsJson.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-using System;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Logging
-{
-    internal class LogEventArgsJson
-    {
-        public LogLevel Level { get; }
-        public TimeSpan Time { get; }
-        public string   ThreadName { get; }
-
-        public string Message { get; }
-        public string Data { get; }
-
-        [JsonConstructor]
-        public LogEventArgsJson(LogLevel level, TimeSpan time, string threadName, string message, string data = null)
-        {
-            Level      = level;
-            Time       = time;
-            ThreadName = threadName;
-            Message    = message;
-            Data       = data;
-        }
-
-        public static LogEventArgsJson FromLogEventArgs(LogEventArgs args)
-        {
-            return new LogEventArgsJson(args.Level, args.Time, args.ThreadName, args.Message, DynamicObjectFormatter.Format(args.Data));
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs b/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs
deleted file mode 100644
index da21f11e8..000000000
--- a/Ryujinx.Common/Logging/LogEventJsonSerializerContext.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Logging
-{
-    [JsonSerializable(typeof(LogEventArgsJson))]
-    internal partial class LogEventJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Logging/LogLevel.cs b/Ryujinx.Common/Logging/LogLevel.cs
index 3786c7561..8857fb45a 100644
--- a/Ryujinx.Common/Logging/LogLevel.cs
+++ b/Ryujinx.Common/Logging/LogLevel.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
 namespace Ryujinx.Common.Logging
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<LogLevel>))]
     public enum LogLevel
     {
         Debug,
diff --git a/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs b/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs
index 06976433e..95f96576c 100644
--- a/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs
+++ b/Ryujinx.Common/Logging/Targets/JsonLogTarget.cs
@@ -1,5 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.IO;
+using System.IO;
+using System.Text.Json;
 
 namespace Ryujinx.Common.Logging
 {
@@ -25,8 +25,12 @@ namespace Ryujinx.Common.Logging
 
         public void Log(object sender, LogEventArgs e)
         {
-            var logEventArgsJson = LogEventArgsJson.FromLogEventArgs(e);
-            JsonHelper.SerializeToStream(_stream, logEventArgsJson, LogEventJsonSerializerContext.Default.LogEventArgsJson);
+            string text = JsonSerializer.Serialize(e);
+
+            using (BinaryWriter writer = new BinaryWriter(_stream))
+            {
+                writer.Write(text);
+            }
         }
 
         public void Dispose()
diff --git a/Ryujinx.Common/Utilities/CommonJsonContext.cs b/Ryujinx.Common/Utilities/CommonJsonContext.cs
deleted file mode 100644
index d7b3f78cd..000000000
--- a/Ryujinx.Common/Utilities/CommonJsonContext.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Utilities
-{
-    [JsonSerializable(typeof(string[]), TypeInfoPropertyName = "StringArray")]
-    [JsonSerializable(typeof(Dictionary<string, string>), TypeInfoPropertyName = "StringDictionary")]
-    public partial class CommonJsonContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Common/Utilities/JsonHelper.cs b/Ryujinx.Common/Utilities/JsonHelper.cs
index 9a2d6f181..36f391149 100644
--- a/Ryujinx.Common/Utilities/JsonHelper.cs
+++ b/Ryujinx.Common/Utilities/JsonHelper.cs
@@ -1,62 +1,15 @@
-using System.IO;
+using Ryujinx.Common.Configuration.Hid;
+using Ryujinx.Common.Configuration.Hid.Controller.Motion;
+using System.IO;
 using System.Text;
 using System.Text.Json;
-using System.Text.Json.Serialization.Metadata;
+using System.Text.Json.Serialization;
 
 namespace Ryujinx.Common.Utilities
 {
     public class JsonHelper
     {
-        private static readonly JsonNamingPolicy SnakeCasePolicy = new SnakeCaseNamingPolicy();
-        private const int DefaultFileWriteBufferSize = 4096;
-
-        /// <summary>
-        /// Creates new serializer options with default settings.
-        /// </summary>
-        /// <remarks>
-        /// It is REQUIRED for you to save returned options statically or as a part of static serializer context
-        /// in order to avoid performance issues. You can safely modify returned options for your case before storing.
-        /// </remarks>
-        public static JsonSerializerOptions GetDefaultSerializerOptions(bool indented = true)
-        {
-            JsonSerializerOptions options = new()
-            {
-                DictionaryKeyPolicy  = SnakeCasePolicy,
-                PropertyNamingPolicy = SnakeCasePolicy,
-                WriteIndented        = indented,
-                AllowTrailingCommas  = true,
-                ReadCommentHandling  = JsonCommentHandling.Skip
-            };
-
-            return options;
-        }
-
-        public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo)
-        {
-            return JsonSerializer.Serialize(value, typeInfo);
-        }
-
-        public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo)
-        {
-            return JsonSerializer.Deserialize(value, typeInfo);
-        }
-
-        public static void SerializeToFile<T>(string filePath, T value, JsonTypeInfo<T> typeInfo)
-        {
-            using FileStream file = File.Create(filePath, DefaultFileWriteBufferSize, FileOptions.WriteThrough);
-            JsonSerializer.Serialize(file, value, typeInfo);
-        }
-
-        public static T DeserializeFromFile<T>(string filePath, JsonTypeInfo<T> typeInfo)
-        {
-            using FileStream file = File.OpenRead(filePath);
-            return JsonSerializer.Deserialize(file, typeInfo);
-        }
-
-        public static void SerializeToStream<T>(Stream stream, T value, JsonTypeInfo<T> typeInfo)
-        {
-            JsonSerializer.Serialize(stream, value, typeInfo);
-        }
+        public static JsonNamingPolicy SnakeCase { get; }
 
         private class SnakeCaseNamingPolicy : JsonNamingPolicy
         {
@@ -67,7 +20,7 @@ namespace Ryujinx.Common.Utilities
                     return name;
                 }
 
-                StringBuilder builder = new();
+                StringBuilder builder = new StringBuilder();
 
                 for (int i = 0; i < name.Length; i++)
                 {
@@ -81,7 +34,7 @@ namespace Ryujinx.Common.Utilities
                         }
                         else
                         {
-                            builder.Append('_');
+                            builder.Append("_");
                             builder.Append(char.ToLowerInvariant(c));
                         }
                     }
@@ -94,5 +47,64 @@ namespace Ryujinx.Common.Utilities
                 return builder.ToString();
             }
         }
+
+        static JsonHelper()
+        {
+            SnakeCase = new SnakeCaseNamingPolicy();
+        }
+
+        public static JsonSerializerOptions GetDefaultSerializerOptions(bool prettyPrint = false)
+        {
+            JsonSerializerOptions options = new JsonSerializerOptions
+            {
+                DictionaryKeyPolicy  = SnakeCase,
+                PropertyNamingPolicy = SnakeCase,
+                WriteIndented        = prettyPrint,
+                AllowTrailingCommas  = true,
+                ReadCommentHandling  = JsonCommentHandling.Skip
+            };
+
+            options.Converters.Add(new JsonStringEnumConverter());
+            options.Converters.Add(new JsonInputConfigConverter());
+            options.Converters.Add(new JsonMotionConfigControllerConverter());
+
+            return options;
+        }
+
+        public static T Deserialize<T>(Stream stream)
+        {
+            using (BinaryReader reader = new BinaryReader(stream))
+            {
+                return JsonSerializer.Deserialize<T>(reader.ReadBytes((int)(stream.Length - stream.Position)), GetDefaultSerializerOptions());
+            }
+        }
+
+        public static T DeserializeFromFile<T>(string path)
+        {
+            return Deserialize<T>(File.ReadAllText(path));
+        }
+
+        public static T Deserialize<T>(string json)
+        {
+            return JsonSerializer.Deserialize<T>(json, GetDefaultSerializerOptions());
+        }
+
+        public static void Serialize<TValue>(Stream stream, TValue obj, bool prettyPrint = false)
+        {
+            using (BinaryWriter writer = new BinaryWriter(stream))
+            {
+                writer.Write(SerializeToUtf8Bytes(obj, prettyPrint));
+            }
+        }
+
+        public static string Serialize<TValue>(TValue obj, bool prettyPrint = false)
+        {
+            return JsonSerializer.Serialize(obj, GetDefaultSerializerOptions(prettyPrint));
+        }
+
+        public static byte[] SerializeToUtf8Bytes<T>(T obj, bool prettyPrint = false)
+        {
+            return JsonSerializer.SerializeToUtf8Bytes(obj, GetDefaultSerializerOptions(prettyPrint));
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs b/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs
deleted file mode 100644
index c0127dc4a..000000000
--- a/Ryujinx.Common/Utilities/TypedStringEnumConverter.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-#nullable enable
-using System;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Common.Utilities
-{
-    /// <summary>
-    /// Specifies that value of <see cref="TEnum"/> will be serialized as string in JSONs
-    /// </summary>
-    /// <remarks>
-    /// Trimming friendly alternative to <see cref="JsonStringEnumConverter"/>.
-    /// Get rid of this converter if dotnet supports similar functionality out of the box.
-    /// </remarks>
-    /// <typeparam name="TEnum">Type of enum to serialize</typeparam>
-    public sealed class TypedStringEnumConverter<TEnum> : JsonConverter<TEnum> where TEnum : struct, Enum
-    {
-        public override TEnum Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
-        {
-            var enumValue = reader.GetString();
-            if (string.IsNullOrEmpty(enumValue))
-            {
-                return default;
-            }
-
-            return Enum.Parse<TEnum>(enumValue);
-        }
-
-        public override void Write(Utf8JsonWriter writer, TEnum value, JsonSerializerOptions options)
-        {
-            writer.WriteStringValue(value.ToString());
-        }
-    }
-}
diff --git a/Ryujinx.HLE/HOS/ApplicationLoader.cs b/Ryujinx.HLE/HOS/ApplicationLoader.cs
index 7d06e5eb7..82bd9b312 100644
--- a/Ryujinx.HLE/HOS/ApplicationLoader.cs
+++ b/Ryujinx.HLE/HOS/ApplicationLoader.cs
@@ -13,7 +13,6 @@ using LibHac.Tools.FsSystem;
 using LibHac.Tools.FsSystem.NcaUtils;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
 using Ryujinx.Cpu;
 using Ryujinx.HLE.FileSystem;
 using Ryujinx.HLE.Loaders.Executables;
@@ -25,13 +24,14 @@ using System.IO;
 using System.Linq;
 using System.Reflection;
 using System.Text;
-using System.Text.Json;
 using static Ryujinx.HLE.HOS.ModLoader;
 using ApplicationId = LibHac.Ncm.ApplicationId;
 using Path = System.IO.Path;
 
 namespace Ryujinx.HLE.HOS
 {
+    using JsonHelper = Common.Utilities.JsonHelper;
+
     public class ApplicationLoader
     {
         // Binaries from exefs are loaded into mem in this order. Do not change.
@@ -57,10 +57,6 @@ namespace Ryujinx.HLE.HOS
         private string _displayVersion;
         private BlitStruct<ApplicationControlProperty> _controlData;
 
-        private static readonly JsonSerializerOptions SerializerOptions = JsonHelper.GetDefaultSerializerOptions();
-        private static readonly DownloadableContentJsonSerializerContext ContentSerializerContext = new(SerializerOptions);
-        private static readonly TitleUpdateMetadataJsonSerializerContext TitleSerializerContext = new(SerializerOptions);
-
         public BlitStruct<ApplicationControlProperty> ControlData => _controlData;
         public string TitleName => _titleName;
         public string DisplayVersion => _displayVersion;
@@ -201,7 +197,7 @@ namespace Ryujinx.HLE.HOS
 
                 if (File.Exists(titleUpdateMetadataPath))
                 {
-                    updatePath = JsonHelper.DeserializeFromFile(titleUpdateMetadataPath, TitleSerializerContext.TitleUpdateMetadata).Selected;
+                    updatePath = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(titleUpdateMetadataPath).Selected;
 
                     if (File.Exists(updatePath))
                     {
@@ -415,7 +411,7 @@ namespace Ryujinx.HLE.HOS
 
             if (File.Exists(titleAocMetadataPath))
             {
-                List<DownloadableContentContainer> dlcContainerList = JsonHelper.DeserializeFromFile(titleAocMetadataPath, ContentSerializerContext.ListDownloadableContentContainer);
+                List<DownloadableContentContainer> dlcContainerList = JsonHelper.DeserializeFromFile<List<DownloadableContentContainer>>(titleAocMetadataPath);
 
                 foreach (DownloadableContentContainer downloadableContentContainer in dlcContainerList)
                 {
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs
index 535779d2e..ec0b0a10b 100644
--- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs
+++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountSaveDataManager.cs
@@ -1,11 +1,11 @@
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Logging;
 using Ryujinx.Common.Utilities;
-using Ryujinx.HLE.HOS.Services.Account.Acc.Types;
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.IO;
+using System.Text.Json.Serialization;
 
 namespace Ryujinx.HLE.HOS.Services.Account.Acc
 {
@@ -13,7 +13,29 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
     {
         private readonly string _profilesJsonPath = Path.Join(AppDataManager.BaseDirPath, "system", "Profiles.json");
 
-        private static readonly ProfilesJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
+        private struct ProfilesJson
+        {
+            [JsonPropertyName("profiles")]
+            public List<UserProfileJson> Profiles { get; set; }
+            [JsonPropertyName("last_opened")]
+            public string LastOpened { get; set; }
+        }
+
+        private struct UserProfileJson
+        {
+            [JsonPropertyName("user_id")]
+            public string UserId { get; set; }
+            [JsonPropertyName("name")]
+            public string Name { get; set; }
+            [JsonPropertyName("account_state")]
+            public AccountState AccountState { get; set; }
+            [JsonPropertyName("online_play_state")]
+            public AccountState OnlinePlayState { get; set; }
+            [JsonPropertyName("last_modified_timestamp")]
+            public long LastModifiedTimestamp { get; set; }
+            [JsonPropertyName("image")]
+            public byte[] Image { get; set; }
+        }
 
         public UserId LastOpened { get; set; }
 
@@ -25,7 +47,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
             {
                 try 
                 {
-                    ProfilesJson profilesJson = JsonHelper.DeserializeFromFile(_profilesJsonPath, SerializerContext.ProfilesJson);
+                    ProfilesJson profilesJson = JsonHelper.DeserializeFromFile<ProfilesJson>(_profilesJsonPath);
 
                     foreach (var profile in profilesJson.Profiles)
                     {
@@ -70,7 +92,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc
                 });
             }
 
-            JsonHelper.SerializeToFile(_profilesJsonPath, profilesJson, SerializerContext.ProfilesJson);
+            File.WriteAllText(_profilesJsonPath, JsonHelper.Serialize(profilesJson, true));
         }
     }
 }
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs
deleted file mode 100644
index 6b54898e5..000000000
--- a/Ryujinx.HLE/HOS/Services/Account/Acc/ProfilesJsonSerializerContext.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Ryujinx.HLE.HOS.Services.Account.Acc.Types;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.HLE.HOS.Services.Account.Acc
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(ProfilesJson))]
-    internal partial class ProfilesJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountState.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountState.cs
index 1699abfbd..2382a2554 100644
--- a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountState.cs
+++ b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/AccountState.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
 namespace Ryujinx.HLE.HOS.Services.Account.Acc
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<AccountState>))]
     public enum AccountState
     {
         Closed,
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs
deleted file mode 100644
index 09f9d1421..000000000
--- a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/ProfilesJson.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.HLE.HOS.Services.Account.Acc.Types
-{
-    internal struct ProfilesJson
-    {
-        public List<UserProfileJson> Profiles { get; set; }
-        public string LastOpened { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs
deleted file mode 100644
index 06ff4833f..000000000
--- a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/UserProfileJson.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Ryujinx.HLE.HOS.Services.Account.Acc.Types
-{
-    internal struct UserProfileJson
-    {
-        public string UserId { get; set; }
-        public string Name { get; set; }
-        public AccountState AccountState { get; set; }
-        public AccountState OnlinePlayState { get; set; }
-        public long LastModifiedTimestamp { get; set; }
-        public byte[] Image { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs
deleted file mode 100644
index e75f62004..000000000
--- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/AmiiboJsonSerializerContext.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using Ryujinx.HLE.HOS.Services.Nfc.Nfp.NfpManager;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
-{
-    [JsonSerializable(typeof(VirtualAmiiboFile))]
-    internal partial class AmiiboJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs
index 9166e87fa..4fdeadcb2 100644
--- a/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs
+++ b/Ryujinx.HLE/HOS/Services/Nfc/Nfp/VirtualAmiibo.cs
@@ -1,6 +1,5 @@
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Memory;
-using Ryujinx.Common.Utilities;
 using Ryujinx.Cpu;
 using Ryujinx.HLE.HOS.Services.Mii;
 using Ryujinx.HLE.HOS.Services.Mii.Types;
@@ -9,6 +8,8 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Text;
+using System.Text.Json;
 
 namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
 {
@@ -16,8 +17,6 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
     {
         private static uint _openedApplicationAreaId;
 
-        private static readonly AmiiboJsonSerializerContext SerializerContext = AmiiboJsonSerializerContext.Default;
-
         public static byte[] GenerateUuid(string amiiboId, bool useRandomUuid)
         {
             if (useRandomUuid)
@@ -174,7 +173,7 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
 
             if (File.Exists(filePath))
             {
-                virtualAmiiboFile = JsonHelper.DeserializeFromFile(filePath, SerializerContext.VirtualAmiiboFile);
+                virtualAmiiboFile = JsonSerializer.Deserialize<VirtualAmiiboFile>(File.ReadAllText(filePath), new JsonSerializerOptions(JsonSerializerDefaults.General));
             }
             else
             {
@@ -198,7 +197,8 @@ namespace Ryujinx.HLE.HOS.Services.Nfc.Nfp
         private static void SaveAmiiboFile(VirtualAmiiboFile virtualAmiiboFile)
         {
             string filePath = Path.Join(AppDataManager.BaseDirPath, "system", "amiibo", $"{virtualAmiiboFile.AmiiboId}.json");
-            JsonHelper.SerializeToFile(filePath, virtualAmiiboFile, SerializerContext.VirtualAmiiboFile);
+
+            File.WriteAllText(filePath, JsonSerializer.Serialize(virtualAmiiboFile));
         }
     }
 }
diff --git a/Ryujinx.Headless.SDL2/Program.cs b/Ryujinx.Headless.SDL2/Program.cs
index 40eec4a73..f618e38d6 100644
--- a/Ryujinx.Headless.SDL2/Program.cs
+++ b/Ryujinx.Headless.SDL2/Program.cs
@@ -56,8 +56,6 @@ namespace Ryujinx.Headless.SDL2
         private static bool _enableKeyboard;
         private static bool _enableMouse;
 
-        private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         static void Main(string[] args)
         {
             Version = ReleaseInformation.GetVersion();
@@ -287,7 +285,10 @@ namespace Ryujinx.Headless.SDL2
 
                 try
                 {
-                    config = JsonHelper.DeserializeFromFile(path, SerializerContext.InputConfig);
+                    using (Stream stream = File.OpenRead(path))
+                    {
+                        config = JsonHelper.Deserialize<InputConfig>(stream);
+                    }
                 }
                 catch (JsonException)
                 {
diff --git a/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs b/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs
deleted file mode 100644
index f81121c28..000000000
--- a/Ryujinx.Ui.Common/App/ApplicationJsonSerializerContext.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.App.Common
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(ApplicationMetadata))]
-    internal partial class ApplicationJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/App/ApplicationLibrary.cs b/Ryujinx.Ui.Common/App/ApplicationLibrary.cs
index add6dad3f..43510d5ec 100644
--- a/Ryujinx.Ui.Common/App/ApplicationLibrary.cs
+++ b/Ryujinx.Ui.Common/App/ApplicationLibrary.cs
@@ -10,7 +10,6 @@ using LibHac.Tools.FsSystem;
 using LibHac.Tools.FsSystem.NcaUtils;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
 using Ryujinx.HLE.FileSystem;
 using Ryujinx.HLE.HOS;
 using Ryujinx.HLE.HOS.SystemState;
@@ -23,6 +22,7 @@ using System.Reflection;
 using System.Text;
 using System.Text.Json;
 using System.Threading;
+using JsonHelper = Ryujinx.Common.Utilities.JsonHelper;
 using Path = System.IO.Path;
 
 namespace Ryujinx.Ui.App.Common
@@ -42,8 +42,6 @@ namespace Ryujinx.Ui.App.Common
         private Language                   _desiredTitleLanguage;
         private CancellationTokenSource    _cancellationToken;
 
-        private static readonly ApplicationJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         public ApplicationLibrary(VirtualFileSystem virtualFileSystem)
         {
             _virtualFileSystem = virtualFileSystem;
@@ -492,12 +490,14 @@ namespace Ryujinx.Ui.App.Common
 
                 appMetadata = new ApplicationMetadata();
 
-                JsonHelper.SerializeToFile(metadataFile, appMetadata, SerializerContext.ApplicationMetadata);
+                using FileStream stream = File.Create(metadataFile, 4096, FileOptions.WriteThrough);
+
+                JsonHelper.Serialize(stream, appMetadata, true);
             }
 
             try
             {
-                appMetadata = JsonHelper.DeserializeFromFile(metadataFile, SerializerContext.ApplicationMetadata);
+                appMetadata = JsonHelper.DeserializeFromFile<ApplicationMetadata>(metadataFile);
             }
             catch (JsonException)
             {
@@ -510,7 +510,9 @@ namespace Ryujinx.Ui.App.Common
             {
                 modifyFunction(appMetadata);
 
-                JsonHelper.SerializeToFile(metadataFile, appMetadata, SerializerContext.ApplicationMetadata);
+                using FileStream stream = File.Create(metadataFile, 4096, FileOptions.WriteThrough);
+
+                JsonHelper.Serialize(stream, appMetadata, true);
             }
 
             return appMetadata;
diff --git a/Ryujinx.Ui.Common/Configuration/AudioBackend.cs b/Ryujinx.Ui.Common/Configuration/AudioBackend.cs
index 1f9bd0baf..99111ea64 100644
--- a/Ryujinx.Ui.Common/Configuration/AudioBackend.cs
+++ b/Ryujinx.Ui.Common/Configuration/AudioBackend.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Configuration
+namespace Ryujinx.Ui.Common.Configuration
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<AudioBackend>))]
     public enum AudioBackend
     {
         Dummy,
diff --git a/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs b/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs
index 14c03957a..e9aec04b2 100644
--- a/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs
+++ b/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormat.cs
@@ -5,7 +5,7 @@ using Ryujinx.Common.Utilities;
 using Ryujinx.Ui.Common.Configuration.System;
 using Ryujinx.Ui.Common.Configuration.Ui;
 using System.Collections.Generic;
-using System.Text.Json.Nodes;
+using System.IO;
 
 namespace Ryujinx.Ui.Common.Configuration
 {
@@ -321,14 +321,14 @@ namespace Ryujinx.Ui.Common.Configuration
         /// </summary>
         /// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks>
         /// TODO: Remove this when those older versions aren't in use anymore.
-        public List<JsonObject> KeyboardConfig { get; set; }
+        public List<object> KeyboardConfig { get; set; }
 
         /// <summary>
         /// Legacy controller control bindings
         /// </summary>
         /// <remarks>Kept for file format compatibility (to avoid possible failure when parsing configuration on old versions)</remarks>
         /// TODO: Remove this when those older versions aren't in use anymore.
-        public List<JsonObject> ControllerConfig { get; set; }
+        public List<object> ControllerConfig { get; set; }
 
         /// <summary>
         /// Input configurations
@@ -354,12 +354,11 @@ namespace Ryujinx.Ui.Common.Configuration
         /// Loads a configuration file from disk
         /// </summary>
         /// <param name="path">The path to the JSON configuration file</param>
-        /// <param name="configurationFileFormat">Parsed configuration file</param>
         public static bool TryLoad(string path, out ConfigurationFileFormat configurationFileFormat)
         {
             try
             {
-                configurationFileFormat = JsonHelper.DeserializeFromFile(path, ConfigurationFileFormatSettings.SerializerContext.ConfigurationFileFormat);
+                configurationFileFormat = JsonHelper.DeserializeFromFile<ConfigurationFileFormat>(path);
 
                 return configurationFileFormat.Version != 0;
             }
@@ -377,7 +376,8 @@ namespace Ryujinx.Ui.Common.Configuration
         /// <param name="path">The path to the JSON configuration file</param>
         public void SaveConfig(string path)
         {
-            JsonHelper.SerializeToFile(path, this, ConfigurationFileFormatSettings.SerializerContext.ConfigurationFileFormat);
+            using FileStream fileStream = File.Create(path, 4096, FileOptions.WriteThrough);
+            JsonHelper.Serialize(fileStream, this, true);
         }
     }
 }
diff --git a/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs b/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs
deleted file mode 100644
index 6ce2ef01a..000000000
--- a/Ryujinx.Ui.Common/Configuration/ConfigurationFileFormatSettings.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using Ryujinx.Common.Utilities;
-
-namespace Ryujinx.Ui.Common.Configuration
-{
-    internal static class ConfigurationFileFormatSettings
-    {
-        public static readonly ConfigurationJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs b/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs
deleted file mode 100644
index bb8dfb499..000000000
--- a/Ryujinx.Ui.Common/Configuration/ConfigurationJsonSerializerContext.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Configuration
-{
-    [JsonSourceGenerationOptions(WriteIndented = true)]
-    [JsonSerializable(typeof(ConfigurationFileFormat))]
-    internal partial class ConfigurationJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs b/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
index 82a331c16..bcdd2e70a 100644
--- a/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
+++ b/Ryujinx.Ui.Common/Configuration/ConfigurationState.cs
@@ -9,7 +9,6 @@ using Ryujinx.Ui.Common.Configuration.Ui;
 using Ryujinx.Ui.Common.Helper;
 using System;
 using System.Collections.Generic;
-using System.Text.Json.Nodes;
 
 namespace Ryujinx.Ui.Common.Configuration
 {
@@ -632,8 +631,8 @@ namespace Ryujinx.Ui.Common.Configuration
                 EnableKeyboard             = Hid.EnableKeyboard,
                 EnableMouse                = Hid.EnableMouse,
                 Hotkeys                    = Hid.Hotkeys,
-                KeyboardConfig             = new List<JsonObject>(),
-                ControllerConfig           = new List<JsonObject>(),
+                KeyboardConfig             = new List<object>(),
+                ControllerConfig           = new List<object>(),
                 InputConfig                = Hid.InputConfig,
                 GraphicsBackend            = Graphics.GraphicsBackend,
                 PreferredGpu               = Graphics.PreferredGpu
diff --git a/Ryujinx.Ui.Common/Configuration/System/Language.cs b/Ryujinx.Ui.Common/Configuration/System/Language.cs
index 404f8063d..3d2dc9914 100644
--- a/Ryujinx.Ui.Common/Configuration/System/Language.cs
+++ b/Ryujinx.Ui.Common/Configuration/System/Language.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Configuration.System
+namespace Ryujinx.Ui.Common.Configuration.System
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<Language>))]
     public enum Language
     {
         Japanese,
diff --git a/Ryujinx.Ui.Common/Configuration/System/Region.cs b/Ryujinx.Ui.Common/Configuration/System/Region.cs
index 7dfac6388..fb51e08e5 100644
--- a/Ryujinx.Ui.Common/Configuration/System/Region.cs
+++ b/Ryujinx.Ui.Common/Configuration/System/Region.cs
@@ -1,9 +1,5 @@
-using Ryujinx.Common.Utilities;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Configuration.System
+namespace Ryujinx.Ui.Common.Configuration.System
 {
-    [JsonConverter(typeof(TypedStringEnumConverter<Region>))]
     public enum Region
     {
         Japan,
diff --git a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs b/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs
deleted file mode 100644
index f412b9504..000000000
--- a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApi.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Models.Amiibo
-{
-    public struct AmiiboApi : IEquatable<AmiiboApi>
-    {
-        [JsonPropertyName("name")]
-        public string Name { get; set; }
-        [JsonPropertyName("head")]
-        public string Head { get; set; }
-        [JsonPropertyName("tail")]
-        public string Tail { get; set; }
-        [JsonPropertyName("image")]
-        public string Image { get; set; }
-        [JsonPropertyName("amiiboSeries")]
-        public string AmiiboSeries { get; set; }
-        [JsonPropertyName("character")]
-        public string Character { get; set; }
-        [JsonPropertyName("gameSeries")]
-        public string GameSeries { get; set; }
-        [JsonPropertyName("type")]
-        public string Type { get; set; }
-
-        [JsonPropertyName("release")]
-        public Dictionary<string, string> Release { get; set; }
-
-        [JsonPropertyName("gamesSwitch")]
-        public List<AmiiboApiGamesSwitch> GamesSwitch { get; set; }
-
-        public override string ToString()
-        {
-            return Name;
-        }
-
-        public string GetId()
-        {
-            return Head + Tail;
-        }
-
-        public bool Equals(AmiiboApi other)
-        {
-            return Head + Tail == other.Head + other.Tail;
-        }
-
-        public override bool Equals(object obj)
-        {
-            return obj is AmiiboApi other && Equals(other);
-        }
-
-        public override int GetHashCode()
-        {
-            return HashCode.Combine(Head, Tail);
-        }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs b/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs
deleted file mode 100644
index def7d1bcc..000000000
--- a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiGamesSwitch.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Models.Amiibo
-{
-    public class AmiiboApiGamesSwitch
-    {
-        [JsonPropertyName("amiiboUsage")]
-        public List<AmiiboApiUsage> AmiiboUsage { get; set; }
-        [JsonPropertyName("gameID")]
-        public List<string> GameId { get; set; }
-        [JsonPropertyName("gameName")]
-        public string GameName { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs b/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs
deleted file mode 100644
index 814573c22..000000000
--- a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboApiUsage.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Models.Amiibo
-{
-    public class AmiiboApiUsage
-    {
-        [JsonPropertyName("Usage")]
-        public string Usage { get; set; }
-        [JsonPropertyName("write")]
-        public bool Write { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs b/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs
deleted file mode 100644
index feb7993c1..000000000
--- a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJson.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Models.Amiibo
-{
-    public struct AmiiboJson
-    {
-        [JsonPropertyName("amiibo")]
-        public List<AmiiboApi> Amiibo { get; set; }
-        [JsonPropertyName("lastUpdated")]
-        public DateTime LastUpdated { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs b/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs
deleted file mode 100644
index 4cbb5a7b4..000000000
--- a/Ryujinx.Ui.Common/Models/Amiibo/AmiiboJsonSerializerContext.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Models.Amiibo
-{
-    [JsonSerializable(typeof(AmiiboJson))]
-    public partial class AmiiboJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs b/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs
deleted file mode 100644
index 10d014783..000000000
--- a/Ryujinx.Ui.Common/Models/Github/GithubReleaseAssetJsonResponse.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Ryujinx.Ui.Common.Models.Github
-{
-    public class GithubReleaseAssetJsonResponse
-    {
-        public string Name { get; set; }
-        public string State { get; set; }
-        public string BrowserDownloadUrl { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs b/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs
deleted file mode 100644
index 954d03e31..000000000
--- a/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonResponse.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System.Collections.Generic;
-
-namespace Ryujinx.Ui.Common.Models.Github
-{
-    public class GithubReleasesJsonResponse
-    {
-        public string Name { get; set; }
-        public List<GithubReleaseAssetJsonResponse> Assets { get; set; }
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs b/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs
deleted file mode 100644
index e5fd9d094..000000000
--- a/Ryujinx.Ui.Common/Models/Github/GithubReleasesJsonSerializerContext.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Text.Json.Serialization;
-
-namespace Ryujinx.Ui.Common.Models.Github
-{
-    [JsonSerializable(typeof(GithubReleasesJsonResponse), GenerationMode = JsonSourceGenerationMode.Metadata)]
-    public partial class GithubReleasesJsonSerializerContext : JsonSerializerContext
-    {
-    }
-}
\ No newline at end of file
diff --git a/Ryujinx/Modules/Updater/Updater.cs b/Ryujinx/Modules/Updater/Updater.cs
index 3f186ce6b..5ad5924e8 100644
--- a/Ryujinx/Modules/Updater/Updater.cs
+++ b/Ryujinx/Modules/Updater/Updater.cs
@@ -2,14 +2,14 @@ using Gtk;
 using ICSharpCode.SharpZipLib.GZip;
 using ICSharpCode.SharpZipLib.Tar;
 using ICSharpCode.SharpZipLib.Zip;
+using Newtonsoft.Json.Linq;
 using Ryujinx.Common;
 using Ryujinx.Common.Logging;
-using Ryujinx.Common.Utilities;
 using Ryujinx.Ui;
-using Ryujinx.Ui.Common.Models.Github;
 using Ryujinx.Ui.Widgets;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Linq;
 using System.Net;
@@ -38,8 +38,6 @@ namespace Ryujinx.Modules
         private static string _buildUrl;
         private static long   _buildSize;
 
-        private static readonly GithubReleasesJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         // On Windows, GtkSharp.Dependencies adds these extra dirs that must be cleaned during updates.
         private static readonly string[] WindowsDependencyDirs = new string[] { "bin", "etc", "lib", "share" };
 
@@ -109,16 +107,22 @@ namespace Ryujinx.Modules
 
                 // Fetch latest build information
                 string  fetchedJson = await jsonClient.GetStringAsync(buildInfoURL);
-                var fetched = JsonHelper.Deserialize(fetchedJson, SerializerContext.GithubReleasesJsonResponse);
-                _buildVer = fetched.Name;
+                JObject jsonRoot    = JObject.Parse(fetchedJson);
+                JToken  assets      = jsonRoot["assets"];
 
-                foreach (var asset in fetched.Assets)
+                _buildVer = (string)jsonRoot["name"];
+
+                foreach (JToken asset in assets)
                 {
-                    if (asset.Name.StartsWith("ryujinx") && asset.Name.EndsWith(_platformExt))
-                    {
-                        _buildUrl = asset.BrowserDownloadUrl;
+                    string assetName = (string)asset["name"];
+                    string assetState = (string)asset["state"];
+                    string downloadURL = (string)asset["browser_download_url"];
 
-                        if (asset.State != "uploaded")
+                    if (assetName.StartsWith("ryujinx") && assetName.EndsWith(_platformExt))
+                    {
+                        _buildUrl = downloadURL;
+
+                        if (assetState != "uploaded")
                         {
                             if (showVersionUpToDate)
                             {
diff --git a/Ryujinx/Ui/Windows/AboutWindow.cs b/Ryujinx/Ui/Windows/AboutWindow.cs
index 41cf9c013..ea827a92f 100644
--- a/Ryujinx/Ui/Windows/AboutWindow.cs
+++ b/Ryujinx/Ui/Windows/AboutWindow.cs
@@ -31,7 +31,7 @@ namespace Ryujinx.Ui.Windows
             {
                 string patreonJsonString = await httpClient.GetStringAsync("https://patreon.ryujinx.org/");
 
-                _patreonNamesText.Buffer.Text = string.Join(", ", JsonHelper.Deserialize(patreonJsonString, CommonJsonContext.Default.StringArray));
+                _patreonNamesText.Buffer.Text = string.Join(", ", JsonHelper.Deserialize<string[]>(patreonJsonString));
             }
             catch
             {
diff --git a/Ryujinx/Ui/Windows/AmiiboWindow.cs b/Ryujinx/Ui/Windows/AmiiboWindow.cs
index 470032373..9140a14e9 100644
--- a/Ryujinx/Ui/Windows/AmiiboWindow.cs
+++ b/Ryujinx/Ui/Windows/AmiiboWindow.cs
@@ -3,7 +3,6 @@ using Ryujinx.Common;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Utilities;
 using Ryujinx.Ui.Common.Configuration;
-using Ryujinx.Ui.Common.Models.Amiibo;
 using Ryujinx.Ui.Widgets;
 using System;
 using System.Collections.Generic;
@@ -12,15 +11,65 @@ using System.Linq;
 using System.Net.Http;
 using System.Reflection;
 using System.Text;
-using System.Text.Json;
+using System.Text.Json.Serialization;
 using System.Threading.Tasks;
-using AmiiboApi = Ryujinx.Ui.Common.Models.Amiibo.AmiiboApi;
-using AmiiboJsonSerializerContext = Ryujinx.Ui.Common.Models.Amiibo.AmiiboJsonSerializerContext;
 
 namespace Ryujinx.Ui.Windows
 {
     public partial class AmiiboWindow : Window
     {
+        private struct AmiiboJson
+        {
+            [JsonPropertyName("amiibo")]
+            public List<AmiiboApi> Amiibo { get; set; }
+            [JsonPropertyName("lastUpdated")]
+            public DateTime LastUpdated { get; set; }
+        }
+
+        private struct AmiiboApi
+        {
+            [JsonPropertyName("name")]
+            public string Name { get; set; }
+            [JsonPropertyName("head")]
+            public string Head { get; set; }
+            [JsonPropertyName("tail")]
+            public string Tail { get; set; }
+            [JsonPropertyName("image")]
+            public string Image { get; set; }
+            [JsonPropertyName("amiiboSeries")]
+            public string AmiiboSeries { get; set; }
+            [JsonPropertyName("character")]
+            public string Character { get; set; }
+            [JsonPropertyName("gameSeries")]
+            public string GameSeries { get; set; }
+            [JsonPropertyName("type")]
+            public string Type { get; set; }
+
+            [JsonPropertyName("release")]
+            public Dictionary<string, string> Release { get; set; }
+
+            [JsonPropertyName("gamesSwitch")]
+            public List<AmiiboApiGamesSwitch> GamesSwitch { get; set; }
+        }
+
+        private class AmiiboApiGamesSwitch
+        {
+            [JsonPropertyName("amiiboUsage")]
+            public List<AmiiboApiUsage> AmiiboUsage { get; set; }
+            [JsonPropertyName("gameID")]
+            public List<string> GameId { get; set; }
+            [JsonPropertyName("gameName")]
+            public string GameName { get; set; }
+        }
+
+        private class AmiiboApiUsage
+        {
+            [JsonPropertyName("Usage")]
+            public string Usage { get; set; }
+            [JsonPropertyName("write")]
+            public bool Write { get; set; }
+        }
+
         private const string DEFAULT_JSON = "{ \"amiibo\": [] }";
 
         public string AmiiboId { get; private set; }
@@ -47,8 +96,6 @@ namespace Ryujinx.Ui.Windows
 
         private List<AmiiboApi> _amiiboList;
 
-        private static readonly AmiiboJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         public AmiiboWindow() : base($"Ryujinx {Program.Version} - Amiibo")
         {
             Icon = new Gdk.Pixbuf(Assembly.GetAssembly(typeof(ConfigurationState)), "Ryujinx.Ui.Common.Resources.Logo_Ryujinx.png");
@@ -80,9 +127,9 @@ namespace Ryujinx.Ui.Windows
 
             if (File.Exists(_amiiboJsonPath))
             {
-                amiiboJsonString = await File.ReadAllTextAsync(_amiiboJsonPath);
+                amiiboJsonString = File.ReadAllText(_amiiboJsonPath);
 
-                if (await NeedsUpdate(JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).LastUpdated))
+                if (await NeedsUpdate(JsonHelper.Deserialize<AmiiboJson>(amiiboJsonString).LastUpdated))
                 {
                     amiiboJsonString = await DownloadAmiiboJson();
                 }
@@ -101,7 +148,7 @@ namespace Ryujinx.Ui.Windows
                 }
             }
 
-            _amiiboList = JsonHelper.Deserialize(amiiboJsonString, SerializerContext.AmiiboJson).Amiibo;
+            _amiiboList = JsonHelper.Deserialize<AmiiboJson>(amiiboJsonString).Amiibo;
             _amiiboList = _amiiboList.OrderBy(amiibo => amiibo.AmiiboSeries).ToList();
 
             if (LastScannedAmiiboShowAll)
diff --git a/Ryujinx/Ui/Windows/ControllerWindow.cs b/Ryujinx/Ui/Windows/ControllerWindow.cs
index 9b4befd85..0f0fba0b8 100644
--- a/Ryujinx/Ui/Windows/ControllerWindow.cs
+++ b/Ryujinx/Ui/Windows/ControllerWindow.cs
@@ -115,8 +115,6 @@ namespace Ryujinx.Ui.Windows
         private bool _mousePressed;
         private bool _middleMousePressed;
 
-        private static readonly InputConfigJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
         public ControllerWindow(MainWindow mainWindow, PlayerIndex controllerId) : this(mainWindow, new Builder("Ryujinx.Ui.Windows.ControllerWindow.glade"), controllerId) { }
 
         private ControllerWindow(MainWindow mainWindow, Builder builder, PlayerIndex controllerId) : base(builder.GetRawOwnedObject("_controllerWin"))
@@ -1122,7 +1120,10 @@ namespace Ryujinx.Ui.Windows
 
                 try
                 {
-                    config = JsonHelper.DeserializeFromFile(path, SerializerContext.InputConfig);
+                    using (Stream stream = File.OpenRead(path))
+                    {
+                        config = JsonHelper.Deserialize<InputConfig>(stream);
+                    }
                 }
                 catch (JsonException) { }
             }
@@ -1144,7 +1145,9 @@ namespace Ryujinx.Ui.Windows
             if (profileDialog.Run() == (int)ResponseType.Ok)
             {
                 string path = System.IO.Path.Combine(GetProfileBasePath(), profileDialog.FileName);
-                string jsonString = JsonHelper.Serialize(inputConfig, SerializerContext.InputConfig);
+                string jsonString;
+
+                jsonString = JsonHelper.Serialize(inputConfig, true);
 
                 File.WriteAllText(path, jsonString);
             }
diff --git a/Ryujinx/Ui/Windows/DlcWindow.cs b/Ryujinx/Ui/Windows/DlcWindow.cs
index b22f15932..9fccec195 100644
--- a/Ryujinx/Ui/Windows/DlcWindow.cs
+++ b/Ryujinx/Ui/Windows/DlcWindow.cs
@@ -7,13 +7,15 @@ using LibHac.Tools.Fs;
 using LibHac.Tools.FsSystem;
 using LibHac.Tools.FsSystem.NcaUtils;
 using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Utilities;
 using Ryujinx.HLE.FileSystem;
 using Ryujinx.Ui.Widgets;
 using System;
 using System.Collections.Generic;
 using System.IO;
-using GUI = Gtk.Builder.ObjectAttribute;
+using System.Text;
+
+using GUI        = Gtk.Builder.ObjectAttribute;
+using JsonHelper = Ryujinx.Common.Utilities.JsonHelper;
 
 namespace Ryujinx.Ui.Windows
 {
@@ -24,8 +26,6 @@ namespace Ryujinx.Ui.Windows
         private readonly string                             _dlcJsonPath;
         private readonly List<DownloadableContentContainer> _dlcContainerList;
 
-        private static readonly DownloadableContentJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
-
 #pragma warning disable CS0649, IDE0044
         [GUI] Label         _baseTitleInfoLabel;
         [GUI] TreeView      _dlcTreeView;
@@ -45,7 +45,7 @@ namespace Ryujinx.Ui.Windows
 
             try
             {
-                _dlcContainerList = JsonHelper.DeserializeFromFile(_dlcJsonPath, SerializerContext.ListDownloadableContentContainer);
+                _dlcContainerList = JsonHelper.DeserializeFromFile<List<DownloadableContentContainer>>(_dlcJsonPath);
             }
             catch
             {
@@ -260,7 +260,10 @@ namespace Ryujinx.Ui.Windows
                 while (_dlcTreeView.Model.IterNext(ref parentIter));
             }
 
-            JsonHelper.SerializeToFile(_dlcJsonPath, _dlcContainerList, SerializerContext.ListDownloadableContentContainer);
+            using (FileStream dlcJsonStream = File.Create(_dlcJsonPath, 4096, FileOptions.WriteThrough))
+            {
+                dlcJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_dlcContainerList, true)));
+            }
 
             Dispose();
         }
diff --git a/Ryujinx/Ui/Windows/TitleUpdateWindow.cs b/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
index 226473fca..4aea58955 100644
--- a/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
+++ b/Ryujinx/Ui/Windows/TitleUpdateWindow.cs
@@ -7,7 +7,6 @@ using LibHac.Ns;
 using LibHac.Tools.FsSystem;
 using LibHac.Tools.FsSystem.NcaUtils;
 using Ryujinx.Common.Configuration;
-using Ryujinx.Common.Utilities;
 using Ryujinx.HLE.FileSystem;
 using Ryujinx.HLE.HOS;
 using Ryujinx.Ui.Widgets;
@@ -15,8 +14,10 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
-using GUI         = Gtk.Builder.ObjectAttribute;
-using SpanHelpers = LibHac.Common.SpanHelpers;
+using System.Text;
+
+using GUI        = Gtk.Builder.ObjectAttribute;
+using JsonHelper = Ryujinx.Common.Utilities.JsonHelper;
 
 namespace Ryujinx.Ui.Windows
 {
@@ -30,7 +31,6 @@ namespace Ryujinx.Ui.Windows
         private TitleUpdateMetadata _titleUpdateWindowData;
 
         private readonly Dictionary<RadioButton, string> _radioButtonToPathDictionary;
-        private static readonly TitleUpdateMetadataJsonSerializerContext SerializerContext = new(JsonHelper.GetDefaultSerializerOptions());
 
 #pragma warning disable CS0649, IDE0044
         [GUI] Label       _baseTitleInfoLabel;
@@ -53,7 +53,7 @@ namespace Ryujinx.Ui.Windows
 
             try
             {
-                _titleUpdateWindowData = JsonHelper.DeserializeFromFile(_updateJsonPath, SerializerContext.TitleUpdateMetadata);
+                _titleUpdateWindowData = JsonHelper.DeserializeFromFile<TitleUpdateMetadata>(_updateJsonPath);
             }
             catch
             {
@@ -192,7 +192,10 @@ namespace Ryujinx.Ui.Windows
                 }
             }
 
-            JsonHelper.SerializeToFile(_updateJsonPath, _titleUpdateWindowData, SerializerContext.TitleUpdateMetadata);
+            using (FileStream dlcJsonStream = File.Create(_updateJsonPath, 4096, FileOptions.WriteThrough))
+            {
+                dlcJsonStream.Write(Encoding.UTF8.GetBytes(JsonHelper.Serialize(_titleUpdateWindowData, true)));
+            }
 
             _parent.UpdateGameTable();