Public Beta

PHP dependencies,
at Rust speed. Phast is a dependency manager for PHP, written in Rust.

Phast resolves, downloads, and links your whole project in a fraction of the time, then gets out of your way. Your registries, your vendor/, an autoloader optimized by default.

curl -fsSL https://raw.githubusercontent.com/phast-sh/phast/main/install.sh | sh
~/laravel-app
❯ phast install -v
Resolved 119 packages in 0.31s
Locked 119 packages in 0.12s
Installed 119 packages in 1.70s
Autoloaded 119 packages in 0.13s
Finished in 2.26s (119 packages)

❯
2.26s
full cold install
119
packages resolved
0.63s
warm re-install
Installs from Packagist Private Packagist Satis Any Composer registry Git repositories Local paths

The manifest

Your whole project, in one file you can read.

/** * You write phast.toml. phast lock derives phast.lock from it, * pinning every package to an exact version, the repository it came * from and the commit it was taken at. */

phast.toml

#:schema https://phast.sh/schema/v1/manifest.json

[package]
name        = "acme/my-app"
description = "My application"
type        = "project"
license     = "MIT"

[require]
php                 = "^8.2"
"laravel/framework" = "^11.0"
"psr/log"           = "^3.0"

[require-dev]
"phpunit/phpunit" = "^11.0"

[autoload.psr-4]
"App\\" = ["src/"]

[scripts]
test = "@php vendor/bin/phpunit"

❯ phast lock

phast.lock

version = 1

[metadata]
generated-by = "phast 0.1.0"
generated-at = "2026-08-22T09:14:03.118762+00:00"

[[packages]]
name        = "psr/log"
version     = "3.0.0"
type        = "library"
description = "Common interface for logging libraries"
license     = ["MIT"]
time        = "2021-07-14T16:46:02+00:00"

[packages.source]
type      = "git"
url       = "https://github.com/php-fig/log.git"
reference = "fe5ea303b0887d5caefd3d431c3e61ad47037001"

[packages.autoload.psr-4]
'Psr\Log\' = ["src"]

That first line on the left is not decoration. Point your editor at the schema and you get completion and validation for every key, and phast validate checks the same rules in CI.

Why Phast

Dependency management, done right.

/** * What changes on the first day: the wait, the file you edit, the * number of tools in the chain, and how much of it you have to * explain to whoever clones the repository next. */

Speed

Ruthlessly fast

Whole projects installed in seconds, however cold the cache.

Compatibility

Fits your stack

Packagist, Private Packagist & Satis, with a standard vendor/autoload.php.

Onboarding

Effortless onboarding

Import an existing project in one step, then phast install.

Monorepos

First-class monorepos

Workspaces, one lock file, one vendor/, no path-repo wiring.

Security

Secure by default

phast audit plus a minimum package age against supply-chain attacks.

Reproducible

Reproducible installs

A deterministic lock file gives every machine byte-for-byte the same tree.

Explore the docs →

Benchmarks

It isn't a little faster. It is faster every single time.

/** * koel, a real music streaming app: 202 packages, one of them * installed straight from a git repository. Median of five runs on * one machine against Composer 2.8 on PHP 8.4, scripts disabled, * caches isolated, over a fast connection. */

no lock, no cache · lower is better

Phast7.00s
Composer67.32s

9.6× faster

Diagnostics

When it can't resolve, it tells you exactly why not.

/** * A solver that records why every candidate was rejected can explain * itself. A conflict comes back in terms of your project: which * requirement, whose requirement, and the two ranges that cannot * overlap. */

~/new-project
❯ phast add symfony/polyfill-mbstring:^99.0

Phast could not find compatible versions for your requirements
 ╰─▶ symfony/polyfill-mbstring has incompatible constraints:
       · your project requires
         symfony/polyfill-mbstring[>=99.0, <100.0]
       · symfony/http-foundation[>=7.0, <8.0] requires
         symfony/polyfill-mbstring[>=1.1, <2.0]

phast.toml not found. Run phast init first.

'psr/log' is already in require. Remove it first with phast remove psr/log.

invalid package name 'psr log'. Expected vendor/package (e.g. psr/log), php, or ext-*.

--member requires a workspace. Add a [workspace] section to phast.toml first.

The same care goes into the ordinary ones. Every message names what went wrong and the command that fixes it.

Workspaces

Monorepos are native citizens here, not guests.

/** * Several packages in one repository, resolved together, sharing one * phast.lock and one vendor/. No path repositories, no merge * plugin, nothing to wire up per member. */

