diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9fa231fb72e317eccebca3c1655ce1943879f241..cf8511470fa22bd741ccf5c9440e78806c1b7b73 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -3,7 +3,7 @@ stages:
   - 'deploy'
 
 .build:
-  image: 'registry.fedoraproject.org/fedora:35'
+  image: 'registry.fedoraproject.org/fedora:42'
   stage: 'build'
   variables:
     CCACHE_BASEDIR: "${CI_PROJECT_DIR}"
@@ -17,7 +17,6 @@ stages:
       redhat-rpm-config
       glib2-devel
       gtk3-devel
-      gobject-introspection-devel
       python2-devel
       python3-devel
       xorg-x11-server-Xvfb
diff --git a/NEWS b/NEWS
index 3653badadeb2305ea4db4e9f6ff8ab9c042fc9de..a716c1a41a0818b33bd5bcea9ad9f9b86ee6f7db 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,16 @@
+Overview of Changes in libpeas 1.38.0.alpha
+===========================================
+
+ * Break ABI to support girepository-2.0. This is required as language
+   bindings are moving to the same GIRepository version. We will try to
+   minimize application changes as much as possible but it is likely that
+   applications using libpeas will need to be recompiled and update any
+   local usage of GIRepository to the new girepository-2.0.
+
+   As libpeas-2.0 does not link against gobject-introspection-1.0 or
+   libgirepository-2.0, it is unaffected. You may find it a better use
+   of time to port to libpeas-2.x instead.
+
 Overview of Changes in libpeas 1.36.0
 =====================================
 
diff --git a/libpeas-gtk/peas-gtk-plugin-manager.c b/libpeas-gtk/peas-gtk-plugin-manager.c
index 9d7d8127a5b94ffcd2b803f091a05601614a6d2a..4841177b8b1d8e04298a48497a796bc5ad43123b 100644
--- a/libpeas-gtk/peas-gtk-plugin-manager.c
+++ b/libpeas-gtk/peas-gtk-plugin-manager.c
@@ -27,7 +27,7 @@
 #endif
 
 #include <string.h>
-#include <girepository.h>
+#include <girepository/girepository.h>
 
 #ifdef OS_OSX
 #include "peas-utils-osx.h"
@@ -337,6 +337,7 @@ static void
 peas_gtk_plugin_manager_init (PeasGtkPluginManager *pm)
 {
   PeasGtkPluginManagerPrivate *priv = peas_gtk_plugin_manager_get_instance_private (pm);
+  GIRepository *repository;
   GtkWidget *toolbar;
   GtkStyleContext *context;
   GtkToolItem *toolitem;
@@ -345,8 +346,8 @@ peas_gtk_plugin_manager_init (PeasGtkPluginManager *pm)
 
   /* If we are using a PeasGtkPluginManager, we know for sure we will be using
      libpeas-gtk, so let's load the typelib for it here. */
-  g_irepository_require (g_irepository_get_default (),
-                         "PeasGtk", "1.0", 0, NULL);
+  repository = gi_repository_dup_default ();
+  gi_repository_require (repository, "PeasGtk", "1.0", 0, NULL);
 
   gtk_orientable_set_orientation (GTK_ORIENTABLE (pm),
                                   GTK_ORIENTATION_VERTICAL);
@@ -402,6 +403,8 @@ peas_gtk_plugin_manager_init (PeasGtkPluginManager *pm)
                     "clicked",
                     G_CALLBACK (show_configure_cb),
                     pm);
+
+  g_clear_object (&repository);
 }
 
 static void
diff --git a/libpeas/meson.build b/libpeas/meson.build
index 2583173021c8f755155943c5ccbedca6ba85c233..d00a0c764889cb9054def843ef53210c2d784182 100644
--- a/libpeas/meson.build
+++ b/libpeas/meson.build
@@ -118,7 +118,7 @@ if generate_gir == true
     'GObject-2.0',
     'GModule-2.0',
     'Gio-2.0',
