---
title: "composer.json"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:files-composer-json@main"
source: "ExtensionArchitecture/FileStructure/ComposerJson.rst"
modified: "2026-09-14T11:10:56+00:00"
---

# `composer.json`

> [!IMPORTANT]
> > [!NOTE]
> > **Changed in version 14.0**
> >
> > With TYPO3 14.0 a valid composer.json is required for all TYPO3 extensions,
> > including those only used in Classic mode installations.

Required in **all** installations

-   **composer.json**

    -   *Scope:* extension
    -   *Path (Composer):* packages/my_extension/composer.json
    -   *Path (Classic):* typo3conf/ext/my_extension/composer.json

-   [Introduction](https://docs.typo3.org/permalink/t3coreapi:introduction@main)
-   [About the composer.json file](https://docs.typo3.org/permalink/t3coreapi:about-the-composer-json-file@main)
-   [Properties](https://docs.typo3.org/permalink/t3coreapi:properties@main)
-   [Properties no longer used](https://docs.typo3.org/permalink/t3coreapi:properties-no-longer-used@main)
-   [More information](https://docs.typo3.org/permalink/t3coreapi:more-information@main)

## Introduction

[Composer](https://getcomposer.org/) is a tool for dependency management in
PHP. It allows you to declare the libraries your extension depends on and it
will manage (install/update) them for you.

[Packagist](https://packagist.org/) is the main Composer repository. It
aggregates public PHP packages installable with Composer. Composer packages
can be published by the package maintainers on Packagist to be installable in an
easy way via the `composer require` command.

> [!WARNING]
> **Attention**
>
> When a Composer package with the type `typo3-cms-extension` is published on
> Packagist, it may be made available in the
> [TYPO3 Extension Repository](https://extensions.typo3.org/)
> automatically. See
> [TYPO3 TER Packagist Integration](https://extensions.typo3.org/about-extension-repository/ter-packagist-integration)
> for more information.

## About the composer.json file

Including a [`composer.json`](#file-extension-composer-json) is **required**.

1.  Without a valid [`composer.json`](#file-extension-composer-json) an extension
    is not installable in TYPO3, even in Classic mode installations not using
    Composer. To update your [`composer.json`](#file-extension-composer-json) file
    for Classic mode compatible extensions see
    [Classic mode compatible composer.json](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-classic-compatible@main) below.
1.  Working with Composer in general is strongly recommended for TYPO3.

    If you are not using Composer for your projects yet, see
    [Migrate a TYPO3 project to Composer](https://docs.typo3.org/permalink/t3coreapi:migratetocomposer@main) in the "Upgrade Guide".

### Minimal composer.json

This is a minimal [`composer.json`](#file-extension-composer-json) for a TYPO3 extension:

-   The vendor name is `MyVendor`.
-   The [extension key](https://docs.typo3.org/permalink/t3coreapi:extension-key@main) is `my_extension`.
-   The extension title is `My Extension` and the description is `An example extension`.

Subsequently:

-   The PHP namespace will be `\MyVendor\MyExtension`
-   The Composer package name will be `my-vendor/my-extension`

**EXT:my_extension/composer.json**

```json
{
    "name": "my-vendor/my-extension",
    "type": "typo3-cms-extension",
    "description": "My Extension - An example extension",
    "license": "GPL-2.0-or-later",
    "require": {
        "typo3/cms-core": "^13.4 || ^14.3"
    },
    "autoload": {
        "psr-4": {
            "MyVendor\\MyExtension\\": "Classes/"
        }
    },
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension"
        }
    }
}

```

-   see [composer.json schema](https://getcomposer.org/doc/04-schema.md) for
    general Composer information
-   see [Properties](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-properties@main) below for TYPO3 specific hints

> [!NOTE]
> **Changed in version 14.2**

The order of installed extensions and their dependencies is specified in
the [`composer.json`](#file-extension-composer-json) file.

> [!NOTE]
> Extension authors should ensure that the information in the
> [`composer.json`](#file-extension-composer-json) file is in sync with the one in the extension's
> [ext_emconf.php](https://docs.typo3.org/permalink/t3coreapi:ext-emconf-php@main) file. This is especially important
> regarding constraints like `depends`, `conflicts` and
> `suggests`. Use the equivalent settings in [`composer.json`](#file-extension-composer-json)
> `require`, `conflict` and `suggest` to set dependencies and ensure a
> specific loading order.

### Extended composer.json

> [!NOTE]
> **See also**
>
> Please see [Extension testing](https://docs.typo3.org/permalink/t3coreapi:testing-extensions@main) for
> further changes to [`composer.json`](#file-extension-composer-json) for testing extensions.

**EXT:my_extension/composer.json**

```json
{
    "name": "my-vendor/my-extension",
    "type": "typo3-cms-extension",
    "description": "My Extension - An example extension",
    "license": "GPL-2.0-or-later",
    "require": {
        "php": "^8.2",
        "typo3/cms-backend": "^13.4 || ^14.3",
        "typo3/cms-core": "^13.4 || ^14.3"
    },
    "require-dev": {
        "typo3/coding-standards": "^0.7.1"
    },
    "authors": [
        {
            "name": "John Doe",
            "role": "Developer",
            "email": "john.doe@example.org",
            "homepage": "https://johndoe.example.org/"
        }
    ],
    "keywords": [
        "typo3",
        "blog"
    ],
    "support": {
        "issues": "https://example.org/my-issues-tracker"
    },
    "funding": [
        {
            "type": "other",
            "url:": "https://example.org/funding/my-vendor"
        }
    ],
    "autoload": {
        "psr-4": {
            "MyVendor\\MyExtension\\": "Classes/"
        }
    },
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension"
        }
    }
}

```

-   See [composer.json schema](https://getcomposer.org/doc/04-schema.md) for
    general Composer information.
-   See [Properties](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-properties@main) below for TYPO3-specific hints.

### Classic mode compatible composer.json

> [!NOTE]
> **Changed in version 14.2**

Extension authors should add [extra.typo3/cms.version](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-property-extra-version@main)  and
[providesPackages](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-property-provides-packages@main)
definitions to [`composer.json`](#file-extension-composer-json) if their extensions
need to  remain compatible with TYPO3 Classic mode.
`providesPackages` must exist even if it is empty.

In Classic mode, TYPO3 distinguishes between dependencies on other TYPO3 extensions
(`require`, `conflicts` and `suggests`) and on
plain Composer packages from Packagist (`providesPackages`). The Extension
Manager uses `version` for compatibility checks and the PackageManager resolves
the extension loading order.

Here the Classic mode compatible extension has a dependency on Composer package `symfony/dotenv`:

**EXT:my_extension/composer.json**

```json
{
    "name": "my-vendor/my-extension",
    "type": "typo3-cms-extension",
    "description": "My Extension - An example extension",
    "license": "GPL-2.0-or-later",
    "require": {
        "typo3/cms-core": "^14.2",
        "vendor/other-example": "*",
        "symfony/dotenv": "^8.0"
    },
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension",
            "version": "1.0.0",
            "Package": {
                "providesPackages": {
                    "symfony/dotenv": ""
                }
            }
        }
    }
}

```

Here the Classic mode compatible extension does not depend on any Composer packages:

**EXT:my_extension/composer.json**

```json
{
    "name": "my-vendor/my-extension",
    "type": "typo3-cms-extension",
    "description": "My Extension - An example extension",
    "license": "GPL-2.0-or-later",
    "require": {
        "typo3/cms-core": "^14.2"
    },
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension",
            "version": "1.0.0",
            "Package": {
                "providesPackages": {}
            }
        }
    }
}

```

> [!IMPORTANT]
> The `version` key in `composer.json` **must** match the Git tag.

## Properties

### name

(*required*)

The name has the format: `<my-vendor>/<dashed extension key>`. "Dashed extension
key" means that every underscore (`_`) has been changed to a dash (`-`).
You must be owner of the vendor name and should register it on
[Packagist](https://packagist.org/). Typically, the name will correspond to
your namespaces used in the `Classes/` folder, but with different
uppercase / lowercase spelling, for example: The PHP namespace
`\JohnDoe\SomeExtension` may be `johndoe/some-extension` in
[`composer.json`](#file-extension-composer-json).

### description

> [!NOTE]
> **Changed in version 14.0**
>
> Extension titles were previously taken from file `ext_emconf.php` but
> in Composer mode the `ext_emconf.php` file is no longer necessary. The
> description field in `composer.json` is exploded to get the extension
> title (in front of "-") and the extension description (after "-").

(*required*)

This field contains the extension title and the description of your extension
(1 line). The title is separated from the description by a dash "-". If there is no
dash, the title will be the entire description.

### type

(*required*)

Use `typo3-cms-extension` for third-party extensions.
The `Resources/Public/` folder will be symlinked into the
[\_assets/](https://docs.typo3.org/permalink/t3coreapi:directory-public-assets@main) folder of your web root.

Additionally, `typo3-cms-framework` is available for system extensions.

See [typo3/cms-composer-installers](https://github.com/TYPO3/CmsComposerInstallers)
(required by `typo3/cms-core`).

### license

(*recommended*)

Has to be `GPL-2.0-only` or `GPL-2.0-or-later`.
See: [https://typo3.com/typo3-cms/what-is-typo3/open-source/licenses](https://typo3.com/typo3-cms/what-is-typo3/open-source/licenses).

### require

(*required*)

At least, you will need to require `typo3/cms-core` in the according version(s).
You should add other system extensions and third-party extensions, if your
extension depends on them.

In Composer-based installations the loading order of extensions and their
dependencies is derived from `require` and `suggest`.

### suggest

You should add other system extensions and third-party extensions, if your
extension has an optional dependency on them.

In Composer-based installations the loading order of extensions and their
dependencies is derived from `require` and `suggest`.

### autoload

(*required*)

The autoload section defines the namespace/path mapping for
[PSR-4 autoloading](https://www.php-fig.org/psr/psr-4/). In TYPO3 we follow
the convention that all classes (except test classes) are in the directory
`Classes/`.

### extra.typo3/cms.extension-key

(*required*)

Not providing this property results in the extension not being installable
properly.

> [!TIP]
> **Hint**
>
> The property `extension-key` means the **literal string** `extension-key`,
> not your actual extension key. The value on the right side should be your
> actual extension key.

Example for extension key `my_extension`:

**Excerpt of EXT:my_extension/composer.json**

```json
{
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension",
            "version": "1.2.3-alpha4",
            "Package": {
                "providesPackages": {}
            }
        }
    }
}

```

### extra.typo3/cms.version

(using either `version` or [extra.typo3/cms.version](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-property-extra-version@main)
is *required* for Classic mode installations)

> [!NOTE]
> **New in version 14.2**
>
> The version number for extensions installed in Classic mode can be set in
> `extra.typo3/cms.version` or alternatively in the `"version"` field in :
> file:`composer.json`. The former `state` property in `ext_emconf.php`
> is now represented by dedicated metadata instead
> of a dedicated field.

**Excerpt of EXT:my_extension/composer.json**

```json
{
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension",
            "version": "1.2.3-alpha4",
            "Package": {
                "providesPackages": {}
            }
        }
    }
}

```

The version must match the tagged release version. Extension Manager (Classic mode)
uses the version for compatibility checks.

see [Classic mode compatible composer.json](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-classic-compatible@main) above.

Supported extension stability values are expressed as version suffixes, for
example: `"version": "1.2.3-alpha4"`.

Supported Composer stability values are:

-   `dev`
-   `alpha`
-   `beta`
-   `RC`
-   `stable`

For example:

-   `1.2.3-dev`
-   `1.2.3-alpha1`
-   `1.2.3-beta2`
-   `1.2.3-RC3`
-   `1.2.3`

Values from the former `state` field that are not supported by Composer stability
can be expressed as build metadata by appending `+...` to the version string.
For example: `"version": "1.4.2+obsolete"`.

### `extra.typo3/cms.Package.providesPackages`

> [!NOTE]
> **New in version 14.2**

(*required* for Classic mode installations)

Even if an extension does not depend on any third party Composer packages,
it is still **required** to specify `providesPackages` in `composer.json`
as an empty object to ensure future compatibility with TYPO3 Classic mode
and to avoid deprecation messages in TYPO3 v14:

**Excerpt of EXT:my_extension/composer.json**

```json
{
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension",
            "version": "1.2.3-alpha4",
            "Package": {
                "providesPackages": {}
            }
        }
    }
}

```

Extensions still need to declare Composer packages that they themselves provide
when loaded in classic mode. For those entries, `providesPackages` can also
define a relative path to a Composer vendor directory. If that directory contains
a Composer-generated `autoload.php`, TYPO3 includes it early during bootstrap.

This makes it possible to both declare Composer packages and bootstrap
their autoloader in a standardized way.

Here is an example of an extension that ships a local Composer vendor directory:

**Excerpt of EXT:my_extension/composer.json**

```json
{
    "extra": {
        "typo3/cms": {
            "extension-key": "my_extension",
            "version": "1.2.3",
            "Package": {
                "providesPackages": {
                    "symfony/dotenv": "Resources/Private/Php/ComposerVendor"
                }
            }
        }
    }
}

```

In this example, the package `symfony/dotenv` is provided by the extension itself
in TYPO3 classic mode, and TYPO3 will include
`Resources/Private/Php/ComposerVendor/autoload.php` early if it is a
Composer-generated autoload file.

see [Classic mode compatible composer.json](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-classic-compatible@main) above

### version

(using either `version` or [extra.typo3/cms.version](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-property-extra-version@main)
is *required* for Classic mode installations)

The version must match the tagged release version. Extension Manager (Classic mode)
uses the version property for compatibility checks.

Note that using the top level `version` field for a TYPO3 extension version
in classic mode has the disadvantage that Composer pulls in
this version also for branches (for example dev versions).
Extension authors would then need
to update this field constantly for branches and/ or releases,
which would have a bigger impact on behaviour in Composer-managed
TYPO3 systems and extension authors than initially intended.

To prevent this behavior declare the version number in the extra section
(see [extra.typo3/cms.version](https://docs.typo3.org/permalink/t3coreapi:ext-composer-json-property-extra-version@main) below).

## Properties no longer used

### replace with `typo3-ter` vendor name

**Excerpt of EXT:my_extension/composer.json**

```json
{
    "replace": {
        "typo3-ter/my-extension": "self.version"
    }
}

```

This was used previously as long as the TER Composer Repository was
relevant. Since the TER Composer Repository is deprecated, the `typo3-ter/*` entry
within `replace` is not required.

### replace with `"ext_key": "self.version"`

**Excerpt of EXT:my_extension/composer.json**

```json
{
    "replace": {
        "ext_key": "self.version"
    }
}

```

This was used previously, but is not compatible with latest Composer
versions and will result in a warning using `composer validate` or
result in an error with Composer version 2.0+:

```text
Deprecation warning: replace.ext_key is invalid, it should have a vendor name, a forward slash, and a package name.
The vendor and package name can be words separated by -, . or _. The complete name should match
"^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$".
Make sure you fix this as Composer 2.0 will error.
```

See
[comment on helhum/composer.json](https://gist.github.com/helhum/0ffd82525c90f305b81a8285329eb4f8#gistcomment-3239391)
and [revisions on helhum/composer.json](https://gist.github.com/helhum/0ffd82525c90f305b81a8285329eb4f8/revisions).

## More information

Not TYPO3-specific:

-   [About Packagist](https://packagist.org/about)
-   [composer.json schema](https://getcomposer.org/doc/04-schema.md)
-   [Composer Getting Started](https://getcomposer.org/doc/00-intro.md)

TYPO3-specific:

-   The [section on testing](https://docs.typo3.org/permalink/t3coreapi:testing-extensions@main) (in this manual) contains
    further information about adding additional properties to
    [`composer.json`](#file-extension-composer-json) that are relevant for testing.
-   The Composer plugin (not extension)
    [typo3/cms-composer-installers](https://packagist.org/packages/typo3/cms-composer-installers)
    is responsible for TYPO3-specific Composer installation. Reading the README
    file and source code can be helpful to understand how it works.