my-project/

phast.toml   # the workspace root
phast.lock   # one lock for everything
vendor/      # one directory, shared
packages/
├── http-client/
│   └── phast.toml
└── api-sdk/
    └── phast.toml
tools/
└── codegen/
    └── phast.toml
        

phast.toml

[workspace]
members = ["packages/*", "tools/codegen"]
exclude = ["packages/legacy"]

[workspace.dependencies]
"symfony/http-foundation" = "^7.0"
"phpunit/phpunit"         = "^11.0"

# and in packages/api-sdk/phast.toml
[require]
"my-org/http-client"      = "^1.0"   # sibling
"symfony/http-foundation" = { workspace = true }

One lock, one vendor/

Every member resolves against the same graph, so two packages in your repository can never disagree about a shared dependency.

The root coordinates

A workspace root declares no dependencies of its own. Shared versions live in [workspace.dependencies], and each member opts in.

Siblings are never copied

Member code stays where it is. The generated autoloader points straight at each member's sources, so an edit is visible with no reinstall.

CLI tooling

A command line you will actually enjoy.

/** * Fast feedback, readable output, and the commands you reach for * every day, right in your terminal. */

❯ phast install

Install in a blink

Resolve, download, and link an entire project in a couple of seconds, no warm cache required.

❯ phast migrate

Bring your project along

Import an existing composer.json in a single step and keep shipping. Nothing else to rewire.

❯ phast audit

Know you are safe

Scan every locked package against advisories, with a minimum-age guard against fresh supply-chain attacks.

❯ phast why

Understand your tree

Trace exactly why a package is in your project, and which dependencies pull it in.

~/laravel-app
❯ phast install -v
Resolved 119 packages in 0.31s
Locked 119 packages in 0.12s
Installed 119 packages in 1.70s
Autoloaded 119 packages in 0.13s
Finished in 2.26s (119 packages)
~/legacy-monolith
❯ phast migrate
composer.json migrated to phast.toml.
Run 'phast install' to install dependencies.

❯ phast install
Finished in 3.19s (248 packages)
~/auth-service
❯ phast audit
Phast found 2 security advisories in your locked dependencies.

  facade/ignition 2.5.1
    CVE-2021-3129   [CRITICAL]  Unauthenticated remote code execution
                                affected  <2.5.2
  guzzlehttp/psr7 2.4.4
    CVE-2023-29197  [MEDIUM]    Improper header parsing
                                affected  >=2.0.0,<2.4.5

Run `phast update` to attempt resolution.
~/trace-tool
❯ phast why psr/log --tree
psr/log 3.0.0
├── monolog/monolog 3.5.0
│   └── required by root
├── laravel/framework 11.0.3
│   └── required by root
└── symfony/http-kernel 7.2.3
    └── laravel/framework 11.0.3
        └── required by root

FAQ

The questions people ask before they try it.

Is Phast compatible with Composer?

Yes. Phast reads your composer.json, resolves what Composer resolves, and writes a vendor/ directory that Composer-era tooling can still read, including the \Composer\InstalledVersions runtime API.

Do I have to rewrite composer.json by hand?

No. phast migrate converts an existing composer.json into phast.toml. Run phast install after it and you are done.

Which registries does Phast support?

Packagist, Private Packagist, Satis, and any other Composer-compatible registry. Phast speaks the same metadata protocol, so private repositories keep working as they do today.

How much faster is Phast than Composer?

On a real application of 202 packages with one installed straight from a git repository, a cold install takes 7.00s against Composer's 67.32s, installing from a lock file 5.20s against 17.17s, a warm cache 2.16s against 7.41s, and an install with nothing to do 0.53s against 3.12s. The run behind these numbers is published in the repository.

Does it work with Laravel and Symfony?

Yes. Phast generates a standard vendor/autoload.php, so a framework loads its dependencies exactly as it did before. Nothing in your application needs to change.

Which platforms can I install it on?

Linux and macOS, on both x86-64 and ARM. Releases ship prebuilt binaries for each, and the install script picks the right one.

Is Phast free to use?

Yes. Phast is open source and dual-licensed under MIT or Apache-2.0, the same pair of licenses most of the Rust ecosystem uses.

Can I use it in production yet?

Phast is in public beta. Try it on real projects and report what breaks; the lock file is deterministic, so you can always keep Composer alongside while you evaluate.

Free & open source.

Phast is built in the open and dual-licensed under MIT or Apache-2.0. Try it, star it, and let us know what you think!