diff --git a/typo3/sysext/core/Classes/Configuration/Parser/PageTsConfigParser.php b/typo3/sysext/core/Classes/Configuration/Parser/PageTsConfigParser.php
index 5c2f0b4795680a9a2b56741a5132238c39e76a17..6afc3e0ac7a192bf1a451038649f7d266f7f7e4e 100644
--- a/typo3/sysext/core/Classes/Configuration/Parser/PageTsConfigParser.php
+++ b/typo3/sysext/core/Classes/Configuration/Parser/PageTsConfigParser.php
@@ -62,7 +62,6 @@ class PageTsConfigParser
             }
             if (!empty($siteSettings)) {
                 // Recursive substitution of site settings (up to 10 nested levels)
-                // note: this code is more or less a duplicate of \TYPO3\CMS\Core\TypoScript\TemplateService::substituteConstants
                 for ($i = 0; $i < 10; $i++) {
                     $beforeSubstitution = $content;
                     $content = preg_replace_callback(
diff --git a/typo3/sysext/core/Classes/TypoScript/TemplateService.php b/typo3/sysext/core/Classes/TypoScript/TemplateService.php
index 67f8ba341a2842925fa30aa03e5cfaaaa92382f4..206135f1b49a257b81de3b1e51d6d8e56880589f 100644
--- a/typo3/sysext/core/Classes/TypoScript/TemplateService.php
+++ b/typo3/sysext/core/Classes/TypoScript/TemplateService.php
@@ -309,6 +309,8 @@ class TemplateService
      */
     protected $frontendController;
 
+    private static bool $deprecationLogged = false;
+
     /**
      * @param Context|null $context
      * @param PackageManager|null $packageManager
@@ -332,6 +334,10 @@ class TemplateService
      */
     public function getProcessExtensionStatics()
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         return $this->processExtensionStatics;
     }
 
@@ -340,6 +346,10 @@ class TemplateService
      */
     public function setProcessExtensionStatics($processExtensionStatics)
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         $this->processExtensionStatics = (bool)$processExtensionStatics;
     }
 
@@ -349,6 +359,10 @@ class TemplateService
      */
     public function setVerbose($verbose)
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         $this->verbose = (bool)$verbose;
     }
 
