Using ddev for development of TYPO3 extensions

As an author and maintainer of several TYPO3 extensions that also support multiple TYPO3 versions, I once faced the problem of how to develop and test them in a simple way. Each extension has its own Git repository and when testing for different TYPO3 versions, cloning or copying the source code multiple times to different TYPO3 versions was not the way I was happy with.

At the time, I had a local Apache installation on my Linux notebook. With symlinks this worked more or less: Different TYPO3 version need different PHP versions. And most importantly, I don't want to have multiple PHP versions installed locally along with Apache. Then ddev came into my life, which made the workflow a lot of easier. If you don't know it yet, have a look at the ddev documentation.

So, let's get started.

The starting point

My extensions are organised in a Projects folder as follows:

  ├── codehighlight
  ├── form_country_select
  ├── matomo_integration
  ├── matomo_widgets
  ├── schema
  ├── typo3v10
  └── typo3v11

The Git repositories for the extensions are stored there along with TYPO3 installations for different versions that are ddev projects.

Now we have to take two steps to integrate these extensions into the TYPO3 installations:

  1. Symlink the extension folder into the TYPO3 project
  2. Mount the extension in the ddev web container

Symlink the extension folder into the TYPO3 project

First, the extension folder, for example schema, is symlinked into the TYPO3 project:

  ├── typo3v11
  │   ├── packages
  │   │   └─ schema -> /home/chris/Projects/schema

Under Linux, you link a folder with the command ln:

ln -s /home/chris/Projects/schema schema

In the Windows prompt, for example, this is done (possibly as administrator):

mklink /d schema C:\Users\Chris\Projects\schema

In this way, access to this extension is possible within an IDE in the project itself, for example for debugging purposes.

Mount the extension in the ddev web container

Next, we need to mount the extension directory in the ddev web container to make it available there. For this purpose, a file docker-compose.volumes.yaml is created:

version: '3.6'

      - "/home/chris/Projects/schema:/var/www/html/packages/schema"

Then we add the local packages path to the composer.json of the project so that the extension can be found there by composer:

ddev composer config repositories.local path "packages/*"

The last step is to add the extension to the composer.json file of the project:

ddev composer req "brotkrueml/schema:*@dev"


This workflow helps me a lot when developing TYPO3 extension for multiple TYPO3 versions. I have the choice to code in the extension project  and also in a TYPO3 project directly — and of course to debug there.