-    'GIRepository-2.0'
+    'GIRepository-3.0'
   ]
 
   libpeas_gir = gnome.generate_gir(
@@ -157,7 +157,7 @@ libpeas_pc_reqs = [
   'gobject-2.0 @0@'.format(glib_req),
   'gmodule-2.0 @0@'.format(glib_req),
   'gio-2.0 @0@'.format(glib_req),
-  'gobject-introspection-1.0 @0@'.format(introspection_req),
+  'girepository-2.0 @0@'.format(glib_req),
 ]
 
 libpeas_pc = pkg.generate(
diff --git a/libpeas/peas-extension-set.c b/libpeas/peas-extension-set.c
index 8435d9b35c7c800f820abb3811a0d9a2886af3ff..44d3fe0df3da5291baac64e6fab81f913623fa14 100644
--- a/libpeas/peas-extension-set.c
+++ b/libpeas/peas-extension-set.c
@@ -552,13 +552,13 @@ peas_extension_set_call_valist (PeasExtensionSet *set,
       return FALSE;
     }
 
-  n_args = g_callable_info_get_n_args (callable_info);
+  n_args = gi_callable_info_get_n_args (callable_info);
   g_return_val_if_fail (n_args >= 0, FALSE);
 
   args = g_newa (GIArgument, n_args);
   peas_gi_valist_to_arguments (callable_info, va_args, args, NULL);
 
-  g_base_info_unref ((GIBaseInfo *) callable_info);
+  gi_base_info_unref ((GIBaseInfo *) callable_info);
 
   return peas_extension_set_callv (set, method_name, args);
 }
diff --git a/libpeas/peas-extension.c b/libpeas/peas-extension.c
index cc593568ca774552b73c725174fdc41dd5f765f5..382594aa1a5f89c5204f65dd9c19313fcdb39d30 100644
--- a/libpeas/peas-extension.c
+++ b/libpeas/peas-extension.c
@@ -40,8 +40,8 @@
  * to load the required "Peas" typelib:
  *
  * ```c
- * g_irepository_require (g_irepository_get_default (),
- *                        "Peas", "1.0", 0, NULL);
+ * GIRepository *repository = gi_repository_dup_default ();
+ * gi_repository_require (repository, "Peas", "1.0", 0, NULL);
  * ```
  *
  * You should proceed the same way for any namespace which provides types
@@ -145,7 +145,7 @@ peas_extension_get_extension_type (PeasExtension *exten)
  * |[ peas_extension_call (extension, "my_method", "some_str", obj, &gint_var); ]|
  *
  * This function will not do anything if the introspection data for the proxied
- * object's class has not been loaded previously through g_irepository_require().
+ * object's class has not been loaded previously through gi_repository_require().
  *
  * Returns: %TRUE on successful call.
  *
@@ -205,7 +205,7 @@ peas_extension_call_valist (PeasExtension *exten,
   if (callable_info == NULL)
     return FALSE;
 
-  n_args = g_callable_info_get_n_args (callable_info);
+  n_args = gi_callable_info_get_n_args (callable_info);
   g_return_val_if_fail (n_args >= 0, FALSE);
   gargs = g_newa (GIArgument, n_args);
   peas_gi_valist_to_arguments (callable_info, args, gargs, &retval_ptr);
@@ -214,11 +214,12 @@ peas_extension_call_valist (PeasExtension *exten,
 
   if (retval_ptr != NULL)
     {
-      g_callable_info_load_return_type (callable_info, &retval_info);
+      gi_callable_info_load_return_type (callable_info, &retval_info);
       peas_gi_argument_to_pointer (&retval_info, &retval, retval_ptr);
+      gi_base_info_clear (&retval_info);
     }
 
-  g_base_info_unref ((GIBaseInfo *) callable_info);
+  gi_base_info_unref ((GIBaseInfo *) callable_info);
 
   return ret;
 }
@@ -260,6 +261,6 @@ peas_extension_callv (PeasExtension *exten,
   success = peas_gi_method_call (G_OBJECT (exten), method_info, gtype,
                                  method_name, args, return_value);
 
-  g_base_info_unref (method_info);
+  gi_base_info_unref (method_info);
   return success;
 }
diff --git a/libpeas/peas-extension.h b/libpeas/peas-extension.h
index 2ac80aa51f45b5f3e0e94f50f136d3064a6ac624..6afb53b45b333ba109f8d879cc7c2d16c58660e9 100644
--- a/libpeas/peas-extension.h
+++ b/libpeas/peas-extension.h
@@ -23,7 +23,7 @@
 #define __PEAS_EXTENSION_H__
 
 #include <glib-object.h>
-#include <girepository.h>
+#include <girepository/girepository.h>
 
 #include "peas-version-macros.h"
 
diff --git a/libpeas/peas-introspection.c b/libpeas/peas-introspection.c
index 49ac17852165d3d3eaf7d823666537b87a7f01f1..93a4f2c367f76bfe059c7a29be5b1e376b3f8086 100644
--- a/libpeas/peas-introspection.c
+++ b/libpeas/peas-introspection.c
@@ -34,22 +34,22 @@ peas_gi_valist_to_arguments (GICallableInfo *callable_info,
                              gpointer       *return_value)
 {
   gint i, n_args;
-  GIArgInfo arg_info;
-  GITypeInfo arg_type_info;
-  GITypeInfo retval_info;
   GIArgument *cur_arg;
 
   g_return_if_fail (callable_info != NULL);
 
-  n_args = g_callable_info_get_n_args (callable_info);
+  n_args = gi_callable_info_get_n_args (callable_info);
 
   for (i = 0; i < n_args; i++)
     {
-      g_callable_info_load_arg (callable_info, i, &arg_info);
-      g_arg_info_load_type (&arg_info, &arg_type_info);
+      GIArgInfo arg_info;
+      GITypeInfo arg_type_info;
+
+      gi_callable_info_load_arg (callable_info, i, &arg_info);
+      gi_arg_info_load_type_info (&arg_info, &arg_type_info);
       cur_arg = &arguments[i];
 
-      switch (g_arg_info_get_direction (&arg_info))
+      switch (gi_arg_info_get_direction (&arg_info))
         {
         case GI_DIRECTION_IN:
           {
@@ -57,7 +57,7 @@ peas_gi_valist_to_arguments (GICallableInfo *callable_info,
              *  - int8, uint8, int16, uint16, short and ushort are promoted to int when passed through '...'
              *  - float is promoted to double when passed through '...'
              */
-            switch (g_type_info_get_tag (&arg_type_info))
+            switch (gi_type_info_get_tag (&arg_type_info))
               {
               case GI_TYPE_TAG_VOID:
                 cur_arg->v_pointer = va_arg (va_args, gpointer);
@@ -125,13 +125,17 @@ peas_gi_valist_to_arguments (GICallableInfo *callable_info,
           cur_arg->v_pointer = va_arg (va_args, gpointer);
           break;
         }
+
+      gi_base_info_clear (&arg_type_info);
     }
 
   if (return_value != NULL)
     {
-      g_callable_info_load_return_type (callable_info, &retval_info);
+      GITypeInfo retval_info;
 
-      if (g_type_info_get_tag (&retval_info) != GI_TYPE_TAG_VOID)
+      gi_callable_info_load_return_type (callable_info, &retval_info);
+
+      if (gi_type_info_get_tag (&retval_info) != GI_TYPE_TAG_VOID)
         *return_value = va_arg (va_args, gpointer);
       else
         *return_value = NULL;
@@ -151,13 +155,13 @@ peas_gi_split_in_and_out_arguments (GICallableInfo *callable_info,
 
   g_return_if_fail (callable_info != NULL);
 
-  n_args = g_callable_info_get_n_args (callable_info);
+  n_args = gi_callable_info_get_n_args (callable_info);
 
   for (i = 0; i < n_args; i++)
     {
-      g_callable_info_load_arg (callable_info, i, &arg_info);
+      gi_callable_info_load_arg (callable_info, i, &arg_info);
 
-      switch (g_arg_info_get_direction (&arg_info))
+      switch (gi_arg_info_get_direction (&arg_info))
         {
         case GI_DIRECTION_IN:
           in_args[(*n_in_args)++] = args[i];
@@ -178,7 +182,7 @@ peas_gi_argument_to_pointer (GITypeInfo     *type_info,
                              GIArgument     *arg,
                              gpointer        ptr)
 {
-  switch (g_type_info_get_tag (type_info))
+  switch (gi_type_info_get_tag (type_info))
     {
     case GI_TYPE_TAG_VOID:
       *((gpointer **) ptr) = arg->v_pointer;
@@ -246,31 +250,27 @@ peas_gi_get_method_info (GType        gtype,
   GIBaseInfo *type_info;
   GIFunctionInfo *func_info;
 
-  repo = g_irepository_get_default ();
-  type_info = g_irepository_find_by_gtype (repo, gtype);
+  repo = gi_repository_dup_default ();
+  type_info = gi_repository_find_by_gtype (repo, gtype);
   if (type_info == NULL)
     {
       g_warning ("Type not found in introspection: '%s'",
                  g_type_name (gtype));
+      g_clear_object (&repo);
       return NULL;
     }
 
-  switch (g_base_info_get_type (type_info))
-    {
-    case GI_INFO_TYPE_OBJECT:
-      func_info = g_object_info_find_method ((GIObjectInfo *) type_info,
-                                             method_name);
-      break;
-    case GI_INFO_TYPE_INTERFACE:
-      func_info = g_interface_info_find_method ((GIInterfaceInfo *) type_info,
-                                                method_name);
-      break;
-    default:
-      func_info = NULL;
-    }
+  if (GI_IS_OBJECT_INFO (type_info))
+    func_info = gi_object_info_find_method (GI_OBJECT_INFO (type_info), method_name);
+  else if (GI_IS_INTERFACE_INFO (type_info))
+    func_info = gi_interface_info_find_method (GI_INTERFACE_INFO (type_info), method_name);
+  else
+    func_info = NULL;
+
+  gi_base_info_unref (type_info);
+  g_clear_object (&repo);
 
-  g_base_info_unref (type_info);
-  return (GICallableInfo *) func_info;
+  return GI_CALLABLE_INFO (func_info);
 }
 
 gboolean
@@ -295,7 +295,7 @@ peas_gi_method_call (GObject        *instance,
                         FALSE);
   g_return_val_if_fail (method_name != NULL, FALSE);
 
-  n_args = g_callable_info_get_n_args (func_info);
+  n_args = gi_callable_info_get_n_args (func_info);
   g_return_val_if_fail (n_args >= 0, FALSE);
   n_in_args = 0;
   n_out_args = 0;
@@ -314,8 +314,8 @@ peas_gi_method_call (GObject        *instance,
   g_debug ("Calling '%s.%s' on '%p'",
            g_type_name (gtype), method_name, instance);
 
-  ret = g_function_info_invoke (func_info, in_args, n_in_args, out_args,
-                                n_out_args, return_value, &error);
+  ret = gi_function_info_invoke (GI_FUNCTION_INFO (func_info), in_args, n_in_args, out_args,
+                                 n_out_args, return_value, &error);
   if (!ret)
     {
       g_warning ("Error while calling '%s.%s': %s",
diff --git a/libpeas/peas-introspection.h b/libpeas/peas-introspection.h
index e5f3bbdf6fa9a779e99cadd860da4287940df7c5..adf84931be8e72adc1bb64cc61b40f60ea12f228 100644
--- a/libpeas/peas-introspection.h
+++ b/libpeas/peas-introspection.h
@@ -23,7 +23,7 @@
 #define __PEAS_INTROSPECTION_H__
 
 #include <glib-object.h>
-#include <girepository.h>
+#include <girepository/girepository.h>
 
 G_BEGIN_DECLS
 
diff --git a/meson.build b/meson.build
index 86f4495051bc43aea2927222ed1621c4fb066caf..d9286cf4b0eb3bc593428c87acb3cb4f63096b95 100644
--- a/meson.build
+++ b/meson.build
@@ -86,10 +86,9 @@ config_h.set_quoted('GETTEXT_PACKAGE', package_string)
 # Dependencies
 cc = meson.get_compiler('c')
 
-glib_req_version = '2.44.0'
+glib_req_version = '2.85.0'
 
 glib_req = '>= @0@'.format(glib_req_version)
-introspection_req = '>= 1.39.0'
 gtk_req = '>= 3.0.0'
 gtk_doc_req = '>= 1.11'
 python2_req = '>= 2.5.2'
@@ -103,7 +102,7 @@ glib_dep = dependency('glib-2.0', version: glib_req)
 gobject_dep = dependency('gobject-2.0', version: glib_req)
 gmodule_dep = dependency('gmodule-2.0', version: glib_req)
 gio_dep = dependency('gio-2.0', version: glib_req)
-introspection_dep = dependency('gobject-introspection-1.0', version: introspection_req)
+introspection_dep = dependency('girepository-2.0', version: glib_req)
 gtk_dep = dependency('gtk+-3.0', version: gtk_req, required: false)
 
 gi_docgen_dep = dependency('gi-docgen', version: '>= 2021.7',
diff --git a/meson_options.txt b/meson_options.txt
index cb21e45acf0efc43672d95097e98b9504a10b636..c2e40f1e832f58a6658ae096b48cc8341701c5d4 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -18,7 +18,7 @@ option('python3_path',
 
 option('introspection',
        type: 'boolean', value: true,
-       description: 'Generate introspection data (requires gobject-introspection)')
+       description: 'Generate introspection data (requires girepository-2.0)')
 option('vapi',
        type: 'boolean', value: false,
        description: 'Generate vapi data (requires vapigen)')
diff --git a/peas-demo/peas-demo.c b/peas-demo/peas-demo.c
index fd9b766cd6f0107694d1cc165d419651c13d4e15..b417b1d6669071999de60a27d639946da9581571 100644
--- a/peas-demo/peas-demo.c
+++ b/peas-demo/peas-demo.c
@@ -23,7 +23,7 @@
 #include <config.h>
 #endif
 
-#include <girepository.h>
+#include <girepository/girepository.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <locale.h>
@@ -131,14 +131,18 @@ main (int    argc,
 
   if (run_from_build_dir)
     {
+      GIRepository *repository = gi_repository_dup_default ();
+
       g_debug ("Running from build directory: %s", PEAS_BUILDDIR);
 
       /* Use the uninstalled typelibs */
-      g_irepository_prepend_search_path (PEAS_BUILDDIR "/libpeas");
-      g_irepository_prepend_search_path (PEAS_BUILDDIR "/libpeas-gtk");
+      gi_repository_prepend_search_path (repository, PEAS_BUILDDIR "/libpeas");
+      gi_repository_prepend_search_path (repository, PEAS_BUILDDIR "/libpeas-gtk");
 
       /* Use the uninstalled plugin loaders */
       g_setenv ("PEAS_PLUGIN_LOADERS_DIR", PEAS_BUILDDIR "/loaders", TRUE);
+
+      g_clear_object (&repository);
     }
 
   engine = peas_engine_get_default ();
diff --git a/tests/libpeas-gtk/testing/testing.c b/tests/libpeas-gtk/testing/testing.c
index 656955daec105f3f5c66cfc726f731c1c033d962..105e9b00202a580b9614a6010e9b77e6f895a23b 100644
--- a/tests/libpeas-gtk/testing/testing.c
+++ b/tests/libpeas-gtk/testing/testing.c
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 
 #include <glib.h>
-#include <girepository.h>
+#include <girepository/girepository.h>
 #include <testing-util.h>
 
 #include "testing.h"
@@ -37,6 +37,7 @@ testing_init (gint    *argc,
 {
   GError *error = NULL;
   static gboolean initialized = FALSE;
+  GIRepository *repository;
 
   if (initialized)
     return;
@@ -51,10 +52,12 @@ testing_init (gint    *argc,
    */
   testing_util_init ();
 
-  g_irepository_require_private (g_irepository_get_default (),
+  repository = gi_repository_dup_default ();
+  gi_repository_require_private (repository,
                                  BUILDDIR "/libpeas-gtk",
                                  "PeasGtk", "1.0", 0, &error);
   g_assert_no_error (error);
+  g_clear_object (&repository);
 
   initialized = TRUE;
 }
diff --git a/tests/libpeas/testing/testing.c b/tests/libpeas/testing/testing.c
index 49b94f325468a31c05d5ef9daeb41a2108851a0d..74722d7a2afee8754a466285e7ec27a23f5c3e75 100644
--- a/tests/libpeas/testing/testing.c
+++ b/tests/libpeas/testing/testing.c
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 
 #include <glib.h>
-#include <girepository.h>
+#include <girepository/girepository.h>
 #include <testing-util.h>
 
 #include "testing.h"
@@ -37,6 +37,7 @@ testing_init (gint    *argc,
 {
   GError *error = NULL;
   static gboolean initialized = FALSE;
+  GIRepository *repository;
 
   if (initialized)
     return;
@@ -48,10 +49,12 @@ testing_init (gint    *argc,
   /* Must be after g_test_init() changes the log settings*/
   testing_util_init ();
 
-  g_irepository_require_private (g_irepository_get_default (),
+  repository = gi_repository_dup_default ();
+  gi_repository_require_private (repository,
                                  BUILDDIR "/tests/libpeas/introspection",
                                  "Introspection", "1.0", 0, &error);
   g_assert_no_error (error);
+  g_clear_object (&repository);
 
   initialized = TRUE;
 }
diff --git a/tests/testing-util/testing-util.c b/tests/testing-util/testing-util.c
index f35c8069d2d014477744ab1b2b954fd66db8a0c7..727fd13d31e17bdfe18779e2e7de33f284cadfc6 100644
--- a/tests/testing-util/testing-util.c
+++ b/tests/testing-util/testing-util.c
@@ -24,7 +24,7 @@
 #include <stdlib.h>
 
 #include <glib.h>
-#include <girepository.h>
+#include <girepository/girepository.h>
 
 #include "libpeas/peas-engine-priv.h"
 
@@ -187,6 +187,7 @@ void
 testing_util_init (void)
 {
   GError *error = NULL;
+  GIRepository *repository;
   const GDebugKey glib_debug_keys[] = {
     { "fatal-criticals", G_LOG_LEVEL_CRITICAL },
     { "fatal-warnings",  G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING }
@@ -207,10 +208,12 @@ testing_util_init (void)
   fatal_flags = g_parse_debug_string (g_getenv ("G_DEBUG"), glib_debug_keys,
                                       G_N_ELEMENTS (glib_debug_keys));
 
-  g_irepository_require_private (g_irepository_get_default (),
+  repository = gi_repository_dup_default ();
+  gi_repository_require_private (repository,
                                  BUILDDIR "/libpeas",
                                  "Peas", "1.0", 0, &error);
   g_assert_no_error (error);
+  g_clear_object (&repository);
 
   initialized = TRUE;
 }