@@ -372,6 +386,10 @@ class TemplateService
      */
     public function matching($cc)
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         if (is_array($cc['all'])) {
             $matchObj = GeneralUtility::makeInstance(ConditionMatcher::class, null, null, null, $this->absoluteRootLine);
             $matchObj->setRootline((array)($cc['rootLine'] ?? []));
@@ -395,6 +413,10 @@ class TemplateService
      */
     public function start($theRootLine)
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         $cc = [];
         if (is_array($theRootLine)) {
             $constantsData = [];
@@ -478,6 +500,10 @@ class TemplateService
      */
     public function runThroughTemplates($theRootLine, $start_template_uid = 0)
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         $this->constants = [];
         $this->config = [];
         $this->rowSum = [];
@@ -555,6 +581,10 @@ class TemplateService
      */
     public function processTemplate($row, $idList, $pid, $templateID = '', $templateParent = '', $includePath = '')
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         // Adding basic template record information to rowSum array
         $this->rowSum[] = [$row['uid'] ?? null, $row['title'] ?? null, $row['tstamp'] ?? null];
         // Processing "Clear"-flags
@@ -850,6 +880,10 @@ class TemplateService
      */
     public function generateConfig()
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         // Add default TS for all code types
         $this->addDefaultTypoScript();
 
@@ -1037,6 +1071,10 @@ class TemplateService
      */
     public function getRootlineLevel($list)
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         $idx = 0;
         foreach ($this->rootLine as $page) {
             if (GeneralUtility::inList($list, $page['uid'])) {
@@ -1054,6 +1092,10 @@ class TemplateService
      */
     public function getRootId(): int
     {
+        if (!self::$deprecationLogged) {
+            trigger_error(__CLASS__ . ' has been marked as deprecated in TYPO3 v12 and will be removed in v13.', E_USER_DEPRECATED);
+            self::$deprecationLogged = true;
+        }
         return (int)$this->rootId;
     }
 
diff --git a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
index 0ac8b458db241072348e5fa9dbb8849daa943135..c743f4e32b4134be80ee872e8667b7bb174e8167 100644
--- a/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
+++ b/typo3/sysext/core/Classes/Utility/ExtensionManagementUtility.php
@@ -1230,7 +1230,7 @@ tt_content.' . $key . $suffix . ' {
         if ($afterStaticUid) {
             // If 'defaultContentRendering' is targeted (formerly static uid 43),
             // the content is added after TypoScript of type contentRendering, e.g. fluid_styled_content, see
-            // EXT:core/Classes/TypoScript/TemplateService.php for more information on how the code is parsed.
+            // EXT:core/Classes/TypoScript/IncludeTree/TreeBuilder.php for more information on how the code is parsed.
             if ($afterStaticUid === 'defaultContentRendering' || $afterStaticUid == 43) {
                 $GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'] ??= '';
                 $GLOBALS['TYPO3_CONF_VARS']['FE']['defaultTypoScript_' . $type . '.']['defaultContentRendering'] .= $content;
diff --git a/typo3/sysext/core/Configuration/DefaultConfiguration.php b/typo3/sysext/core/Configuration/DefaultConfiguration.php
index 6db2bf6208df772ea10e88d897b2c2bee3bfb4c3..d835d61f6126ce5016101921be1f6e912c6a82d1 100644
--- a/typo3/sysext/core/Configuration/DefaultConfiguration.php
+++ b/typo3/sysext/core/Configuration/DefaultConfiguration.php
@@ -1384,7 +1384,7 @@ return [
         'additionalCanonicalizedUrlParameters' => [],
         'workspacePreviewLogoutTemplate' => '',
         'versionNumberInFilename' => 'querystring',
-        'contentRenderingTemplates' => [], // Array to define the TypoScript parts that define the main content rendering. Extensions like "fluid_styled_content" provide content rendering templates. Other extensions like "felogin" or "indexed search" extend these templates and their TypoScript parts are added directly after the content templates. See EXT:fluid_styled_content/ext_localconf.php and EXT:frontend/Classes/TypoScript/TemplateService.php
+        'contentRenderingTemplates' => [], // Array to define the TypoScript parts that define the main content rendering. Extensions like "fluid_styled_content" provide content rendering templates. Other extensions like "felogin" or "indexed search" extend these templates and their TypoScript parts are added directly after the content templates.
         'typolinkBuilder' => [  // Matches the LinkService implementations for generating URL, link text via typolink
             'page' => \TYPO3\CMS\Frontend\Typolink\PageLinkBuilder::class,
             'file' => \TYPO3\CMS\Frontend\Typolink\FileOrFolderLinkBuilder::class,
diff --git a/typo3/sysext/core/Documentation/Changelog/12.1/Deprecation-99020-DeprecateTypoScriptTemplateService.rst b/typo3/sysext/core/Documentation/Changelog/12.1/Deprecation-99020-DeprecateTypoScriptTemplateService.rst
new file mode 100644
index 0000000000000000000000000000000000000000..1bb16d4f85f480adfc8a7005baebb51b73f6ef36
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/12.1/Deprecation-99020-DeprecateTypoScriptTemplateService.rst
@@ -0,0 +1,49 @@
+.. include:: /Includes.rst.txt
+
+.. _deprecation-99020-1667911024:
+
+==========================================================
+Deprecation: #99020 - Deprecate TypoScript/TemplateService
+==========================================================
+
+See :issue:`99020`
+
+Description
+===========
+
+Class :php:`TYPO3\CMS\Core\TypoScript\TemplateService` has been marked as deprecated
+in TYPO3 v12 and will be removed in v13. This class is sometimes indirectly accessed
+using :php:`TypoScriptFrontendController->tmpl` or :php:`$GLOBALS['TSFE']->tmpl`.
+
+
+Impact
+======
+
+Class :php:`TemplateService` is part of the old TypoScript parser and has been
+substituted with a new parser approach. Actively calling class methods will
+trigger a deprecation log level warning.
+
+
+Affected installations
+======================
+
+Instances with extensions directly using :php:`TemplateService` or indirectly
+using it by calling :php:`TypoScriptFrontendController->tmpl` or
+:php:`$GLOBALS['TSFE']->tmpl` are affected.
+
+
+Migration
+=========
+
+Class :php:`TemplateService` is typically called in TYPO3 Frontend scope. Extensions
+should avoid using :php:`TypoScriptFrontendController->tmpl` and :php:`$GLOBALS['TSFE']->tmpl`
+methods and properties. They can retrieve TypoScript from the PSR-7 Request instead
+using the attribute :php:`frontend.typoscript`. As example, the full Frontend TypoScript
+can be retrieved like this:
+
+.. code-block:: php
+
+    $fullTypoScript = $request()->getAttribute('frontend.typoscript')->getSetupArray();
+
+
+.. index:: PHP-API, FullyScanned, ext:core
diff --git a/typo3/sysext/core/Tests/UnitDeprecated/TypoScript/Fixtures/ext_typoscript_setup.typoscript b/typo3/sysext/core/Tests/UnitDeprecated/TypoScript/Fixtures/ext_typoscript_setup.typoscript
new file mode 100644
index 0000000000000000000000000000000000000000..b843d96cb232717b2843fdeb67c5d8050c060289
--- /dev/null
+++ b/typo3/sysext/core/Tests/UnitDeprecated/TypoScript/Fixtures/ext_typoscript_setup.typoscript
@@ -0,0 +1 @@
+test.Core.TypoScript = 1
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Unit/TypoScript/TemplateServiceTest.php b/typo3/sysext/core/Tests/UnitDeprecated/TypoScript/TemplateServiceTest.php
similarity index 98%
rename from typo3/sysext/core/Tests/Unit/TypoScript/TemplateServiceTest.php
rename to typo3/sysext/core/Tests/UnitDeprecated/TypoScript/TemplateServiceTest.php
index ec5abe8b0ff5cd0a5c8f0b93a3e0a3cbda45333a..fa2e771fd5c9c565d0fe5d1a68992c251f246dcc 100644
--- a/typo3/sysext/core/Tests/Unit/TypoScript/TemplateServiceTest.php
+++ b/typo3/sysext/core/Tests/UnitDeprecated/TypoScript/TemplateServiceTest.php
@@ -15,7 +15,7 @@ declare(strict_types=1);
  * The TYPO3 project - inspiring people to share!
  */
 
-namespace TYPO3\CMS\Core\Tests\Unit\TypoScript;
+namespace TYPO3\CMS\Core\Tests\UnitDeprecated\TypoScript;
 
 use PHPUnit\Framework\MockObject\MockObject;
 use TYPO3\CMS\Core\Context\Context;
diff --git a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
index 6adc6e91af1164407016765140d2cd60f09c9d32..bf16b0bd4de0c21d168efa9e47ab35577b29200c 100644
--- a/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
+++ b/typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
@@ -1431,7 +1431,6 @@ class TypoScriptFrontendController implements LoggerAwareInterface
 
                 // Create top-level setup AST 'types' node from all top-level PAGE objects.
                 // This is essentially a preparation for type-lookup below and should vanish later.
-                // Previously, TemplateService->generateConfig() did that.
                 $typesNode = new ChildNode('types');
                 $gotTypeNumZero = false;
                 foreach ($setupAst->getNextChild() as $setupChild) {
diff --git a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php
index 5442934eecc7b1fc04243b7bb279dbced695d339..215de7bcf22d7a55c7707223d8c800f246bc129f 100644
--- a/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php
+++ b/typo3/sysext/frontend/Classes/Typolink/PageLinkBuilder.php
@@ -572,8 +572,6 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
      * Initializes the automatically created mountPointMap coming from the "config.MP_mapRootPoints" setting
      * Can be called many times with overhead only the first time since then the map is generated and cached in memory.
      *
-     * Previously located within TemplateService::getFromMPmap()
-     *
      * @param int $pageId Page id to return MPvar value for.
      * @return string
      */
@@ -637,7 +635,6 @@ class PageLinkBuilder extends AbstractTypolinkBuilder
 
     /**
      * Creating mountPointMap for a certain ID root point.
-     * Previously called TemplateService->initMPmap_create()
      *
      * @param array $mountPointMap the exiting mount point map
      * @param int $id Root id from which to start map creation.
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
index 1e345ffbcc93bd27c4f99cd9da9201e169aedb53..64d85dc2d75177da0c5ddf4e1993a633a02e48fd 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
@@ -2202,4 +2202,10 @@ return [
             'Deprecation-98996-DoctrineDBALBackendWorkspaceRestrictionAndFrontendWorkspaceRestriction.rst',
         ],
     ],
+    'TYPO3\CMS\Core\TypoScript\TemplateService' => [
+        'restFiles' => [
+            'Deprecation-99020-DeprecateTypoScriptTemplateService.rst',
+            'Breaking-97816-NewTypoScriptParserInFrontend.rst',
+        ],
+    ],
 ];
diff --git a/typo3/sysext/t3editor/Resources/Private/tsref.xml b/typo3/sysext/t3editor/Resources/Private/tsref.xml
index 31d2214f551fffa1ad7de18c4c5192471e7d7513..c5bd4876fa63e96f59f5cf1c18d19ba05ba0d592 100644
--- a/typo3/sysext/t3editor/Resources/Private/tsref.xml
+++ b/typo3/sysext/t3editor/Resources/Private/tsref.xml
@@ -205,7 +205,7 @@ This will by default add "&MP=2-207" to all links pointing to pages 36,37 and 48
 		<property name="MP_mapRootPoints" type="string">
 			<description><![CDATA[list of PIDs/string
       Defines a list of ID numbers from which the MP-vars are automatically calculated for the branch.
-The result is used just like MP_defaults are used to find MP-vars if none has been specified prior to the call to \TYPO3\CMS\Core\TypoScript\TemplateService::linkData().
+The result is used just like MP_defaults are used to find MP-vars if none has been specified.
 You can specify "root" as a special keyword in the list of IDs and that will create a map-tree for the whole site (but this may be VERY processing intensive if there are many pages!).
 The order of IDs specified may have a significance; Any ID in a branch which is processed already (by a previous ID root point) will not be processed again.]]></description>
 			<default><![CDATA[
@@ -2488,7 +2488,7 @@ Basically this shows that
 
 - the fields "header_layout", "bodytext" and "image" are mapped to non-existing fields in the page-record
 
-- a new field, "sectionIndex_uid" is introduced in the page-record which is detected by the function \TYPO3\CMS\Core\TypoScript\TemplateService->linkData(). If this field is present in a pagerecord, the linkData()-function will prepend a hash-mark and the number of the field.
+- a new field, "sectionIndex_uid" is introduced in the page-record. If this field is present in a page record, the linkData()-function will prepend a hash-mark and the number of the field.
 
 NOTE: