> ## Documentation Index
> Fetch the complete documentation index at: https://developer.upsun.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Composer 1 is dead – Upgrade to Composer 2 now

> Composer 1 has reached end of life and is no longer available on Upsun and Platform.sh. Learn why it’s no longer possible to rely on Composer 1, what errors you’ll see, and how to safely upgrade your project to Composer 2.


export const PostMeta = ({data = {}}) => {
  const {author, date, image} = data;
  const authors = Array.isArray(author) ? author : author ? [author] : [];
  const resolveAuthor = slug => {
    const entry = AUTHOR_MAP[slug] || ({});
    const name = entry.name || slug;
    const github = entry.github || null;
    const linkedin = entry.linkedin || null;
    const url = github ? `https://github.com/${github}` : linkedin || null;
    const avatarUrl = github ? `https://github.com/${github}.png?size=64` : null;
    return {
      name,
      url,
      avatarUrl
    };
  };
  const formattedDate = date ? new Date(date).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  }) : null;
  if (!image && authors.length === 0 && !formattedDate) return null;
  const AUTHOR_MAP = {
    "aaron-collier": {
      "name": "Aaron Collier"
    },
    "aaron-dudenhofer": {
      "name": "Aaron Dudenhofer"
    },
    "aaron-porter": {
      "name": "Aaron Porter"
    },
    "adriaan-odendaal": {
      "name": "Adriaan Odendaal"
    },
    "ajmal": {
      "name": "Ajmal Siddiqui"
    },
    "akalipetis": {
      "name": "Antonis Kalipetis"
    },
    "alexander-varwijk": {
      "name": "Alexander Varwijk"
    },
    "alicia-bevilacqua": {
      "name": "Alicia Bevilacqua"
    },
    "amelie-deguerry": {
      "name": "Amelie Deguerry"
    },
    "anacidre": {
      "name": "Ana Cidre",
      "linkedin": "https://www.linkedin.com/in/ana-cidre"
    },
    "andoni": {
      "name": "Andoni Auzmendi"
    },
    "andrei-taranu": {
      "name": "Andrei (Alex) Taranu",
      "linkedin": "https://www.linkedin.com/in/andrei-alex-taranu/"
    },
    "andrew-baxter": {
      "name": "Andrew Baxter"
    },
    "andrew-melck": {
      "name": "Andrew Melck"
    },
    "antoine-crochet-damais": {
      "name": "Antoine Crochet Damais"
    },
    "augustin-delaporte": {
      "name": "Augustin Delaporte",
      "linkedin": "https://www.linkedin.com/in/augustindelaporte/"
    },
    "branislav-bujisic": {
      "name": "Branislav Bujisic"
    },
    "carl-smith": {
      "name": "Carl Smith"
    },
    "caroline-leroy": {
      "name": "Caroline Leroy"
    },
    "cati-mayer": {
      "name": "Cati Mayer"
    },
    "catplat": {
      "name": "C Trinkwon"
    },
    "ceelolulu": {
      "name": "Celeste van der Watt"
    },
    "chadwcarlson": {
      "name": "Chad Carlson",
      "github": "chadwcarlson",
      "linkedin": "https://www.linkedin.com/in/chadwcarlson"
    },
    "chris-ward": {
      "name": "Chris Ward"
    },
    "chris-yates": {
      "name": "Chris Yates"
    },
    "christian-sieber": {
      "name": "Christian Sieber"
    },
    "christopher-lockheardt": {
      "name": "Christopher Lockheardt"
    },
    "christopher-skene": {
      "name": "Christopher Skene"
    },
    "chuck-morgan": {
      "name": "Chuck Morgan"
    },
    "corey-dockendorf": {
      "name": "Corey Dockendorf"
    },
    "crell": {
      "name": "Crell"
    },
    "damz": {
      "name": "Damz"
    },
    "dan-morrison": {
      "name": "Dan Morrison"
    },
    "davidbonachera": {
      "name": "David Bonachera",
      "github": "davidbonachera",
      "linkedin": "https://www.linkedin.com/in/davidbonachera"
    },
    "dereliahmet1": {
      "name": "Ahmet Faruk Dereli"
    },
    "devicezero": {
      "name": "Jonas Kröger",
      "github": "devicezero",
      "linkedin": "https://www.linkedin.com/in/jonaskroeger/"
    },
    "doug-goldberg": {
      "name": "Doug Goldberg"
    },
    "duncan-naves": {
      "name": "Duncan Naves",
      "github": "duncannaves",
      "linkedin": "https://www.linkedin.com/in/duncan-naves-a94423aa"
    },
    "erika-bustamante": {
      "name": "Erika Bustamante"
    },
    "fabpot": {
      "name": "Fabien Potencier"
    },
    "flovntp": {
      "name": "Florent Huck",
      "github": "flovntp",
      "linkedin": "https://www.linkedin.com/in/florenthuck"
    },
    "fred-plais": {
      "name": "Fred Plais"
    },
    "gauthier-garnier": {
      "name": "Gauthier Garnier"
    },
    "gilzow": {
      "name": "Paul Gilzow"
    },
    "gmoigneu": {
      "name": "Guillaume Moigneu",
      "github": "gmoigneu",
      "linkedin": "https://www.linkedin.com/in/guillaumemoigneu/"
    },
    "gregqualls": {
      "name": "Greg Qualls"
    },
    "guguss": {
      "name": "Augustin Delaporte"
    },
    "haylee-millar": {
      "name": "Haylee Millar"
    },
    "ivana-kotur": {
      "name": "Ivana Kotur"
    },
    "jackrabbithanna": {
      "name": "Mark Hanna"
    },
    "jared-wright": {
      "name": "Jared Wright",
      "github": "jww-sh",
      "linkedin": "https://www.linkedin.com/in/jaredwaynewright"
    },
    "jessica-orozco": {
      "name": "Jessica Orozco"
    },
    "joey-stanford": {
      "name": "Joey Stanford"
    },
    "john-grubb": {
      "name": "John Grubb"
    },
    "jonas-kruger": {
      "name": "Jonas Kruger"
    },
    "kathryn-frazer": {
      "name": "Kathryn Frazer"
    },
    "kemiojo": {
      "name": "Kemi Elizabeth Ojogbede"
    },
    "kieronsambrook-smith": {
      "name": "Kieronsambrook Smith"
    },
    "laurent-arnoud": {
      "name": "Laurent Arnoud"
    },
    "letoya-boyne": {
      "name": "Letoya Boyne"
    },
    "lolautruche": {
      "name": "Jérôme Vieilledent"
    },
    "lyly-lepinay": {
      "name": "Lyly Lepinay"
    },
    "manauwar-alam": {
      "name": "Manauwar Alam"
    },
    "marc-antoine-porri": {
      "name": "Marc Antoine Porri"
    },
    "maria-antinkaapo": {
      "name": "Maria Antinkaapo"
    },
    "maria-de-anton": {
      "name": "Maria De Anton"
    },
    "mark-dorison": {
      "name": "Mark Dorison"
    },
    "markus-hausammann": {
      "name": "Markus Hausammann"
    },
    "mary-thomas": {
      "name": "Mary Thomas"
    },
    "mathias-bolt-lesniak": {
      "name": "Mathias Bolt Lesniak"
    },
    "mathieu-strauch": {
      "name": "Mathieu Strauch"
    },
    "matthias-van-woensel": {
      "name": "Matthias Van Woensel",
      "linkedin": "https://www.linkedin.com/in/matthias-van-woensel-267a069"
    },
    "michael-sharp": {
      "name": "Michael Sharp"
    },
    "mupsi": {
      "name": "Marine Gandy"
    },
    "natalie-harper": {
      "name": "Natalie Harper"
    },
    "ngommenginger": {
      "name": "Nicolas Gommenginger",
      "linkedin": "https://www.linkedin.com/in/nicolas-gommenginger"
    },
    "nicholas-bennison": {
      "name": "Nicholas Bennison"
    },
    "nicholas-vahalik": {
      "name": "Nicholas Vahalik"
    },
    "nick-hardiman": {
      "name": "Nick Hardiman"
    },
    "nickanderegg": {
      "name": "Nickanderegg"
    },
    "nicolas-grekas": {
      "name": "Nicolas Grekas",
      "github": "nicolas-grekas",
      "linkedin": "https://www.linkedin.com/in/nicolasgrekas/"
    },
    "niti-malwade": {
      "name": "Niti Malwade"
    },
    "opensocialteam": {
      "name": "Opensocialteam"
    },
    "ori-pekelman": {
      "name": "Ori Pekelman"
    },
    "otavio-santana": {
      "name": "Otavio Santana"
    },
    "palwandi": {
      "name": "Pawan Alwandi",
      "github": "pawpy",
      "linkedin": "https://www.linkedin.com/in/pawanalwandi"
    },
    "patrick-boest": {
      "name": "Patrick Boest"
    },
    "patrick-dawkins": {
      "name": "Patrick Dawkins",
      "github": "pjcdawkins",
      "linkedin": "https://www.linkedin.com/in/patrickdawkins"
    },
    "patrick-klima": {
      "name": "Patrick Klima"
    },
    "pjcdawkins": {
      "name": "Pjcdawkins"
    },
    "prineet-kaurbhurji": {
      "name": "Prineet Kaurbhurji"
    },
    "quentin-sinig": {
      "name": "Quentin Sinig"
    },
    "ralt": {
      "name": "Florian Margaine",
      "github": "ralt",
      "linkedin": "https://www.linkedin.com/in/florian-margaine-43971136"
    },
    "ramanathanramakrishnamurthy": {
      "name": "Ramanathanramakrishnamurthy"
    },
    "remi-lejeune": {
      "name": "Rémi Lejeune"
    },
    "ribel": {
      "name": "Taras Kruts"
    },
    "robert-douglass": {
      "name": "Robert Douglass"
    },
    "rudy-weber": {
      "name": "Rudy Weber"
    },
    "ryan-hicks": {
      "name": "Ryan Hicks"
    },
    "sabri-helal": {
      "name": "Sabri Helal"
    },
    "savannah-bergeron": {
      "name": "Savannah Bergeron"
    },
    "shannon-vettes": {
      "name": "Shannon Vettes"
    },
    "shawn-ogasawara": {
      "name": "Shawn Ogasawara",
      "linkedin": "https://www.linkedin.com/in/shawn-ogasawara-83a9a0/"
    },
    "shawna-spoor": {
      "name": "Shawna Spoor"
    },
    "shedrack-akintayo": {
      "name": "Shedrack Akintayo"
    },
    "simon-ruggier": {
      "name": "Simon Ruggier"
    },
    "sophie-van-der-kindere": {
      "name": "Sophie Van Der Kindere"
    },
    "stefanos-thampis": {
      "name": "Stefanos Thampis"
    },
    "stephen-weinberg": {
      "name": "Stephen Weinberg"
    },
    "sukhman-virk": {
      "name": "Sukhman Virk"
    },
    "sumaira-nazir": {
      "name": "Sumaira Nazir"
    },
    "sumer": {
      "name": "Sümer Cip"
    },
    "syed-raza": {
      "name": "Syed Raza"
    },
    "tamara-bacchia": {
      "name": "Tamara Bacchia"
    },
    "tara-arnold": {
      "name": "Tara Arnold"
    },
    "theosakamg": {
      "name": "Mickael Gaillard",
      "github": "theosakamg"
    },
    "thomasdiluccio": {
      "name": "Thomas di Luccio"
    },
    "tim-anderson": {
      "name": "Tim Anderson"
    },
    "tom-helmer-hansen": {
      "name": "Tom Helmer Hansen"
    },
    "tylermills": {
      "name": "Tyler Mills"
    },
    "upsun": {
      "name": "Upsun"
    },
    "veronika-tolkachova": {
      "name": "Veronika Tolkachova",
      "linkedin": "https://www.linkedin.com/in/veronika-tolkachova-169167a2"
    },
    "vince-parker": {
      "name": "Vince Parker"
    },
    "vinnie-russo": {
      "name": "Vincenzo Russo"
    },
    "vrobert78": {
      "name": "Vincent Robert",
      "github": "vrobert78",
      "linkedin": "https://www.linkedin.com/in/vincent-robert-498a883"
    },
    "yuriy-babenko": {
      "name": "Yuriy Babenko"
    },
    "yuriy-gerasimov": {
      "name": "Yuriy Gerasimov"
    }
  };
  return <div className="post-meta">
      {(authors.length > 0 || formattedDate) && <div className="post-meta-info">
          {authors.length > 0 && <div className="post-meta-authors">
              {authors.map(slug => {
    const {name, url, avatarUrl} = resolveAuthor(slug);
    const inner = <>
                    {avatarUrl && <img src={avatarUrl} alt={name} className="post-meta-avatar" />}
                    <span className="post-meta-author-name">{name}</span>
                  </>;
    return url ? <a key={slug} href={url} target="_blank" rel="noopener noreferrer" className="post-meta-author">
                    {inner}
                  </a> : <span key={slug} className="post-meta-author">{inner}</span>;
  })}
            </div>}
          {authors.length > 0 && formattedDate && <span className="post-meta-separator" aria-hidden="true">·</span>}
          {formattedDate && <span className="post-meta-date">{formattedDate}</span>}
        </div>}
      {image && <img src={image} alt="" className="post-meta-image" aria-hidden="true" />}
    </div>;
};

