diff --git a/steam-runtime-tools/json-utils-internal.h b/steam-runtime-tools/json-utils-internal.h
new file mode 100644
index 0000000000000000000000000000000000000000..af01e3ef89b69ab4fce51c3182b13d17d66d7810
--- /dev/null
+++ b/steam-runtime-tools/json-utils-internal.h
@@ -0,0 +1,44 @@
+/*<private_header>*/
+/*
+ * Copyright © 2019-2020 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <stdio.h>
+
+#include <glib.h>
+
+#include <json-glib/json-glib.h>
+
+#include <steam-runtime-tools/macros.h>
+
+_SRT_PRIVATE_EXPORT
+guint srt_get_flags_from_json_array (GType flags_type,
+                                     JsonObject *json_obj,
+                                     const gchar *array_member,
+                                     guint flag_if_unknown);
+
+gchar ** _srt_json_array_to_strv (JsonObject *json_obj,
+                                  const gchar *array_member);
diff --git a/steam-runtime-tools/json-utils.c b/steam-runtime-tools/json-utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..a752f12672d95a08083e5df43a54a9b9e8df3af7
--- /dev/null
+++ b/steam-runtime-tools/json-utils.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright © 2019-2020 Collabora Ltd.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "steam-runtime-tools/json-utils-internal.h"
+
+#include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/utils-internal.h"
+
+/**
+ * srt_get_flags_from_json_array:
+ * @flags_type: The type of the flag
+ * @json_obj: (not nullable): A JSON Object used to search for
+ *  @array_member property
+ * @array_member: (not nullable): The JSON member to look up
+ * @flag_if_unknown: flag to use in case of parsing error
+ *
+ * Get the flags from a given JSON object array member.
+ * If @json_obj doesn't have the provided @member, or it is malformed, the
+ * @flag_if_unknown will be returned.
+ * If the parsed JSON array_member has some elements that we can't parse,
+ * @flag_if_unknown will be added to the returned flags.
+ *
+ * Returns: the found flags from the provided @json_obj
+ */
+guint
+srt_get_flags_from_json_array (GType flags_type,
+                               JsonObject *json_obj,
+                               const gchar *array_member,
+                               guint flag_if_unknown)
+{
+  JsonArray *array;
+  guint ret = flag_if_unknown;
+
+  g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), 0);
+  g_return_val_if_fail (json_obj != NULL, 0);
+  g_return_val_if_fail (array_member != NULL, 0);
+
+  if (json_object_has_member (json_obj, array_member))
+    {
+      array = json_object_get_array_member (json_obj, array_member);
+
+      if (array == NULL)
+        goto out;
+
+      /* We reset the value out because we found the member we were looking for */
+      ret = 0;
+
+      for (guint j = 0; j < json_array_get_length (array); j++)
+        {
+          const gchar *issue_string = json_array_get_string_element (array, j);
+          if (!srt_add_flag_from_nick (flags_type, issue_string, &ret, NULL))
+            ret |= flag_if_unknown;
+        }
+    }
+
+out:
+  return ret;
+}
+
+/**
+ * _srt_json_array_to_strv:
+ * @json_obj: (not nullable): A JSON Object used to search for
+ *  @array_member property
+ * @array_member: (not nullable): The JSON member to look up
+ *
+ * Every %NULL or non string members of the array are replaced with the value
+ * "<invalid>".
+ *
+ * Returns: (transfer full) (array zero-terminated=1) (element-type utf8) (nullable):
+ *  A string array from the given @json_obj, or %NULL if it doesn't have a
+ *  property @array_member
+ */
+gchar **
+_srt_json_array_to_strv (JsonObject *json_obj,
+                         const gchar *array_member)
+{
+  JsonArray *array;
+  guint length;
+  const gchar *element;
+  gchar **ret = NULL;
+
+  g_return_val_if_fail (json_obj != NULL, NULL);
+  g_return_val_if_fail (array_member != NULL, NULL);
+
+  if (json_object_has_member (json_obj, array_member))
+    {
+      array = json_object_get_array_member (json_obj, array_member);
+      if (array == NULL)
+        return ret;
+
+      length = json_array_get_length (array);
+      ret = g_new0 (gchar *, length + 1);
+      for (guint i = 0; i < length; i++)
+        {
+          element = json_array_get_string_element (array, i);
+          if (element == NULL)
+            element = "<invalid>";
+          ret[i] = g_strdup (element);
+        }
+      ret[length] = NULL;
+    }
+
+  return ret;
+}
diff --git a/steam-runtime-tools/library.c b/steam-runtime-tools/library.c
index a09c181490e903051aeafd4d0912a6cba93852f7..e77694aaff7af4aab8d51e0f19da38ecf4487c57 100644
--- a/steam-runtime-tools/library.c
+++ b/steam-runtime-tools/library.c
@@ -29,6 +29,7 @@
 #include "steam-runtime-tools/enums.h"
 #include "steam-runtime-tools/glib-backports-internal.h"
 #include "steam-runtime-tools/json-glib-backports-internal.h"
