---
title: "Environment Builder"
manual: "Environment State Manager"
version: "main"
permalink: "https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-environment-builder@main"
source: "Developer/EnvironmentBuilder/Index.rst"
rendered: "2026-10-17T14:50:33+00:00"
---

# Environment Builder {#developer-environment-builder}

An environment builder creates a `StateInterface` instance describing a
fully bootstrapped TYPO3 environment for a given `StateBuildContext`.

## The build context {#the-build-context}

The `StateBuildContext` is a small, immutable DTO describing *what*
environment should be built:

```php
use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::FRONTEND,
    pageId: 1,
    languageId: 0,
);
```

## The factory {#the-factory}

The concrete builder differs between the supported TYPO3 core versions. Use the
`EnvironmentBuilderFactoryInterface` to retrieve a TYPO3 core version
compatible builder for the given context. The factory is registered as a public
service and can be injected through dependency injection:

```php
use FGTCLB\EnvironmentStateManager\EnvironmentBuilderFactoryInterface;
use FGTCLB\EnvironmentStateManager\StateBuildContext;
use FGTCLB\EnvironmentStateManager\StateInterface;
use TYPO3\CMS\Core\Http\ApplicationType;

final class MyService
{
    public function __construct(
        private readonly EnvironmentBuilderFactoryInterface $environmentBuilderFactory,
    ) {}

    public function buildState(int $pageId): StateInterface
    {
        $stateBuildContext = new StateBuildContext(
            applicationType: ApplicationType::FRONTEND,
            pageId: $pageId,
            languageId: 0,
        );

        $environmentBuilder = $this->environmentBuilderFactory->create($stateBuildContext);

        return $environmentBuilder->build($stateBuildContext);
    }
}
```

The returned `StateInterface` holds the version-agnostic bootstrapped
environment elements, for example the `ServerRequestInterface`, the
`PageRenderer` and the `Context`.

On TYPO3 v13, TYPO3 core-version specific state lives on the matching
`Core13ExtendedStateInterface`. In particular the
`TypoScriptFrontendController` accessors are declared there, because the
`TypoScriptFrontendController` is deprecated in TYPO3 v13. Narrow the
returned state to `Core13ExtendedStateInterface` when you explicitly need
that TYPO3 v13 specific state. TYPO3 v14 removed the
`TypoScriptFrontendController` and therefore has no extended state
interface: `Core14State` implements the version-agnostic
`StateInterface` directly.

> [!NOTE]
> Always type-hint the `EnvironmentBuilderFactoryInterface`,
> `EnvironmentBuilderInterface` and `StateInterface`, never the
> concrete `Core13*` or `Core14*` classes. The dependency injection
> container resolves the implementation for the running TYPO3 core version. See
> [Public API and stability](https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-public-api@main) for the full public API surface.

Both the `ApplicationType::FRONTEND` and `ApplicationType::BACKEND`
application types are implemented, provided by the
`FrontendEnvironmentBuilder` and the `BackendEnvironmentBuilder`
respectively. A
`FGTCLBEnvironmentStateManagerExceptionNoTypo3VersionCompatibleEnvironmentBuilderFound`
exception is thrown when no builder is available for the current TYPO3 core
version.

## Building a backend environment {#building-a-backend-environment}

For `ApplicationType::BACKEND` the build context additionally accepts the
backend user and the workspace to operate in. The builder assembles a backend
request, a backend user, a language service and a context with the
`backend.user` and `workspace` aspects for the selected page:

```php
use FGTCLB\EnvironmentStateManager\StateBuildContext;
use TYPO3\CMS\Core\Http\ApplicationType;

$stateBuildContext = new StateBuildContext(
    applicationType: ApplicationType::BACKEND,
    pageId: 42,
    // Optional: the backend user to load. Defaults to a synthetic in-memory
    // admin that needs no `be_users` record.
    backendUserId: null,
    // Optional: the workspace to operate in. Defaults to the live workspace.
    workspaceId: null,
);

$this->stateManager->execute($stateBuildContext, function () {
    // Code in here runs within the backend environment built for page 42,
    // e.g. BackendUtility::getPagesTSconfig(42) resolves the page TSconfig.
});
```

In most cases you do not interact with the builder directly but use the
[state manager](https://docs.typo3.org/permalink/fgtclb/environment-state-manager:developer-state-manager@main), which uses the factory
internally.
