diff --git a/app/Config/Events.php b/app/Config/Events.php
index 8da203d08d177b18d46d0fb240e8a5764819c268..ac4ed255e4bb54e85bcca04ccff7b37d580ee9f6 100644
--- a/app/Config/Events.php
+++ b/app/Config/Events.php
@@ -50,11 +50,12 @@ Events::on('pre_system', static function (): void {
      */
     if (CI_DEBUG && ! is_cli()) {
         Events::on('DBQuery', Database::class . '::collect');
-        Services::toolbar()->respond();
+        service('toolbar')
+            ->respond();
 
         // Hot Reload route - for framework use on the hot reloader.
         if (ENVIRONMENT === 'development') {
-            Services::routes()->get('__hot-reload', static function (): void {
+            service('routes')->get('__hot-reload', static function (): void {
                 (new HotReloader())->run();
             });
         }
diff --git a/app/Config/Format.php b/app/Config/Format.php
index 2b72fc0e8eabc0fd8385f84b9e4067e8730140bd..86b7e2ddb16974ab2673c67f115b92ca3652450a 100644
--- a/app/Config/Format.php
+++ b/app/Config/Format.php
@@ -74,6 +74,6 @@ class Format extends BaseConfig
      */
     public function getFormatter(string $mime): FormatterInterface
     {
-        return Services::format()->getFormatter($mime);
+        return service('format')->getFormatter($mime);
     }
 }
diff --git a/app/Config/Paths.php b/app/Config/Paths.php
index 496590dc28f8867774fbede9f8e68134cb2d56f6..aa51ea9e7be7822d0585515527caa6f111b2548d 100644
--- a/app/Config/Paths.php
+++ b/app/Config/Paths.php
@@ -70,7 +70,7 @@ class Paths
      * This variable must contain the name of the directory that
      * contains the view files used by your application. By
      * default this is in `app/Views`. This value
-     * is used when no value is provided to `Services::renderer()`.
+     * is used when no value is provided to `service('renderer')`.
      */
     public string $viewDirectory = __DIR__ . '/../Views';
 }
diff --git a/app/Controllers/EpisodeAudioController.php b/app/Controllers/EpisodeAudioController.php
index 68fdb292973ad4533457f00c1facaa63550743ed..e0aa40ee7b0581d180450ab6c79a580d0aab0c04 100644
--- a/app/Controllers/EpisodeAudioController.php
+++ b/app/Controllers/EpisodeAudioController.php
@@ -20,7 +20,6 @@ use CodeIgniter\HTTP\RedirectResponse;
 use CodeIgniter\HTTP\RequestInterface;
 use CodeIgniter\HTTP\ResponseInterface;
 use CodeIgniter\HTTP\URI;
-use Config\Services;
 use Modules\Analytics\Config\Analytics;
 use Modules\PremiumPodcasts\Entities\Subscription;
 use Modules\PremiumPodcasts\Models\SubscriptionModel;
@@ -124,7 +123,7 @@ class EpisodeAudioController extends Controller
             }
         }
 
-        $session = Services::session();
+        $session = service('session');
 
         $serviceName = '';
         if ($this->request->getGet('_from')) {
diff --git a/app/Controllers/EpisodeController.php b/app/Controllers/EpisodeController.php
index 93dfe2b23f33976215472d3a66baccde847a604c..e1194174321c866f054a0e9b7f1055cfa8d0bd06 100644
--- a/app/Controllers/EpisodeController.php
+++ b/app/Controllers/EpisodeController.php
@@ -20,7 +20,6 @@ use CodeIgniter\Database\BaseBuilder;
 use CodeIgniter\Exceptions\PageNotFoundException;
 use CodeIgniter\HTTP\ResponseInterface;
 use Config\Embed;
-use Config\Services;
 use Modules\Analytics\AnalyticsTrait;
 use Modules\Fediverse\Objects\OrderedCollectionObject;
 use Modules\Fediverse\Objects\OrderedCollectionPage;
@@ -277,7 +276,7 @@ class EpisodeController extends BaseController
 
         $this->registerPodcastWebpageHit($this->episode->podcast_id);
 
-        $session = Services::session();
+        $session = service('session');
 
         if (service('superglobals')->server('HTTP_REFERER') !== null) {
             $session->set('embed_domain', parse_url(service('superglobals')->server('HTTP_REFERER'), PHP_URL_HOST));
diff --git a/app/Entities/Location.php b/app/Entities/Location.php
index ca63a7530ede70377122a1daa9c583aef22b191e..2a387a020ae66968a3c7ec9a88d85d3e6393e8c9 100644
--- a/app/Entities/Location.php
+++ b/app/Entities/Location.php
@@ -11,7 +11,6 @@ declare(strict_types=1);
 namespace App\Entities;
 
 use CodeIgniter\Entity\Entity;
-use Config\Services;
 
 /**
  * @property string $url
@@ -85,7 +84,7 @@ class Location extends Entity
      */
     public function fetchOsmLocation(): static
     {
-        $client = Services::curlrequest();
+        $client = service('curlrequest');
 
         $response = $client->request(
             'GET',
diff --git a/app/Helpers/breadcrumb_helper.php b/app/Helpers/breadcrumb_helper.php
index 5ddb90e8235c7570f64bd3da5d3b2604ec024bb6..31592039a984ee271b1506703fbca8f349adb286 100644
--- a/app/Helpers/breadcrumb_helper.php
+++ b/app/Helpers/breadcrumb_helper.php
@@ -2,14 +2,6 @@
 
 declare(strict_types=1);
 
-/**
- * @copyright  2020 Ad Aures
- * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
- * @link       https://castopod.org/
- */
-
-use Config\Services;
-
 if (! function_exists('render_breadcrumb')) {
     /**
      * Renders the breadcrumb navigation through the Breadcrumb service
@@ -19,8 +11,7 @@ if (! function_exists('render_breadcrumb')) {
      */
     function render_breadcrumb(string $class = null): string
     {
-        $breadcrumb = Services::breadcrumb();
-        return $breadcrumb->render($class);
+        return service('breadcrumb')->render($class);
     }
 }
 
@@ -30,7 +21,6 @@ if (! function_exists('replace_breadcrumb_params')) {
      */
     function replace_breadcrumb_params(array $newParams): void
     {
-        $breadcrumb = Services::breadcrumb();
-        $breadcrumb->replaceParams($newParams);
+        service('breadcrumb')->replaceParams($newParams);
     }
 }
diff --git a/app/Libraries/Router.php b/app/Libraries/Router.php
index 4d5b4ff84968c5fa02ec0b5d81ef73683d595532..902c8c43b5ac2bd85532597d88a33101978bbe14 100644
--- a/app/Libraries/Router.php
+++ b/app/Libraries/Router.php
@@ -18,7 +18,6 @@ use CodeIgniter\Exceptions\PageNotFoundException;
 use CodeIgniter\Router\Exceptions\RedirectException;
 use CodeIgniter\Router\Exceptions\RouterException;
 use CodeIgniter\Router\Router as CodeIgniterRouter;
-use Config\Services;
 use Override;
 
 class Router extends CodeIgniterRouter
@@ -117,8 +116,8 @@ class Router extends CodeIgniterRouter
                     array_key_exists('alternate-content', $this->matchedRouteOptions) &&
                     is_array($this->matchedRouteOptions['alternate-content'])
                 ) {
-                    $request = Services::request();
-                    $negotiate = Services::negotiator();
+                    $request = service('request');
+                    $negotiate = service('negotiator');
 
                     // Accept header is mandatory
                     if ($request->header('Accept') === null) {
diff --git a/app/Views/errors/cli/error_exception.php b/app/Views/errors/cli/error_exception.php
index 1ce53a5273d34ebe74832722319e54d46d088e06..7a7247fc6a0bd6dd261209cd830a328b8d1328c0 100644
--- a/app/Views/errors/cli/error_exception.php
+++ b/app/Views/errors/cli/error_exception.php
@@ -54,7 +54,7 @@ if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE) {
 
         $args = implode(', ', array_map(static fn ($value) => match (true) {
             is_object($value) => 'Object(' . $value::class . ')',
-            is_array($value)  => count($value) ? '[...]' : '[]',
+            is_array($value)  => $value !== [] ? '[...]' : '[]',
             $value === null   => 'null', // return the lowercased version
             default           => var_export($value, true),
         }, array_values($error['args'] ?? [])));
diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php
index 6ccf08c8d5cad71b1865658d09f007294fbef0f7..9898ed5da71e8a1686755b17c466dc829fd235b8 100644
--- a/app/Views/errors/html/error_exception.php
+++ b/app/Views/errors/html/error_exception.php
@@ -4,7 +4,6 @@ declare(strict_types=1);
 
 use CodeIgniter\CodeIgniter;
 use CodeIgniter\HTTP\Header;
-use Config\Services;
 
 $errorId = uniqid('error', true);
 ?>
@@ -228,7 +227,7 @@ while ($prevException = $last->getPrevious()) {
 
 			<!-- Request -->
 			<div class="content" id="request">
-				<?php $request = Services::request(); ?>
+				<?php $request = service('request'); ?>
 
 				<table>
 					<tbody>
@@ -346,7 +345,7 @@ while ($prevException = $last->getPrevious()) {
 
 			<!-- Response -->
 			<?php
-                $response = Services::response();
+                $response = service('response');
 $response->setStatusCode(http_response_code());
 ?>
 			<div class="content" id="response">
diff --git a/composer.json b/composer.json
index 9fac8709bc4e751a0d73f28d0a2ff5c030ffcd7a..26acb97e5be9450072f914dbad21a6b1f81fe768 100644
--- a/composer.json
+++ b/composer.json
@@ -9,16 +9,16 @@
     "php": "^8.3",
     "adaures/ipcat-php": "^v1.0.0",
     "adaures/podcast-persons-taxonomy": "^v1.0.1",
-    "aws/aws-sdk-php": "^3.336.2",
+    "aws/aws-sdk-php": "^3.336.6",
     "chrisjean/php-ico": "^1.0.4",
     "cocur/slugify": "^v4.6.0",
-    "codeigniter4/framework": "v4.5.5",
+    "codeigniter4/framework": "v4.5.6",
     "codeigniter4/settings": "v2.2.0",
     "codeigniter4/shield": "v1.1.0",
     "codeigniter4/tasks": "dev-develop",
     "geoip2/geoip2": "v3.1.0",
     "james-heinrich/getid3": "^2.0.0-beta6",
-    "league/commonmark": "^2.6.0",
+    "league/commonmark": "^2.6.1",
     "league/html-to-markdown": "5.1.1",
     "melbahja/seo": "^v2.1.1",
     "michalsn/codeigniter4-uuid": "v1.1.0",
@@ -37,7 +37,7 @@
     "phpstan/extension-installer": "^1.4.3",
     "phpstan/phpstan": "^2.0.4",
     "phpunit/phpunit": "^11.5.2",
-    "rector/rector": "^2.0.3",
+    "rector/rector": "^2.0.4",
     "symplify/coding-standard": "^12.2.3",
     "symplify/easy-coding-standard": "^12.5.4"
   },
diff --git a/composer.lock b/composer.lock
index a60b42f9dfad7f29e2beacd8106591c7be342dea..cf8f74a7ceab0edfd2c9c5456b25989143aa9df5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
     "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
     "This file is @generated automatically"
   ],
-  "content-hash": "f95311413c714e2dcef9364da4348b30",
+  "content-hash": "6b99aa0bcdbc76f94b529ba8c5ff0ee7",
   "packages": [
     {
       "name": "adaures/ipcat-php",
@@ -189,16 +189,16 @@
     },
     {
       "name": "aws/aws-sdk-php",
-      "version": "3.336.2",
+      "version": "3.336.6",
       "source": {
         "type": "git",
         "url": "https://github.com/aws/aws-sdk-php.git",
-        "reference": "954bfdfc048840ca34afe2a2e1cbcff6681989c4"
+        "reference": "0a99dab427f0a1c082775301141aeac3558691ad"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/954bfdfc048840ca34afe2a2e1cbcff6681989c4",
-        "reference": "954bfdfc048840ca34afe2a2e1cbcff6681989c4",
+        "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/0a99dab427f0a1c082775301141aeac3558691ad",
+        "reference": "0a99dab427f0a1c082775301141aeac3558691ad",
         "shasum": ""
       },
       "require": {
@@ -275,9 +275,9 @@
       "support": {
         "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
         "issues": "https://github.com/aws/aws-sdk-php/issues",
-        "source": "https://github.com/aws/aws-sdk-php/tree/3.336.2"
+        "source": "https://github.com/aws/aws-sdk-php/tree/3.336.6"
       },
-      "time": "2024-12-20T19:05:10+00:00"
+      "time": "2024-12-28T04:16:13+00:00"
     },
     {
       "name": "brick/math",
@@ -448,16 +448,16 @@
     },
     {
       "name": "codeigniter4/framework",
-      "version": "v4.5.5",
+      "version": "v4.5.6",
       "source": {
         "type": "git",
         "url": "https://github.com/codeigniter4/framework.git",
-        "reference": "2849e7ff36b4c4aa1376d990a9a1e3f0c393b8d0"
+        "reference": "7822476e6c672387b0ca1d64a74040ed28c42d9f"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/codeigniter4/framework/zipball/2849e7ff36b4c4aa1376d990a9a1e3f0c393b8d0",
-        "reference": "2849e7ff36b4c4aa1376d990a9a1e3f0c393b8d0",
+        "url": "https://api.github.com/repos/codeigniter4/framework/zipball/7822476e6c672387b0ca1d64a74040ed28c42d9f",
+        "reference": "7822476e6c672387b0ca1d64a74040ed28c42d9f",
         "shasum": ""
       },
       "require": {
@@ -514,7 +514,7 @@
         "slack": "https://codeigniterchat.slack.com",
         "source": "https://github.com/codeigniter4/CodeIgniter4"
       },
-      "time": "2024-09-07T08:49:38+00:00"
+      "time": "2024-12-28T18:27:37+00:00"
     },
     {
       "name": "codeigniter4/settings",
@@ -1411,16 +1411,16 @@
     },
     {
       "name": "league/commonmark",
-      "version": "2.6.0",
+      "version": "2.6.1",
       "source": {
         "type": "git",
         "url": "https://github.com/thephpleague/commonmark.git",
-        "reference": "d150f911e0079e90ae3c106734c93137c184f932"
+        "reference": "d990688c91cedfb69753ffc2512727ec646df2ad"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d150f911e0079e90ae3c106734c93137c184f932",
-        "reference": "d150f911e0079e90ae3c106734c93137c184f932",
+        "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d990688c91cedfb69753ffc2512727ec646df2ad",
+        "reference": "d990688c91cedfb69753ffc2512727ec646df2ad",
         "shasum": ""
       },
       "require": {
@@ -1512,7 +1512,7 @@
           "type": "tidelift"
         }
       ],
-      "time": "2024-12-07T15:34:16+00:00"
+      "time": "2024-12-29T14:10:59+00:00"
     },
     {
       "name": "league/config",
@@ -2857,12 +2857,12 @@
       },
       "type": "library",
       "extra": {
+        "thanks": {
+          "url": "https://github.com/symfony/contracts",
+          "name": "symfony/contracts"
+        },
         "branch-alias": {
           "dev-main": "3.5-dev"
-        },
-        "thanks": {
-          "name": "symfony/contracts",
-          "url": "https://github.com/symfony/contracts"
         }
       },
       "autoload": {
@@ -3383,11 +3383,11 @@
       "bin": ["bin/captainhook"],
       "type": "library",
       "extra": {
-        "branch-alias": {
-          "dev-main": "6.0.x-dev"
-        },
         "captainhook": {
           "config": "captainhook.json"
+        },
+        "branch-alias": {
+          "dev-main": "6.0.x-dev"
         }
       },
       "autoload": {
@@ -5282,21 +5282,21 @@
     },
     {
       "name": "rector/rector",
-      "version": "2.0.3",
+      "version": "2.0.4",
       "source": {
         "type": "git",
         "url": "https://github.com/rectorphp/rector.git",
-        "reference": "3f27091368bd935dbbaa8387099792fb20f65f68"
+        "reference": "df5de7b80deced1ea7f719a0b4d02e4aee87dd21"
       },
       "dist": {
         "type": "zip",
-        "url": "https://api.github.com/repos/rectorphp/rector/zipball/3f27091368bd935dbbaa8387099792fb20f65f68",
-        "reference": "3f27091368bd935dbbaa8387099792fb20f65f68",
+        "url": "https://api.github.com/repos/rectorphp/rector/zipball/df5de7b80deced1ea7f719a0b4d02e4aee87dd21",
+        "reference": "df5de7b80deced1ea7f719a0b4d02e4aee87dd21",
         "shasum": ""
       },
       "require": {
         "php": "^7.4|^8.0",
-        "phpstan/phpstan": "^2.0.1"
+        "phpstan/phpstan": "^2.0.4"
       },
       "conflict": {
         "rector/rector-doctrine": "*",
@@ -5318,7 +5318,7 @@
       "keywords": ["automation", "dev", "migration", "refactoring"],
       "support": {
         "issues": "https://github.com/rectorphp/rector/issues",
-        "source": "https://github.com/rectorphp/rector/tree/2.0.3"
+        "source": "https://github.com/rectorphp/rector/tree/2.0.4"
       },
       "funding": [
         {
@@ -5326,7 +5326,7 @@
           "type": "github"
         }
       ],
-      "time": "2024-12-12T15:22:19+00:00"
+      "time": "2024-12-26T23:06:19+00:00"
     },
     {
       "name": "sebastian/cli-parser",
@@ -6562,12 +6562,12 @@
       },
       "type": "library",
       "extra": {
+        "thanks": {
+          "url": "https://github.com/symfony/contracts",
+          "name": "symfony/contracts"
+        },
         "branch-alias": {
           "dev-main": "3.5-dev"
-        },
-        "thanks": {
-          "name": "symfony/contracts",
-          "url": "https://github.com/symfony/contracts"
         }
       },
       "autoload": {
@@ -7092,12 +7092,12 @@
       },
       "type": "library",
       "extra": {
+        "thanks": {
+          "url": "https://github.com/symfony/contracts",
+          "name": "symfony/contracts"
+        },
         "branch-alias": {
           "dev-main": "3.5-dev"
-        },
-        "thanks": {
-          "name": "symfony/contracts",
-          "url": "https://github.com/symfony/contracts"
         }
       },
       "autoload": {
diff --git a/modules/Admin/Controllers/AboutController.php b/modules/Admin/Controllers/AboutController.php
index f355c7853061ade023c4ac102baec5bbfe41991a..b61abf291803756d8c592fe0815dba1a443ba102 100644
--- a/modules/Admin/Controllers/AboutController.php
+++ b/modules/Admin/Controllers/AboutController.php
@@ -11,7 +11,6 @@ declare(strict_types=1);
 namespace Modules\Admin\Controllers;
 
 use CodeIgniter\HTTP\RedirectResponse;
-use Config\Services;
 
 class AboutController extends BaseController
 {
@@ -43,7 +42,7 @@ class AboutController extends BaseController
 
     public function migrateDatabase(): RedirectResponse
     {
-        $migrate = Services::migrations();
+        $migrate = service('migrations');
 
         $migrate->setNamespace(null)
             ->latest();
diff --git a/modules/Analytics/AnalyticsTrait.php b/modules/Analytics/AnalyticsTrait.php
index e7d8a9495173a2ff248e9d3661052799961307a9..a345c597bf71b8502c87370cf8e3f30bfd838dae 100644
--- a/modules/Analytics/AnalyticsTrait.php
+++ b/modules/Analytics/AnalyticsTrait.php
@@ -10,8 +10,6 @@ declare(strict_types=1);
 
 namespace Modules\Analytics;
 
-use Config\Services;
-
 trait AnalyticsTrait
 {
     protected function registerPodcastWebpageHit(int $podcastId): void
@@ -28,7 +26,7 @@ trait AnalyticsTrait
         set_user_session_referer();
         set_user_session_entry_page();
 
-        $session = Services::session();
+        $session = service('session');
 
         if (! $session->get('denyListIp')) {
             $db = db_connect();
diff --git a/modules/Analytics/Helpers/analytics_helper.php b/modules/Analytics/Helpers/analytics_helper.php
index 18c28098f6a0a417d5a177fd5d75a23dde7f86ed..3630462f6dd84164eddfcce60d77216edb64104f 100644
--- a/modules/Analytics/Helpers/analytics_helper.php
+++ b/modules/Analytics/Helpers/analytics_helper.php
@@ -9,7 +9,6 @@ declare(strict_types=1);
  */
 
 use AdAures\Ipcat\IpDb;
-use Config\Services;
 use GeoIp2\Database\Reader;
 use Opawg\UserAgentsV2Php\UserAgents;
 use WhichBrowser\Parser;
@@ -55,7 +54,7 @@ if (! function_exists('set_user_session_deny_list_ip')) {
      */
     function set_user_session_deny_list_ip(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         if (! $session->has('denyListIp')) {
             $session->set('denyListIp', IpDb::find(client_ip()) !== null);
@@ -69,7 +68,7 @@ if (! function_exists('set_user_session_location')) {
      */
     function set_user_session_location(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         $location = [
             'countryCode' => 'N/A',
@@ -105,7 +104,7 @@ if (! function_exists('set_user_session_player')) {
      */
     function set_user_session_player(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         if (! $session->has('player')) {
             $playerFound = null;
@@ -148,7 +147,7 @@ if (! function_exists('set_user_session_browser')) {
      */
     function set_user_session_browser(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         if (! $session->has('browser')) {
             $browserName = '- Other -';
@@ -174,7 +173,7 @@ if (! function_exists('set_user_session_referer')) {
      */
     function set_user_session_referer(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         $newreferer = service('superglobals')
             ->server('HTTP_REFERER') ?? '- Direct -';
@@ -195,7 +194,7 @@ if (! function_exists('set_user_session_entry_page')) {
      */
     function set_user_session_entry_page(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         $entryPage = service('superglobals')
             ->server('REQUEST_URI');
@@ -238,7 +237,7 @@ if (! function_exists('podcast_hit')) {
         string $serviceName,
         ?int $subscriptionId,
     ): void {
-        $session = Services::session();
+        $session = service('session');
 
         $clientIp = client_ip();
 
diff --git a/modules/Api/Rest/V1/Controllers/EpisodeController.php b/modules/Api/Rest/V1/Controllers/EpisodeController.php
index d4fb1569428ddd5c78af31cc338a4a477ac46fb6..4688a8587a6def62afa832484948a315dffb8a30 100644
--- a/modules/Api/Rest/V1/Controllers/EpisodeController.php
+++ b/modules/Api/Rest/V1/Controllers/EpisodeController.php
@@ -15,7 +15,6 @@ use CodeIgniter\API\ResponseTrait;
 use CodeIgniter\Controller;
 use CodeIgniter\HTTP\ResponseInterface;
 use CodeIgniter\I18n\Time;
-use Modules\Api\Rest\V1\Config\Services;
 use Modules\Auth\Models\UserModel;
 
 class EpisodeController extends Controller
@@ -24,7 +23,7 @@ class EpisodeController extends Controller
 
     public function __construct()
     {
-        Services::restApiExceptions()->initialize();
+        service('restApiExceptions')->initialize();
     }
 
     public function list(): ResponseInterface
diff --git a/modules/Api/Rest/V1/Controllers/PodcastController.php b/modules/Api/Rest/V1/Controllers/PodcastController.php
index cce5178379c9bb642e2258104fb570c7278a08f4..7e45b2e0b5f9fc5b441019e6669bf52f3788e272 100644
--- a/modules/Api/Rest/V1/Controllers/PodcastController.php
+++ b/modules/Api/Rest/V1/Controllers/PodcastController.php
@@ -9,7 +9,6 @@ use App\Models\PodcastModel;
 use CodeIgniter\API\ResponseTrait;
 use CodeIgniter\Controller;
 use CodeIgniter\HTTP\ResponseInterface;
-use Modules\Api\Rest\V1\Config\Services;
 
 class PodcastController extends Controller
 {
@@ -17,7 +16,7 @@ class PodcastController extends Controller
 
     public function __construct()
     {
-        Services::restApiExceptions()->initialize();
+        service('restApiExceptions')->initialize();
     }
 
     public function list(): ResponseInterface
diff --git a/modules/Auth/Commands/RolesDoc.php b/modules/Auth/Commands/RolesDoc.php
index bc9d9cc687847bbf2022188d1582e1e4bca2ce0b..5f95bfa9cd199dd979faec7337081ba67bf6a8a5 100644
--- a/modules/Auth/Commands/RolesDoc.php
+++ b/modules/Auth/Commands/RolesDoc.php
@@ -8,7 +8,6 @@ use Closure;
 use CodeIgniter\CLI\BaseCommand;
 use CodeIgniter\CLI\CLI;
 use CodeIgniter\View\Table;
-use Config\Services;
 use League\HTMLToMarkdown\Converter\TableConverter;
 use League\HTMLToMarkdown\HtmlConverter;
 use Modules\Auth\Config\AuthGroups;
@@ -59,8 +58,8 @@ class RolesDoc extends BaseCommand
 
         foreach ($files as $file) {
             $locale = $this->detectLocaleFromPath($file);
-            $language = Services::language();
-            $language->setLocale($locale);
+            service('language')
+                ->setLocale($locale);
 
             $authGroups = new AuthGroups();
 
diff --git a/modules/Auth/Filters/PermissionFilter.php b/modules/Auth/Filters/PermissionFilter.php
index 8d53c4a351aecf1691006be0338276783cf5eed5..b12ee6bbd36620777cda00e9d036871816a88541 100644
--- a/modules/Auth/Filters/PermissionFilter.php
+++ b/modules/Auth/Filters/PermissionFilter.php
@@ -9,7 +9,6 @@ use App\Models\PodcastModel;
 use CodeIgniter\Filters\FilterInterface;
 use CodeIgniter\HTTP\RequestInterface;
 use CodeIgniter\HTTP\ResponseInterface;
-use Config\Services;
 use Override;
 use RuntimeException;
 
@@ -62,7 +61,7 @@ class PermissionFilter implements FilterInterface
         foreach ($arguments as $permission) {
             // is permission specific to a podcast?
             if (str_contains($permission, '$')) {
-                $router = Services::router();
+                $router = service('router');
                 $routerParams = $router->params();
 
                 if (! preg_match('/\$(\d+)\./', $permission, $match)) {
diff --git a/modules/Fediverse/ActivityRequest.php b/modules/Fediverse/ActivityRequest.php
index 5334f1dadaea41a5976425519f7bcf4555b11d03..f5b56a2957c608b33195a666ea99c5673d635b38 100644
--- a/modules/Fediverse/ActivityRequest.php
+++ b/modules/Fediverse/ActivityRequest.php
@@ -14,7 +14,6 @@ use CodeIgniter\HTTP\CURLRequest;
 use CodeIgniter\HTTP\ResponseInterface;
 use CodeIgniter\HTTP\URI;
 use CodeIgniter\I18n\Time;
-use Config\Services;
 use Modules\Fediverse\Core\Activity;
 use phpseclib\Crypt\RSA;
 
@@ -33,7 +32,7 @@ class ActivityRequest
 
     public function __construct(string $uri, ?string $activityPayload = null)
     {
-        $this->request = Services::curlrequest();
+        $this->request = service('curlrequest');
 
         if ($activityPayload !== null) {
             $this->request->setBody($activityPayload);
diff --git a/modules/Fediverse/Filters/FediverseFilter.php b/modules/Fediverse/Filters/FediverseFilter.php
index 67d904988a79cd8738e42e3da4f647583e4f88f6..1e64839bffac537d045c07d20210605f5dc491ca 100644
--- a/modules/Fediverse/Filters/FediverseFilter.php
+++ b/modules/Fediverse/Filters/FediverseFilter.php
@@ -9,7 +9,6 @@ use CodeIgniter\Filters\FilterInterface;
 use CodeIgniter\HTTP\RequestInterface;
 use CodeIgniter\HTTP\ResponseInterface;
 use CodeIgniter\HTTP\URI;
-use Config\Services;
 use Exception;
 use Modules\Fediverse\HttpSignature;
 use Override;
@@ -33,7 +32,7 @@ class FediverseFilter implements FilterInterface
         }
 
         if (in_array('verify-activitystream', $params, true)) {
-            $negotiate = Services::negotiator();
+            $negotiate = service('negotiator');
 
             $allowedContentTypes = [
                 'application/ld+json; profile="https://www.w3.org/ns/activitystreams',
diff --git a/modules/Fediverse/HttpSignature.php b/modules/Fediverse/HttpSignature.php
index cbec3f4473eff006192d2299365b767c66ec81a8..3b9eccdca495b5a0a0a1abdac3b8bbf1014527af 100644
--- a/modules/Fediverse/HttpSignature.php
+++ b/modules/Fediverse/HttpSignature.php
@@ -16,7 +16,6 @@ namespace Modules\Fediverse;
 
 use CodeIgniter\HTTP\IncomingRequest;
 use CodeIgniter\I18n\Time;
-use Config\Services;
 use Exception;
 use phpseclib\Crypt\RSA;
 
@@ -40,7 +39,7 @@ class HttpSignature
     public function __construct(IncomingRequest $request = null)
     {
         if (! $request instanceof IncomingRequest) {
-            $request = Services::request();
+            $request = service('request');
         }
 
         $this->request = $request;
diff --git a/modules/Install/Commands/InitDatabase.php b/modules/Install/Commands/InitDatabase.php
index 7f4b22a89402d2d931f44b3a91b1b6f86192764a..67d8f61baa2c98e13c707b5dd596bcf358daff4c 100644
--- a/modules/Install/Commands/InitDatabase.php
+++ b/modules/Install/Commands/InitDatabase.php
@@ -6,7 +6,6 @@ namespace Modules\Install\Commands;
 
 use CodeIgniter\CLI\BaseCommand;
 use Config\Database;
-use Config\Services;
 use Override;
 
 class InitDatabase extends BaseCommand
@@ -30,7 +29,7 @@ class InitDatabase extends BaseCommand
     public function run(array $params): void
     {
         // Run all migrations
-        $migrate = Services::migrations();
+        $migrate = service('migrations');
         $migrate->setNamespace(null)
             ->latest();
 
diff --git a/modules/Install/Controllers/InstallController.php b/modules/Install/Controllers/InstallController.php
index 587dca32181fa3723ad4f889a2ba14738419ef64..15bd9c6d0e5ec2ac264dd1cb8078c24e861de952 100644
--- a/modules/Install/Controllers/InstallController.php
+++ b/modules/Install/Controllers/InstallController.php
@@ -19,7 +19,6 @@ use CodeIgniter\HTTP\ResponseInterface;
 use CodeIgniter\Shield\Entities\User;
 use CodeIgniter\Shield\Exceptions\ValidationException as ShieldValidationException;
 use Config\Database;
-use Config\Services;
 use Dotenv\Dotenv;
 use Dotenv\Exception\ValidationException;
 use Modules\Auth\Models\UserModel;
@@ -247,7 +246,7 @@ class InstallController extends Controller
      */
     public function migrate(): void
     {
-        $migrate = Services::migrations();
+        $migrate = service('migrations');
 
         $migrate->setNamespace(null)
             ->latest();
diff --git a/modules/Media/Entities/Image.php b/modules/Media/Entities/Image.php
index 564823bccfda01f1864384e2fcd00bacd0778902..2d88bd3adac08d21b61bef4a705dc44ddabb7642 100644
--- a/modules/Media/Entities/Image.php
+++ b/modules/Media/Entities/Image.php
@@ -11,7 +11,6 @@ declare(strict_types=1);
 namespace Modules\Media\Entities;
 
 use CodeIgniter\Files\File;
-use Config\Services;
 use GdImage;
 use Override;
 
@@ -140,7 +139,7 @@ class Image extends BaseMedia
         }
 
         // save derived sizes
-        $imageService = Services::image();
+        $imageService = service('image');
 
         foreach ($this->sizes as $name => $size) {
             $tempFilePath = tempnam(WRITEPATH . 'temp', 'img_');
diff --git a/modules/Platforms/Controllers/PlatformController.php b/modules/Platforms/Controllers/PlatformController.php
index 1140f74883e99058cd62317539dc29915939273d..3d080c0ff3175ac49647698410c2ca9bbf7478ba 100644
--- a/modules/Platforms/Controllers/PlatformController.php
+++ b/modules/Platforms/Controllers/PlatformController.php
@@ -14,7 +14,6 @@ use App\Entities\Podcast;
 use App\Models\PodcastModel;
 use CodeIgniter\Exceptions\PageNotFoundException;
 use CodeIgniter\HTTP\RedirectResponse;
-use Config\Services;
 use Modules\Admin\Controllers\BaseController;
 use Modules\Platforms\Models\PlatformModel;
 
@@ -65,7 +64,7 @@ class PlatformController extends BaseController
     public function updateAction(string $platformType): RedirectResponse
     {
         $platformModel = new PlatformModel();
-        $validation = Services::validation();
+        $validation = service('validation');
 
         $platformsData = [];
         foreach (
diff --git a/modules/PodcastImport/Commands/PodcastImport.php b/modules/PodcastImport/Commands/PodcastImport.php
index cf5bc8483d717d97bb0f52e59da20bfbccae0de4..3479cc06c5632abe6bfbb6958720dcf57ff4326f 100644
--- a/modules/PodcastImport/Commands/PodcastImport.php
+++ b/modules/PodcastImport/Commands/PodcastImport.php
@@ -16,7 +16,6 @@ use CodeIgniter\CLI\BaseCommand;
 use CodeIgniter\CLI\CLI;
 use CodeIgniter\I18n\Time;
 use CodeIgniter\Shield\Entities\User;
-use Config\Services;
 use Exception;
 use League\HTMLToMarkdown\HtmlConverter;
 use Modules\Auth\Models\UserModel;
@@ -96,7 +95,8 @@ class PodcastImport extends BaseCommand
     public function run(array $params): void
     {
         // FIXME: getting named routes doesn't work from v4.3 anymore, so loading all routes before importing
-        Services::routes()->loadRoutes();
+        service('routes')
+            ->loadRoutes();
 
         try {
             $this->init();
diff --git a/modules/Update/Commands/DatabaseUpdate.php b/modules/Update/Commands/DatabaseUpdate.php
index bda484b0f99f51d34f90ebeaaddb22961dcf6b73..380f530599fe7cd4488ed863e2dcb06837c05ff8 100644
--- a/modules/Update/Commands/DatabaseUpdate.php
+++ b/modules/Update/Commands/DatabaseUpdate.php
@@ -5,7 +5,6 @@ declare(strict_types=1);
 namespace Modules\Update\Commands;
 
 use CodeIgniter\CLI\BaseCommand;
-use Config\Services;
 use Override;
 
 class DatabaseUpdate extends BaseCommand
@@ -28,7 +27,7 @@ class DatabaseUpdate extends BaseCommand
     #[Override]
     public function run(array $params): void
     {
-        $migrate = Services::migrations();
+        $migrate = service('migrations');
 
         $migrate->setNamespace(null)
             ->latest();
diff --git a/phpstan.neon b/phpstan.neon
index 792fb1dc5e19e84ade2a54f9a5c6f84c2abb2178..5aa7d8cee5c0ab966e1f7435230f011714c21ca0 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -47,6 +47,7 @@ parameters:
             - Modules\Platforms\Config\Services
             - Modules\Plugins\Config\Services
             - Modules\PremiumPodcasts\Config\Services
+            - Modules\Api\Rest\V1\Config\Services
     ignoreErrors:
         - '#^Call to an undefined method CodeIgniter\\Cache\\CacheInterface\:\:deleteMatching\(\)#'
         - identifier: missingType.generics
diff --git a/tests/session/ExampleSessionTest.php b/tests/session/ExampleSessionTest.php
index 6e2637ec2c8a056ec9c0d1851246e0258843a55c..b4299f17475bd617c2d1c01524f4dd7e9aa4327d 100644
--- a/tests/session/ExampleSessionTest.php
+++ b/tests/session/ExampleSessionTest.php
@@ -5,13 +5,12 @@ declare(strict_types=1);
 namespace Tests\Session;
 
 use CodeIgniter\Test\CIUnitTestCase;
-use Config\Services;
 
 class ExampleSessionTest extends CIUnitTestCase
 {
     public function testSessionSimple(): void
     {
-        $session = Services::session();
+        $session = service('session');
 
         $session->set('logged_in', 123);
         $this->assertSame(123, $session->get('logged_in'));
diff --git a/tests/unit/HealthTest.php b/tests/unit/HealthTest.php
index b3b5dbcec223bf50b3446f2978d1534ea5e3547c..86da3268fef6643e31907b1be75c91cc81df6671 100644
--- a/tests/unit/HealthTest.php
+++ b/tests/unit/HealthTest.php
@@ -4,7 +4,6 @@ declare(strict_types=1);
 
 use CodeIgniter\Test\CIUnitTestCase;
 use Config\App;
-use Config\Services;
 use Tests\Support\Libraries\ConfigReader;
 
 /**
@@ -19,7 +18,7 @@ final class HealthTest extends CIUnitTestCase
 
     public function testBaseUrlHasBeenSet(): void
     {
-        $validation = Services::validation();
+        $validation = service('validation');
 
         $env = false;