+#include "steam-runtime-tools/json-utils-internal.h"
 #include "steam-runtime-tools/library-internal.h"
 #include "steam-runtime-tools/utils.h"
 #include "steam-runtime-tools/utils-internal.h"
diff --git a/steam-runtime-tools/locale.c b/steam-runtime-tools/locale.c
index 8e46d9eb61027042d46011e3837f1637380492f6..4bc7249d0669c81761a2ab1b923717e0f584ab17 100644
--- a/steam-runtime-tools/locale.c
+++ b/steam-runtime-tools/locale.c
@@ -29,6 +29,7 @@
 #include "steam-runtime-tools/enums.h"
 #include "steam-runtime-tools/glib-backports-internal.h"
 #include "steam-runtime-tools/json-glib-backports-internal.h"
+#include "steam-runtime-tools/json-utils-internal.h"
 #include "steam-runtime-tools/locale-internal.h"
 #include "steam-runtime-tools/utils-internal.h"
 
diff --git a/steam-runtime-tools/meson.build b/steam-runtime-tools/meson.build
index 964a56fce530d7dc528baeb04ee8a934469729fc..6c0acce1c1f5ecc6f5a60ad4595b13942f88d6c4 100644
--- a/steam-runtime-tools/meson.build
+++ b/steam-runtime-tools/meson.build
@@ -34,6 +34,8 @@ libsteamrt_sources = [
     'graphics.c',
     'json-glib-backports.c',
     'json-glib-backports-internal.h',
+    'json-utils.c',
+    'json-utils-internal.h',
     'library-internal.h',
     'library.c',
     'locale-internal.h',
diff --git a/steam-runtime-tools/runtime.c b/steam-runtime-tools/runtime.c
index be908f2e3b7a297be6a10177b91558669614e04e..0cdd35405a250b3e1c1321af98316ad371b5a829 100644
--- a/steam-runtime-tools/runtime.c
+++ b/steam-runtime-tools/runtime.c
@@ -37,6 +37,7 @@
 #include <glib/gstdio.h>
 
 #include "steam-runtime-tools/glib-backports-internal.h"
+#include "steam-runtime-tools/json-utils-internal.h"
 #include "steam-runtime-tools/utils.h"
 
 /**
diff --git a/steam-runtime-tools/system-info.c b/steam-runtime-tools/system-info.c
index fef92aba2b1cf023f4c2a6f6b03b8fcc5269b4be..899a542c43f013ff23f8bc5846733ffc1aefcae2 100644
--- a/steam-runtime-tools/system-info.c
+++ b/steam-runtime-tools/system-info.c
@@ -36,6 +36,7 @@
 #include "steam-runtime-tools/desktop-entry-internal.h"
 #include "steam-runtime-tools/graphics.h"
 #include "steam-runtime-tools/graphics-internal.h"
+#include "steam-runtime-tools/json-utils-internal.h"
 #include "steam-runtime-tools/library-internal.h"
 #include "steam-runtime-tools/locale-internal.h"
 #include "steam-runtime-tools/os-internal.h"
diff --git a/steam-runtime-tools/utils-internal.h b/steam-runtime-tools/utils-internal.h
index 3609b4b888b1a59be2734f4fda56ea2232f134e5..3a7f0fba5871441d952de90dd25b7b23d188cc4d 100644
--- a/steam-runtime-tools/utils-internal.h
+++ b/steam-runtime-tools/utils-internal.h
@@ -30,8 +30,6 @@
 
 #include <glib.h>
 
-#include <json-glib/json-glib.h>
-
 #include <steam-runtime-tools/macros.h>
 
 typedef enum
@@ -73,12 +71,6 @@ gboolean srt_add_flag_from_nick (GType flags_type,
                                  guint *value_out,
                                  GError **error);
 
-_SRT_PRIVATE_EXPORT
-guint srt_get_flags_from_json_array (GType flags_type,
-                                     JsonObject *json_obj,
-                                     const gchar *array_member,
-                                     guint flag_if_unknown);
-
 G_GNUC_INTERNAL void _srt_child_setup_unblock_signals (gpointer ignored);
 
 _SRT_PRIVATE_EXPORT
@@ -87,9 +79,6 @@ void _srt_unblock_signals (void);
 G_GNUC_INTERNAL int _srt_indirect_strcmp0 (gconstpointer left,
                                            gconstpointer right);
 
-gchar ** _srt_json_array_to_strv (JsonObject *json_obj,
-                                  const gchar *array_member);
-
 _SRT_PRIVATE_EXPORT
 gboolean _srt_rm_rf (const char *directory);
 
diff --git a/steam-runtime-tools/utils.c b/steam-runtime-tools/utils.c
index a52f07947597aeb20efa87b3dc3fa024715be6a9..074a8ad3b19daec307893830f3e7938f097554f2 100644
--- a/steam-runtime-tools/utils.c
+++ b/steam-runtime-tools/utils.c
@@ -573,57 +573,6 @@ srt_add_flag_from_nick (GType flags_type,
   return result;
 }
 
-/**
- * srt_get_flags_from_json_array:
- * @flags_type: The type of the flag
- * @json_obj: (not nullable): A JSON Object used to search for
- *  @array_member property
- * @array_member: (not nullable): The JSON member to look up
- * @flag_if_unknown: flag to use in case of parsing error
- *
- * Get the flags from a given JSON object array member.
- * If @json_obj doesn't have the provided @member, or it is malformed, the
- * @flag_if_unknown will be returned.
- * If the parsed JSON array_member has some elements that we can't parse,
- * @flag_if_unknown will be added to the returned flags.
- *
- * Returns: the found flags from the provided @json_obj
- */
-guint
-srt_get_flags_from_json_array (GType flags_type,
-                               JsonObject *json_obj,
-                               const gchar *array_member,
-                               guint flag_if_unknown)
-{
-  JsonArray *array;
-  guint ret = flag_if_unknown;
-
-  g_return_val_if_fail (G_TYPE_IS_FLAGS (flags_type), 0);
-  g_return_val_if_fail (json_obj != NULL, 0);
-  g_return_val_if_fail (array_member != NULL, 0);
-
-  if (json_object_has_member (json_obj, array_member))
-    {
-      array = json_object_get_array_member (json_obj, array_member);
-
-      if (array == NULL)
-        goto out;
-
-      /* We reset the value out because we found the member we were looking for */
-      ret = 0;
-
-      for (guint j = 0; j < json_array_get_length (array); j++)
-        {
-          const gchar *issue_string = json_array_get_string_element (array, j);
-          if (!srt_add_flag_from_nick (flags_type, issue_string, &ret, NULL))
-            ret |= flag_if_unknown;
-        }
-    }
-
-out:
-  return ret;
-}
-
 static void _srt_constructor (void) __attribute__((__constructor__));
 static void
 _srt_constructor (void)
@@ -787,52 +736,6 @@ _srt_rm_rf (const char *directory)
   return TRUE;
 }
 
