<!-- SPDX-License-Identifier: CC-BY-SA-4.0 -->
<!-- SPDX-FileCopyrightText: Netresearch DTT GmbH -->
# TYPO3 DDEV Skill
> An Agent Skill for automating DDEV environment setup in TYPO3 extension projects
[](https://typo3.org/)
[](https://ddev.com/)
[](#license)
[](https://agentskills.io)
## 🔌 Compatibility
This is an **Agent Skill** following the [open standard](https://agentskills.io) originally developed by Anthropic and released for cross-platform use.
**Supported Platforms:**
- ✅ Claude Code (Anthropic)
- ✅ Cursor
- ✅ Windsurf
- ✅ GitHub Copilot
- ✅ Other skills-compatible AI agents
> Skills are portable packages of procedural knowledge that work across any AI agent supporting the Agent Skills specification.
## Overview
This skill helps TYPO3 extension developers quickly set up a complete DDEV development environment with multiple TYPO3 versions. Instead of manually configuring DDEV, this skill automates the entire process - from detecting your extension metadata to generating all configuration files and installing TYPO3.
### What It Does
- ✅ Detects TYPO3 extension projects automatically
- ✅ Extracts extension metadata (key, package name, namespace)
- ✅ Generates complete DDEV configuration
- ✅ Creates multi-version TYPO3 testing environment (11.5, 12.4, 13.4 and 14.3 LTS)
- ✅ Provides backend and frontend access with preconfigured credentials
- ✅ Includes custom DDEV commands for easy TYPO3 installation
### Who It's For
- TYPO3 extension developers
- Teams working on TYPO3 extensions
- Developers needing to test extensions across multiple TYPO3 versions
- Anyone wanting a quick, reproducible TYPO3 development environment
## Prerequisites
Before using this skill, ensure you have:
- [DDEV](https://ddev.readthedocs.io/en/stable/users/install/ddev-installation/) installed
- [Docker](https://www.docker.com/get-started) running
- A TYPO3 extension project (with `ext_emconf.php` or `composer.json`)
- A skills-compatible AI agent (Claude Code, Cursor, Windsurf, GitHub Copilot, etc.)
## Installation
### Marketplace (Recommended)
Add the [Netresearch marketplace](https://github.com/netresearch/claude-code-marketplace) once, then browse and install skills:
```bash
# Claude Code
/plugin marketplace add netresearch/claude-code-marketplace
/plugin install typo3-ddev@netresearch-claude-code-marketplace
```
### Without a marketplace
Since Claude Code 2.1.157 a plugin directory under your personal skills directory loads on its own:
```bash
mkdir -p ~/.claude/skills
git clone https://github.com/netresearch/typo3-ddev-skill.git \
~/.claude/skills/typo3-ddev
```
It loads as `typo3-ddev@skills-dir` on the next session. Update with `git -C ~/.claude/skills/typo3-ddev pull` and start a new session; remove it by deleting the directory. This route has no `claude plugin update`.
### npx ([skills.sh](https://skills.sh))
Install with any [Agent Skills](https://agentskills.io)-compatible agent:
```bash
npx skills add https://github.com/netresearch/typo3-ddev-skill --skill typo3-ddev
```
### Download Release
Download the [latest release](https://github.com/netresearch/typo3-ddev-skill/releases/latest) and extract to your agent's skills directory.
### Git Clone
```bash
git clone https://github.com/netresearch/typo3-ddev-skill.git
```
### Composer (PHP Projects)
```bash
composer require netresearch/typo3-ddev-skill
```
Requires [netresearch/composer-agent-skill-plugin](https://github.com/netresearch/composer-agent-skill-plugin).
## Usage
### Invoking the Skill
Once installed, invoke the skill in your TYPO3 extension project directory:
**Via slash command:**
```
/typo3-ddev
```
**Via natural language:**
```
Set up DDEV for my TYPO3 extension
```
The skill will:
1. Validate prerequisites (DDEV, Docker, TYPO3 extension structure)
2. Extract your extension metadata
3. Confirm configuration with you
4. Generate all `.ddev/` files with proper values
5. Guide you through starting DDEV and installing TYPO3
### What You'll Get
After setup, you'll have:
```
project-root/
├── .ddev/
│ ├── config.yaml
│ ├── docker-compose.web.yaml
│ ├── apache/
│ │ └── apache-site.conf
│ ├── web-build/
│ │ └── Dockerfile
│ └── commands/
│ └── web/
│ ├── install-v11
│ ├── install-v12
│ ├── install-v13
│ ├── install-v14
│ └── install-all
├── Classes/
├── Configuration/
├── ext_emconf.php
└── composer.json
```
### Accessing Your Environment
Once installed, access TYPO3 at:
**Overview Dashboard:**
```
https://your-ext.ddev.site/
```
**TYPO3 14.3 LTS (default / gold standard):**
- Frontend: `https://v14.your-ext.ddev.site/`
- Backend: `https://v14.your-ext.ddev.site/typo3/`
**TYPO3 13.4 LTS:**
- Frontend: `https://v13.your-ext.ddev.site/`
- Backend: `https://v13.your-ext.ddev.site/typo3/`
**TYPO3 12.4 LTS:**
- Frontend: `https://v12.your-ext.ddev.site/`
- Backend: `https://v12.your-ext.ddev.site/typo3/`
**TYPO3 11.5 LTS (ELTS):**
- Frontend: `https://v11.your-ext.ddev.site/`
- Backend: `https://v11.your-ext.ddev.site/typo3/`
### Backend Credentials
```
Username: admin
Password: Joh316!!
```
### Branded Landing Page
The overview dashboard automatically uses branded templates based on your project:
| Vendor | Template | Branding |
|--------|----------|----------|
| `netresearch/*` | Netresearch | Turquoise (#2F99A4), [n] logo |
| All others | TYPO3 | Orange (#FF8700), TYPO3 swoosh |
**Features:**
- Three-state theme switcher (Light / System / Dark)
- Git branch and commit info display
- Links to TER, Packagist, GitHub, Documentation, Mailpit
- TYPO3 version cards with Frontend/Backend links
- Composer package name display
Generate or regenerate the landing page:
```bash
ddev generate-index
```
**Template Variables** (auto-detected from `composer.json`):
- `{{EXTENSION_NAME}}` - Human-readable extension name
- `{{COMPOSER_PACKAGE}}` - Composer package name
- `{{TER_EXTENSION_KEY}}` - TER extension key
- `{{GITHUB_REPO}}` - GitHub repository URL
- `{{GIT_BRANCH}}` - Current git branch
- `{{GIT_COMMIT_SHORT}}` - Short commit hash
## Custom DDEV Commands
The skill creates these custom commands:
```bash
# Install specific TYPO3 version
ddev install-v14 # TYPO3 14.3 LTS (default / gold standard)
ddev install-v13 # TYPO3 13.4 LTS
ddev install-v12 # TYPO3 12.4 LTS
ddev install-v11 # TYPO3 11.5 LTS (ELTS)
# Install all versions at once
ddev install-all
# Install Introduction Package (demo content)
ddev install-introduction v13
```
## Adding Demo Content
Test your extension with realistic content using the TYPO3 Introduction Package:
```bash
# Install Introduction Package
ddev install-introduction v13
```
**Includes:**
- 86+ pages with example content
- 226+ content elements (text, images, forms, tables)
- Multi-language support (EN, DE, DA)
- Bootstrap Package responsive theme
- Perfect for testing RTE features
## Extension Auto-Configuration
For extensions needing additional setup (RTE config, TSconfig, TypoScript), create a custom configuration command:
```bash
# Copy template
cp .ddev/templates/commands/web/configure-extension.optional \
.ddev/commands/web/configure-myext
# Customize for your extension's needs
# Add: RTE YAML, Page TSConfig, TypoScript, site package setup
# Run after TYPO3 installation
ddev configure-myext v13
```
**Use Cases:**
- **RTE/CKEditor plugins** - Configure toolbar, import plugin YAML
- **Backend modules** - Set up TSconfig, permissions
- **Frontend plugins** - TypoScript configuration, example content
**Pattern Benefits:**
- One-command post-install setup
- Consistent team configuration
- Includes demo content automatically
- Reduces manual configuration errors
See `SKILL.md` for detailed examples and template structure.
## Troubleshooting
### Database Already Exists
If reinstalling TYPO3:
```bash
ddev mysql -e "DROP DATABASE IF EXISTS v13; CREATE DATABASE v13;"
ddev install-v13
```
### Services Not Starting
Check and restart services:
```bash
docker ps --filter "name=ddev-your-ext"
ddev restart
```
### Extension Not Visible
Flush caches:
```bash
ddev exec -d /var/www/html/v13 vendor/bin/typo3 cache:flush
```
## Architecture
The setup creates a unique multi-version environment:
- **Extension Source**: Mounted at `/var/www/{{EXTENSION_KEY}}` (your project root)
- **TYPO3 Installations**: Separate directories for each version (`/var/www/html/v11`, `v12`, `v13`, `v14`)
- **Extension Installation**: Installed via Composer path repository in each TYPO3 version
- **Persistent Data**: Docker volumes for each TYPO3 version database and files
This architecture allows you to:
- Develop extension code in your project root
- Test immediately across all TYPO3 versions
- Keep TYPO3 installations separate and clean
- Avoid committing TYPO3 core files to your extension repository
## Configuration
### Supported TYPO3 Versions
By default, the skill supports:
- TYPO3 14.3 LTS (PHP 8.2+, up to 8.5) — **default / gold standard**
- TYPO3 13.4 LTS (PHP 8.2+)
- TYPO3 12.4 LTS (PHP 8.1+)
- TYPO3 11.5 LTS (PHP 8.0+) — ELTS
PHP version is set to 8.2 for maximum compatibility.
### Customization
After generation, you can customize:
**PHP Version** (`.ddev/config.yaml`):
```yaml
php_version: "8.3" # Change to 8.1, 8.3, or 8.5 if needed
```
**PHP Patch Upgrades** (`.ddev/web-build/Dockerfile.apt`):
When DDEV ships an older PHP patch (e.g., 8.5.0RC3) and you need a newer one (e.g., 8.5.1):
```dockerfile
# .ddev/web-build/Dockerfile.apt
RUN apt-get update
RUN apt-get install --only-upgrade -y php${PHP_VERSION}-*
```
Then run `ddev restart`.
**PHP Extensions** (`.ddev/web-build/Dockerfile`):
```dockerfile
# Use apt-get, NOT pecl (pecl not available in DDEV)
RUN apt-get update && apt-get install -y php${PHP_VERSION}-pcov
RUN apt-get update && apt-get install -y php${PHP_VERSION}-redis
```
**Custom PHP Settings** (`.ddev/php/custom.ini`):
```ini
memory_limit = 512M
max_execution_time = 300
```
**XDebug** (enable/disable):
```bash
ddev xdebug on # Enable
ddev xdebug off # Disable
```
**Database** (Tiered Selection: SQLite/MariaDB/PostgreSQL/MySQL):
The skill uses **intelligent tiered database selection** based on extension complexity:
**🎯 Tier 1: SQLite (Simple Extensions - Development Optimized)**
For extensions using only TYPO3 Core APIs (no custom tables, no raw SQL):
```yaml
# No .ddev/config.yaml database config needed
# TYPO3 installation automatically uses SQLite
```
**Benefits:**
- ⚡ Startup: 5-10 seconds faster per ddev start
- 💾 RAM: 900 MB saved (no container)
- 💿 Disk: 744 MB saved
- 🔒 Perfect v11/v12/v13 isolation
**⚠️ Development ONLY** - Never use SQLite in production. Switch to MariaDB for final testing.
**🔧 Tier 2: MariaDB 10.11 (Complex Extensions - Production Parity)**
For extensions with custom tables, raw SQL, or unknown complexity:
```yaml
# Default for complex extensions (.ddev/config.yaml)
database:
type: mariadb
version: "10.11"
```
**Why MariaDB 10.11?** Production standard (95% hosting), extension compatibility, 13-36% faster than MySQL 8.
**🌐 Tier 3 & 4: Specialized Databases**
```yaml
# PostgreSQL 16 (for GIS, analytics, full-text search)
database:
type: postgres
version: "16"
# MariaDB 11 (forward-looking performance)
database:
type: mariadb
version: "11.4"
# MySQL 8.0 (corporate/Oracle ecosystem)
database:
type: mysql
version: "8.0"
```
**For detailed rationale**, see `docs/adr/0002-mariadb-default-with-database-alternatives.md`.
**Caching Service** (Valkey or Redis):
The skill provides Valkey 8 as the default caching service (open source, future-proof):
```bash
# Default: Valkey 8
cp .ddev/templates/docker-compose.services.yaml.optional .ddev/docker-compose.services.yaml
# Alternative: Redis 7 (for legacy production parity)
cp .ddev/templates/docker-compose.services-redis.yaml.optional .ddev/docker-compose.services.yaml
# Restart DDEV
ddev restart
```
**Why Valkey?** True open source (BSD-3), AWS/Google/Oracle backing, 30% smaller than Redis 8, cost-effective. See `docs/adr/0001-valkey-default-with-redis-alternative.md` for details.
**Additional Services** (add to `.ddev/docker-compose.services.yaml`):
```yaml
# The services template includes: Valkey/Redis, MailPit, Ofelia
# See SKILL.md for complete documentation
```
## Troubleshooting
### DDEV Won't Start
**Port Conflicts:**
```bash
# Check what's using ports 80/443
sudo lsof -i :80
sudo lsof -i :443
# Option 1: Stop conflicting services
# Option 2: Change ports in .ddev/config.yaml
router_http_port: "8080"
router_https_port: "8443"
```
### PHP Version Outdated
If DDEV ships with an older PHP patch version:
```bash
# Create .ddev/web-build/Dockerfile.apt
echo 'RUN apt-get update' > .ddev/web-build/Dockerfile.apt
echo 'RUN apt-get install --only-upgrade -y php${PHP_VERSION}-*' >> .ddev/web-build/Dockerfile.apt
ddev restart
```
### PCOV/Extension Installation Fails
DDEV doesn't include `pecl`. Use `apt-get` instead:
```dockerfile
# In .ddev/web-build/Dockerfile
RUN apt-get update && apt-get install -y php${PHP_VERSION}-pcov
```
### PHP Settings Not Applied
Place settings in `.ddev/php/custom.ini`, NOT in `/usr/local/etc/php/conf.d/`:
```ini
# .ddev/php/custom.ini (correct location)
memory_limit = 512M
```
### Installation Fails
**Check Composer Issues:**
```bash
ddev ssh
composer diagnose
```
**View Installation Logs:**
```bash
ddev logs
```
**Retry Installation:**
```bash
# For specific version
ddev ssh
rm -rf /var/www/html/v13/*
exit
ddev install-v13
```
### Extension Not Appearing
**Verify Extension Key:**
```bash
ddev ssh
echo $EXTENSION_KEY # Should match your ext_emconf.php
```
**Check Composer Repository:**
```bash
ddev ssh
cd /var/www/html/v13
composer config repositories
```
For complete troubleshooting guide, see `references/troubleshooting.md`.
## Contributing
Contributions welcome! Please:
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request
The commands for working on this repository are listed in [AGENTS.md](AGENTS.md#commands). A pull request that adds or changes behaviour in a script adds or updates a check in `tests/` that fails without the change.
### Tests
The behavioural tests live in `tests/` and run offline, without Docker or DDEV; they need bash, coreutils, git, sed, jq and python3, and php for two checks of `additional.php`:
```bash
bash tests/provision-without-ddev.sh # skills/typo3-ddev/scripts/provision-without-ddev.sh
bash tests/validate-prerequisites.sh # skills/typo3-ddev/scripts/validate-prerequisites.sh
bash tests/check-plugin-version.sh # Build/Scripts/check-plugin-version.sh and Build/hooks/pre-push
bash tests/git-info-templates.sh # git-info hook, pre-start-git-info and generate-index templates
```
- `tests/provision-without-ddev.sh` replaces composer, php, curl, apache2ctl, a2enmod and sleep with stubs that log their arguments, and checks the argument errors, what the provisioner reads from `.ddev/config.yaml`, the site configuration, that `additional.php` parses and holds a password with a quote and a backslash unchanged, the `--serve` path, and that a backend that never answers ends the run with exit 1.
- `tests/validate-prerequisites.sh` runs the prerequisite check with stubbed `docker` and `ddev` on an isolated `PATH` and checks each missing prerequisite and the Docker 20.10 and Compose 2.0 boundaries.
- `tests/check-plugin-version.sh` builds throwaway git repositories and checks that a semver tag at `HEAD` must match the version in `.claude-plugin/plugin.json`, and that the pre-push hook passes the result on.
- `tests/git-info-templates.sh` runs the `config.yaml` post-start hook (with a `ddev` stub that runs `ddev exec` locally), `pre-start-git-info` and `generate-index` in a throwaway repository whose branch name and commit subject hold shell, YAML, sed, HTML and CSS metacharacters, and checks that each value arrives as written and that nothing in it runs.
Each check prints `ok` or `FAIL`; a `FAIL` line names the expectation that was not met and is followed by the script's output. A test file exits 1 when any check failed. In CI, the Skill Tests workflow (`.github/workflows/tests.yml`) runs every `tests/**/*.sh` on each pull request and on pushes to `main`, and fails when the repository ships scripts under `skills/*/scripts/` but no test ran.
Not covered by tests: the DDEV templates under `skills/typo3-ddev/assets/templates/` other than the three git-info ones (their commands need a running DDEV project) and `scripts/verify-harness.sh`. The skill's Markdown is not executed; Skill Validation checks its structure, and Eval Validation checks the eval definitions in `evals/evals.json`. `pre-commit run --all-files` runs the hooks of [`.pre-commit-config.yaml`](.pre-commit-config.yaml) locally.
### Dependencies
- **Composer:** `composer.json` requires `netresearch/composer-agent-skill-plugin` (`*`, the latest release at install time), which installs the skill into a PHP project. No `composer.lock` is committed.
- **What the skill installs in a user's project:** TYPO3 and its packages through Composer, and the container images named in the templates. Which versions and images, and how they are verified, is listed in [docs/SECURITY-ASSURANCE.md](docs/SECURITY-ASSURANCE.md#downloads-and-how-they-are-verified). They are chosen per TYPO3 LTS version (`commands/install-v11` … `install-v14`) and by the ADRs in `skills/typo3-ddev/references/` (Valkey, database, PHP version).
- **Scripts:** `provision-without-ddev.sh` needs bash, composer, php, sed and, with `--serve`, Apache and curl; `validate-prerequisites.sh` needs docker and ddev to report on them. Neither installs tools.
- **Development tools:** the hooks in `.pre-commit-config.yaml` are pinned by `rev:`. Renovate ([`renovate.json`](renovate.json), `config:recommended` with the pre-commit manager enabled) proposes updates for them. The Composer requirement has no version range and no lock file, so there is nothing for it to update.
- **CI:** the workflows call reusable workflows of `netresearch/.github`, `netresearch/skill-repo-skill` and `netresearch/typo3-ci-workflows`; those reusables pin the actions they use by commit SHA.
## Governance and policies
This repository follows the Netresearch organisation policies:
- [Governance](https://github.com/netresearch/.github/blob/main/GOVERNANCE.md): ownership, roles, how decisions are made and disputes resolved, and continuity.
- [Roadmap](https://github.com/netresearch/.github/blob/main/ROADMAP.md): planned and explicitly excluded work for the coming year.
- [Handling of dependency and code analysis findings](https://github.com/netresearch/.github/blob/main/SECURITY.md#handling-of-dependency-and-code-analysis-findings): thresholds, deadlines and the exception process for dependency (SCA) and static analysis (SAST) findings.
- [Secret management](https://github.com/netresearch/.github/blob/main/SECURITY.md#secret-management): how CI and release credentials are stored, accessed and rotated.
- [Access roster](https://github.com/netresearch/.github/blob/main/docs/access-roster.md): who holds administrative access to this repository and the organisation.
The security assurance case for this skill (what it downloads, trust boundaries, threats, countermeasures and limits) is in [docs/SECURITY-ASSURANCE.md](docs/SECURITY-ASSURANCE.md).
Checks that run on pull requests in this repository:
- Every pull request: Skill Validation (`lint.yml`: skill structure, markdownlint, yamllint, actionlint, JSON syntax, ShellCheck at severity error, ruff, checkpoint schema), Eval Validation (`eval-validate.yml`) and Skill Tests (`tests.yml`).
- Pull requests to `main`: `security.yml` with Betterleaks (secret scanning), zizmor (workflow static analysis), dependency review (fails on vulnerabilities of severity high or above), Composer Audit and Opengrep SAST (findings handled under the [organisation's static analysis rule](https://github.com/netresearch/.github/blob/main/SECURITY.md#static-analysis-sast)), and CodeQL (the GitHub Actions workflows); Harness Verification (`harness-verify.yml`) and Template Drift (`check-template-drift.yml`).
- Every pull request, from the template workflows: Labeler (`labeler.yml`) and the dependency auto-merge job (`auto-merge-deps.yml`, skipped unless a dependency bot opened the pull request).
- Configured outside the workflows: SonarCloud code analysis, the DCO sign-off check, Copilot code review (a repository ruleset), CodeRabbit review, and GitHub secret scanning with push protection.
## Credits
This skill is based on the excellent work by [Armin Vieweg](https://github.com/a-r-m-i-n) in [ddev-for-typo3-extensions](https://github.com/a-r-m-i-n/ddev-for-typo3-extensions).
### Additional Resources
- [DDEV Documentation](https://ddev.readthedocs.io/)
- [TYPO3 Extension Development](https://docs.typo3.org/m/typo3/reference-coreapi/main/en-us/ExtensionArchitecture/Index.html)
- [TYPO3 DDEV Setup Guide](https://docs.typo3.org/m/typo3/tutorial-getting-started/main/en-us/Installation/UsingDdev.html)
## License
This project uses split licensing:
- **Code** (scripts, workflows, configs): [MIT](LICENSE-MIT)
- **Content** (skill definitions, documentation, references): [CC-BY-SA-4.0](LICENSE-CC-BY-SA-4.0)
See the individual license files for full terms.
## Support
- **Issues**: [GitHub Issues](https://github.com/netresearch/typo3-ddev-skill/issues)
- **Discussions**: [GitHub Discussions](https://github.com/netresearch/typo3-ddev-skill/discussions)
- **TYPO3 Slack**: #ddev channel
---
**Made with ❤️ for the TYPO3 Community by [Netresearch DTT GmbH](https://www.netresearch.de/)**