<PostMeta data={{ author: ["flovntp"], date: "2025-09-09T10:00:00+00:00", image: "/images/posts/how-tos/composer1-rip/composer-migrate-v1-v2.webp" }} />

[Composer](https://getcomposer.org/) has long been the de-facto dependency manager for PHP projects.
It powers millions of applications, frameworks, and libraries by providing a reliable way to manage dependencies.

However, **Composer 1 reached its end of life** and [is
no longer maintained](https://blog.packagist.com/shutting-down-packagist-org-support-for-composer-1-x/).
If your project or CI pipeline is still using Composer 1, it’s time to upgrade.

## What happens if your project still requires Composer 1?

If your `composer.json` specifies a constraint like `^1` for the Composer runtime, your build
on [Upsun](https://www.upsun.com) or [Platform.sh](https://platform.sh) will fail.\
Here’s the kind of error you’ll see:

```bash {filename="Logs"} theme={null}
      Building application 'app' (runtime type: php:8.3, tree: 7760752)
        Generating runtime configuration.

        Installing build dependencies...
          Installing php build dependencies: composer
          W: Changed current directory to /app/.global/composer
          W: No composer.lock file present. Updating dependencies to latest instead of installing from lock file. See https://getcomposer.org/install for more information.
          W: Loading composer repositories with package information
          W: Updating dependencies
          W: Your requirements could not be resolved to an installable set of packages.
          W:
          W:   Problem 1
          W:     - Root composer.json requires composer ^1, found composer[2.8.11] but it does not match the constraint.
```

## How to check your Composer version

To check your current Composer version, execute the following:

```bash {filename="Terminal"} theme={null}
composer --version
```

If you see `Composer version 1.x.x`, you are running the deprecated version.

## How to upgrade your project to Composer 2

Upgrading is straightforward:

### 1. Update globally (recommended)

If Composer is installed globally on your system:

```bash {filename="Terminal"} theme={null}
composer self-update --2
```

This will switch you directly to the latest stable Composer 2 release.

### 2. Install via Package Manager

For example, on macOS with Homebrew:

```bash {filename="Terminal"} theme={null}
brew update
brew upgrade composer
```

### 3. Use the official installer

If you installed Composer manually:

```bash {filename="Terminal"} theme={null}
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php --2
php -r "unlink('composer-setup.php');"
```

This will download Composer 2 locally into your project. You can move it globally if needed:

```bash {filename="Terminal"} theme={null}
mv composer.phar /usr/local/bin/composer
```

## Actions to take in your project

<Tabs>
  <Tab title="using Upsun">
    1. Update your `composer.json`

       Update the required PHP version and add a runtime API requirement to enforce Composer 2:

       ```json {filename="composer.json"} theme={null}
       {
           "require": {
             "php": ">=8.2",
             "composer-runtime-api": "^2"
           }
       }
       ```

           <Note>
             **Your current PHP version is maybe outdated?**<br />
             Composer 2 requires **at least PHP 7.2.5**, but many modern packages no longer support versions below **PHP 8.1**.
             To ensure long-term compatibility, security, and access to the latest ecosystem improvements, we strongly recommend upgrading to **PHP 8.2 or higher**.
           </Note>

    2. Check your `.upsun/config.yaml`
       Ensure you declare Composer 2 in your `.upsun/config.yaml` configuration, or, as Composer version 2 is now the
       default version installed on every project, completely remove the Composer dependency:
       ```yaml {filename=".upsun/config.yaml"} theme={null}
       applications:
         app:
           dependencies:
             php:
               composer: "^2" # or remove this dependency as Composer v2 is the default
       ```

    3. Test dependency resolution
       Run `composer update` with Composer 2 and commit the updated `composer.lock`. In rare cases, some legacy
       packages may need adjustments:
       ```bash {filename="Terminal"} theme={null}
       composer update
       git add .upsun/config.yaml composer.lock
       git commit "Update Composer to version 2"
       upsun push
       ```

    4. **Update your CI/CD pipelines**\
       Check your Docker images, GitHub Actions, or other CI jobs. Many older PHP images still ship with Composer 1 by
       default.
       * For Docker, use the `composer:2` official image.
       * For GitHub Actions, specify a step to upgrade Composer.

    5. **Communicate the change**\
       Update your project’s documentation to state that Composer 2 is required.
  </Tab>

  <Tab title="using Platform.sh">
    1. Update your `composer.json`

       Update the required PHP version and add a runtime API requirement to enforce Composer 2:

       ```json {filename="composer.json"} theme={null}
       {
           "require": {
             "php": ">=8.2",
             "composer-runtime-api": "^2"
           }
       }
       ```

           <Note>
             **Your current PHP version is maybe outdated?**<br />
             Composer 2 requires **at least PHP 7.2.5**, but many modern packages no longer support versions below **PHP 8.1**.
             To ensure long-term compatibility, security, and access to the latest ecosystem improvements, we strongly recommend upgrading to **PHP 8.2 or higher**.
           </Note>

    2. Check your `.platform.app.yaml`
       Ensure you declare Composer 2 in your `.platform.app.yaml` (or `.platform/applications.yaml`) configuration, or, as
       Composer version 2 is now the
       default version installed on every project, completely remove the Composer dependency:
       ```yaml {filename=".platform.app.yaml"} theme={null}
       name: app
       dependencies:
         php:
           composer: "^2" # or remove this dependency as Composer v2 is the default
       ```

    3. Test dependency resolution
       Run `composer update` with Composer 2 and commit the updated `composer.lock`. In rare cases, some legacy
       packages may need adjustments:
       ```bash {filename="Terminal"} theme={null}
       composer update
       git add .platform.app.yaml .platform/applications.yaml composer.lock 
       git commit "Update Composer to version 2"
       platform push
       ```

    4. **Update your CI/CD pipelines**\
       Check your Docker images, GitHub Actions, or other CI jobs. Many older PHP images still ship with Composer 1 by
       default.
       * For Docker, use the `composer:2` official image.
       * For GitHub Actions, specify a step to upgrade Composer.

    5. **Communicate the change**\
       Update your project’s documentation to state that Composer 2 is required.
  </Tab>
</Tabs>

## Troubleshooting common migration issues

Upgrading from Composer 1 to 2 is usually seamless, but you may encounter issues:

* **API Rate Limits (GitHub, GitLab, etc.)**\
  Composer 2 uses parallel downloads which can trigger API rate limits. Solution: configure OAuth tokens for GitHub or
  GitLab in your `auth.json`.

* **Plugins Not Compatible**\
  Some Composer plugins written for v1 may not work on v2. Ensure you update plugins to their latest version, or replace
  them if no update is available.

* **Stricter Dependency Checks**\
  Composer 2 is stricter about dependency resolution. If you encounter errors, check your `composer.json` for
  constraints that need adjusting.

* **CI/CD Caching Issues**\
  Clear your Composer cache in CI/CD environments (`composer clear-cache`) if builds fail after upgrading.

## Conclusion

Composer 1 is officially unsupported.
By upgrading to Composer 2, you get:

* Faster dependency resolution
* Modern PHP compatibility
* A safer, future-proof environment

Don’t wait until a dependency breaks or your pipeline fails—**upgrade today**.