-/**
- * _srt_json_array_to_strv:
- * @json_obj: (not nullable): A JSON Object used to search for
- *  @array_member property
- * @array_member: (not nullable): The JSON member to look up
- *
- * Every %NULL or non string members of the array are replaced with the value
- * "<invalid>".
- *
- * Returns: (transfer full) (array zero-terminated=1) (element-type utf8) (nullable):
- *  A string array from the given @json_obj, or %NULL if it doesn't have a
- *  property @array_member
- */
-gchar **
-_srt_json_array_to_strv (JsonObject *json_obj,
-                         const gchar *array_member)
-{
-  JsonArray *array;
-  guint length;
-  const gchar *element;
-  gchar **ret = NULL;
-
-  g_return_val_if_fail (json_obj != NULL, NULL);
-  g_return_val_if_fail (array_member != NULL, NULL);
-
-  if (json_object_has_member (json_obj, array_member))
-    {
-      array = json_object_get_array_member (json_obj, array_member);
-      if (array == NULL)
-        return ret;
-
-      length = json_array_get_length (array);
-      ret = g_new0 (gchar *, length + 1);
-      for (guint i = 0; i < length; i++)
-        {
-          element = json_array_get_string_element (array, i);
-          if (element == NULL)
-            element = "<invalid>";
-          ret[i] = g_strdup (element);
-        }
-      ret[length] = NULL;
-    }
-
-  return ret;
-}
-
 /*
  * _srt_divert_stdout_to_stderr:
  * @error: Used to raise an error on failure
diff --git a/steam-runtime-tools/xdg-portal.c b/steam-runtime-tools/xdg-portal.c
index 5c32df417370036bcc476f95588bd02015913d4f..fb3c56a950fdec881d84c1bbb149da4c0057d02c 100644
--- a/steam-runtime-tools/xdg-portal.c
+++ b/steam-runtime-tools/xdg-portal.c
@@ -28,6 +28,7 @@
 #include "steam-runtime-tools/enums.h"
 #include "steam-runtime-tools/glib-backports-internal.h"
 #include "steam-runtime-tools/json-glib-backports-internal.h"
+#include "steam-runtime-tools/json-utils-internal.h"
 #include "steam-runtime-tools/xdg-portal-internal.h"
 #include "steam-runtime-tools/utils.h"
 #include "steam-runtime-tools/utils-internal.h"