internal/dload
DLoad simplifies downloading and managing binary artifacts for PHP projects. Automatically fetch tools like RoadRunner, Temporal, and custom binaries at pinned versions, ensuring consistent, cross-platform dev environments without committing binaries to version control.
Install the package:
composer require internal/dload -W
This adds the vendor/bin/dload CLI tool to your project.
Initialize configuration (interactive mode):
./vendor/bin/dload init
This generates a dload.xml file in your project root with default tools (e.g., RoadRunner, Temporal).
First download:
./vendor/bin/dload get
This fetches all configured binaries/PHARs to your project root (or specified extract-path).
<!-- dload.xml -->
<dload>
<actions>
<download software="rr" version="^2025.1.0" />
</actions>
</dload>
Then run:
./vendor/bin/dload get
Verify with:
./rr --version
dload.xml — actions are still the entry point for everything../vendor/bin/dload software — now also lists software definitions contributed by installed Composer packages (vendor/<pkg>#<id> style entries), so a package you already require may register its own binary without any XML at all..tgz, .tar) are extractable as of 1.19.0, so "release ships a tarball" is no longer a blocker.Add to composer.json to auto-download on composer install:
{
"scripts": {
"post-update-cmd": "dload get --no-interaction -v || echo 'Failed to download binaries'"
}
}
Why? Ensures CI/CD and local devs always have consistent tooling.
1.19 tip: if the tool you need ships a dload software definition in its own Composer package, declaring the dependency is enough — dload get picks up registry entries from installed packages. Use <package>#<id> as the software attribute to disambiguate when the same id exists in multiple packages or in the built-in registry.
<!-- dload.xml -->
<dload>
<registry overwrite="false">
<software name="MyPharTool" alias="myphar" description="Custom PHAR tool">
<repository type="github" uri="myorg/myphar" asset-pattern="/^myphar\.phar$/" />
<binary name="myphar" pattern="/^.*\.phar$/" version-command="--version" />
</software>
</registry>
<actions>
<download software="myphar" type="phar" extract-path="./tools" />
</actions>
</dload>
Key Points:
type="phar" to skip extraction (PHARs are self-contained).extract-path isolates tools from project files.# .github/workflows/download.yml
jobs:
setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install
- run: ./vendor/bin/dload get --no-interaction
- run: ./rr worker:start
Best Practices:
./runtime (DLoad’s temp dir) to avoid re-downloading.--no-interaction to skip prompts.% are no longer swallowed, so failure output is trustworthy../runtime won't poison subsequent runs with truncated binaries.<!-- dload.xml -->
<dload>
<actions>
<!-- Explicit OS/arch targeting -->
<download software="rr" arch="arm64" os="darwin" />
<download software="buf" arch="amd64" os="linux" />
</actions>
</dload>
Use Case: Force specific binaries for M1 Macs or ARM CI runners.
1.19 improvements: universal macOS binaries and x86-64 microarchitecture levels (x86-64-v2, v3, …) are now ranked when picking an asset, so mixed Intel/M1 fleets usually pick the right build without pinning. Also note that OS packages are not selected when a binary is expected — and DLoad now names the skipped OS packages in the failure report, plus warns when it fell back to an older release.
<download software="temporal"
version-path="[email protected]/sdk"
version="^1.0.0" />
How It Works:
version-path to a Composer constraint (e.g., "temporal/sdk": "^1.0.0").version constraint.1.19 note: constraint parsing was rewritten. Hyphen ranges (1.2.3 - 2.0.0), != / <>, a leading v, constraints with five or more numeric parts, build metadata (+build.5), and numbered pre-releases are all supported now. See Gotchas — ordering is DLoad's own, not Composer's.
<download software="mycli" type="archive" extract-path="./tools" />
<software name="InternalTool" alias="itool">
<repository type="gitlab" uri="https://git.internal.example.com/team/itool" />
<binary name="itool" pattern="/^itool$/" />
</software>
.tgz and .tar assets are unpacked automatically. If an archive can't be unpacked but a binary is expected, DLoad skips it instead of hard-failing the action.uri.| Issue | Solution |
|---|---|
| Binary not found | Check asset-pattern in registry; the 1.19 failure report now lists skipped OS packages and any older-release fallback. |
| Wrong OS/arch downloaded | Explicitly set arch/os or fix asset-pattern regex. Universal macOS and x86-64 microarch levels are auto-ranked since 1.19. |
| PHAR unpacked accidentally | Always use type="phar" for .phar files. |
| Permission denied | Run chmod +x ./rr or use --force in dload get. |
| CI fails silently | Add -v flag to dload get for verbose logs. |
| Constraint resolves differently than Composer | DLoad uses its own version ordering since 1.19; re-verify pinned ranges. |
| Shadowed software entry | A package-provided definition may shadow a built-in one — DLoad reports shadowed entries; disambiguate with <package>#<id>. |
| Stale truncated file | Fixed in 1.19: partial files are removed on failure. Older versions need a manual ./runtime purge. |
./vendor/bin/dload software
./vendor/bin/dload get --dry-run
ls -la ./runtime/
xmllint --schema vendor/internal/dload/dload.xsd dload.xml
<registry overwrite="true">
<!-- Overrides built-in tools -->
<software name="rr" alias="rr" version="2025.1.0">
<repository uri="spatie/roadrunner" asset-pattern="/^roadrunner-.*/" />
</software>
</registry>
Use Case: Pin a specific fork of a tool.
<actions>
<velox config-file="./velox.toml"
binary-path="./bin/custom-rr"
debug="true" />
</actions>
Requirements:
velox.toml generated from roadrunner.dev/build.--cache to reuse downloaded assets. Repository fallback (invalid URI / unknown type) means a misconfigured mirror no longer burns a run.Add a new tool to the registry:
Prefer shipping a software definition inside your own Composer package (1.19.0) over editing vendor/internal/dload/src/Registry/SoftwareRegistry.php.
Better: Use inline <registry> in dload.xml, or a Composer-provided definition referenced as <package>#<id>.
Custom download handlers:
Implement Dload\Contracts\DownloadHandler and bind it in a service provider. The installer was refactored into a readonly step pipeline in 1.19 — handlers that assumed a specific install order or wrote the destination themselves should be revisited.
dload get --dry-run for every configured action after upgrading and pin exact versions if a range now selects a different release.software entry that "never matched" before may suddenly download something. Review asset-patterns.How can I help you explore Laravel packages today?