Skip to main navigation Skip to main content Skip to page footer

TYPO3 Extension Repository Speaks composer.json

The TYPO3 Extension Repository (TER) now accepts extensions with composer.json as their only manifest. Authors no longer need an ext_emconf.php file to upload, and for versions that require TYPO3 v14.3 or newer, TER publishes the exact archive the author uploaded.

On 14 September 2026, the TYPO3 Extension Repository (TER) accepted an upload it would have refused the day before: a zip archive with all components for an extension with a composer.json file at its root and no ext_emconf.php file anywhere. It looked like every other PHP package on the planet. That was the point.

How We Got Here

To understand why this took until 2026, we have to go back to 2003. TYPO3 v3.5 was the release that split one large system into a core and extensions. It introduced the Extension Manager to install those extensions, TER as a first open-source app store to share them, and a small PHP file called ext_emconf.php that told the Extension Manager what it was looking at. The file held the title, version, author, and compatible TYPO3 versions, plus a category field that nobody was ever quite sure about.

Because PHP 4 couldn't open zip files by default, TER got its own archive format. The .t3x file was a compressed, serialized PHP array containing every file of the extension, with a checksum in front. The Extension Manager downloaded it, unpacked it, and wrote a brand new ext_emconf.php file from the metadata in the stream. Whatever the author uploaded, the installed file was TER's cleaned-up reconstruction. In 2003, this was a clever solution, but it meant nobody could check a download against the file they had sent.

In 2006, TYPO3 v4.0 taught the Extension Manager to fetch one large list from a mirror instead of asking about each extension one by one. Since then, extensions.xml.gz has been the backbone of extension browsing, making it possible to host extensions outside the official TER. In 2012, TYPO3 v6.0 added support for plain zip archives alongside .t3x.

Then Composer arrived, matured through TYPO3 v7 and v8, and doubled the work for extension authors. Every public extension needed a composer.json for Composer-based projects and an ext_emconf.php for Classic Mode installations and TER uploads. For a decade, authors kept the two files in sync by hand, by script, or through continuous integration.

The Core Moved On

The Core moved first. In 2021, TYPO3 v11.4 stopped reading ext_emconf.php in Composer mode. TYPO3 v14 required every extension in Classic Mode to have a composer.json with an extension key, and read the title and description from it.

TYPO3 v14.2 also took the version, state, and constraints from composer.json, and deprecated ext_emconf.php. Recent TYPO3 v14.3 releases download the zip from TER instead of the .t3x and verify it with a SHA-256 checksum. TYPO3 v15 doesn't read ext_emconf.php at all, not even as a fallback.

That left TER as the only place that still required the file. The Core didn't need it, but TER rejected uploads without it, so authors had to maintain a manifest just to get past the upload form.

TER Now Reads composer.json

Since 14 September 2026, TER reads composer.json as the manifest of an uploaded extension. It uses the package name, description, authors, autoload section, and the require, conflict, and suggest sections.

TER translates Composer constraints such as ^13.4 into the version ranges the Extension Manager has understood for twenty years. It turns typo3/cms-core into the TYPO3 dependency and looks up third-party packages by the Composer names registered on TER.

If the archive also contains an ext_emconf.php, TER reads only what composer.json can't express: the category, the state, and the author company. Without ext_emconf.php, the category stays empty and the state defaults to "stable." Archives that contain only an ext_emconf.php, like thousands of existing extensions, work exactly as before.

TER Publishes the Archive You Upload

The same release fixes the oldest quirk of all. For every version that requires TYPO3 v14.3 or newer, TER now stores the archive the author uploaded, byte for byte, and publishes its SHA-256 hash. The hash you compute on your machine is the hash the Extension Manager verifies. Versions that support older TYPO3 releases keep the rebuilt zip with a generated ext_emconf.php. TYPO3 v13 in Classic Mode finds extensions by looking for that file, and no existing installation should break because of a cleanup.

Compatibility Does Not Disappear Overnight

TER still generates a .t3x for every version, so older Extension Managers work as they always have. Once the last Extension Managers that depend on it are updated, TER will stop generating .t3x files for extensions that require TYPO3 v14.3 or newer.

The latest release of tailor, the command-line tool for publishing extensions from a pipeline, validates composer.json the same way TER reads it. It no longer requires an ext_emconf.php.

What Extension Authors Need to Do

If you maintain an extension, make sure your composer.json:

  • Declares "type": "typo3-cms-extension"
  • Sets extra.typo3/cms.extension-key
  • Requires typo3/cms-core with the TYPO3 versions you support

If you care how TER and the Extension Manager display your extension's title, write the description as Title - Description. Name your archive <extension_key>_<version>.zip, and pack the contents of the extension directory, not the directory itself.

Keep ext_emconf.php only if you still support TYPO3 v13 or want to set a category and state. Until you delete it, keep its version in sync.

If TER rejects an upload, it now tells you why: the archive has no manifest, the manifest is in a subdirectory, the composer.json is invalid JSON or doesn't describe an extension, or the version doesn't match.

One File After Twenty-Three Years

Twenty-three years after ext_emconf.php first appeared, one file describes a TYPO3 extension: the same composer.json every other PHP package uses. It looks like a small change, but it took a great many people to get there.

PS: In case you wondered, ext_emconf.php stands for Extension Manager configuration because most files in an extension's root had the prefix ext_.