Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Bowerphp Laravel Package

beelab/bowerphp

A PHP implementation of Bower, the front-end package manager. Install with Composer, configure your bower directory via .bowerrc, and set BOWERPHP_TOKEN to lift GitHub API rate limits. Stable but still pre-1.0, so backward compatibility isn't guaranteed.

View on GitHub
Deep Wiki
Context7

Getting Started

BowerPHP is a Symfony Console application that reimplements a subset of Bower's CLI in PHP — no Node.js, no npm install -g bower. You add it to a project that already has (or inherits) a bower.json and run it to materialize bower_components/.

Minimal steps:

# 1. Install as a dev dependency (it is a build-time tool, not runtime code)
composer require --dev beelab/bowerphp

# 2. Confirm the binary and the command surface
vendor/bin/bowerphp list

# 3. Tell it where components should land
cat > .bowerrc <<'JSON'
{ "directory": "resources/assets/vendor" }
JSON

# 4. Point it at a manifest (copy the legacy one, or create inline)
cat > bower.json <<'JSON'
{
  "name": "my-app",
  "dependencies": {
    "jquery": "2.2.4",
    "bootstrap": "3.3.7"
  }
}
JSON

# 5. Resolve and download
vendor/bin/bowerphp install

Where to look first:

  • .bowerrc — the only configuration surface the README documents. The directory key is the one that matters; everything else is defaults.
  • bower.json — the manifest. Treat dependencies as the source of truth and pin exact tags, because BowerPHP's semver resolution is not as forgiving as real Bower's.
  • vendor/bin/bowerphp list — the authoritative list of commands. BowerPHP implements a subset of Bower (typically install, update, search, info), so verify before assuming bower link, bower cache clean, or bower prune exist.
  • The package source under vendor/beelab/bowerphp/src/ if a command misbehaves — you will be reading it eventually, since there is no active issue tracker response.

First use case that actually justifies the tool: you have inherited a Laravel 4/5-era app whose layouts reference bower_components/bootstrap/dist/css/bootstrap.css, the machine no longer has Node, and you need those files present for a php artisan serve smoke test or a CSS rebuild. BowerPHP gets you there with only a PHP toolchain.

Implementation Patterns

Hook asset installation into Composer. If BowerPHP is part of the deploy contract, make it run automatically rather than relying on tribal knowledge:

"scripts": {
  "post-install-cmd": ["@bowerphp-install"],
  "bowerphp-install": "bowerphp install --no-interaction"
}

Because it lives in require-dev, guard against --no-dev production installs — either move it to require for the rare case where production assets are built on the server, or accept that assets must be pre-built in CI.

Point .bowerrc at your build pipeline's input, not at public/. The default bower_components directory sitting next to bower.json is almost never what a Laravel app wants. Two workable layouts:

  • "directory": "resources/assets/vendor" — then let Laravel Mix/Webpack resolve vendor/jquery/dist/jquery.js as modules. This keeps vendor JS out of your committed public/ and lets you concatenate/version normally.
  • "directory": "public/vendor" — for legacy apps where Blade templates hardcode <script src="/vendor/...">. Fast, but you must decide whether public/vendor is committed or gitignored-per-deploy; mixing the two is the classic source of "works on my machine".

Inject the GitHub token through the process environment, not just .env. The README's rate-limit guidance (BOWERPHP_TOKEN) is read from the real environment. In a Laravel context that means exporting it, or explicitly passing it to a subprocess:

use Symfony\Component\Process\Process;

$process = new Process(['vendor/bin/bowerphp', 'install', '--no-interaction']);
$process->setEnv(['BOWERPHP_TOKEN' => config('services.github.token')]);
$process->setTimeout(600);
$process->run();

Wrapping it in an Artisan command (php artisan assets:bower) is a reasonable integration pattern if you want the install to be part of a deployment script with your app's logging and failure semantics.

Cache aggressively in CI. The GitHub API limit is 60 requests/hour unauthenticated. A cold install of a dozen packages will blow through that. Cache both the token-authenticated path and the download directory, and cache bower_components keyed on the hash of bower.json:

- uses: actions/cache@v4
  with:
    path: resources/assets/vendor
    key: bowerphp-${{ hashFiles('bower.json', '.bowerrc') }}
- run: vendor/bin/bowerphp install --no-interaction
  env:
    BOWERPHP_TOKEN: ${{ secrets.BOWER_TOKEN }}

Pin exact versions and vendor the result. Because BowerPHP is unmaintained, treat every install as a one-way door: resolve once, commit either bower_components/ or the extracted files you actually use, and stop depending on network resolution for reproducible builds. This is also your migration escape hatch — once the tree is on disk, you can rewrite the imports to npm equivalents and delete BowerPHP.

Use it as a resolver, not a package manager. The highest-value pattern for a modern Laravel app is a one-shot: run bowerphp install against the legacy manifest, copy the handful of dist/ files into resources/js/vendor/ or node_modules equivalents, then remove the dependency. BowerPHP is a translation tool for a dead ecosystem, not a thing to build a long-lived workflow on.

Gotchas and Tips

It is archived and effectively abandoned. Last release January 2017, no maintainer response path, and 0 dependents on the tracked index. Realistically:

  • The Symfony Console and Guzzle versions it pins are ancient. On PHP 8.x expect hard failures (mcrypt, removed each(), $var{0} string offsets, deprecated Symfony\Component\Console APIs). PHP 7.1/7.2 is the practical ceiling; verify before committing to it.
  • If Composer refuses to install due to platform constraints, --ignore-platform-reqs will get it onto disk but not necessarily make it run. Test vendor/bin/bowerphp list immediately.
  • Prefer running it in a container pinned to PHP 7.x if you must keep it in a modern app's CI.

The Bower registry is the weak link. install resolves names via the public Bower registry, which has been unreliable/deprecated for years, and unknown packages fall back to GitHub lookups. Symptoms: hangs, 404s on packages that definitely exist, or resolution of a fork instead of the canonical repo. Workarounds:

  • Use full Git URLs in bower.json ("[email protected]:twbs/bootstrap.git#3.3.7") instead of registry names.
  • Prefer https:// over git:// in URLs — git:// is blocked on many networks and CI runners.
  • git must be installed and on PATH; BowerPHP shells out to it. Failures here often surface as opaque "could not resolve" errors rather than a clear missing-git message.

Rate limiting is the #1 operational failure. 60 requests/hour is trivial to exhaust — a single install of a package with many transitive bower dependencies can consume most of it. Set BOWERPHP_TOKEN everywhere: local shell, CI secrets, container env. Remember Laravel's .env does not automatically populate the OS environment for subprocesses; use Process::setEnv() or export. Debug with ENV inspection first, then -vvv verbosity on the command.

Semver resolution differs from real Bower. Ranges like ~1.2 or ^2.0 may resolve differently, and there is no equivalent of Bower's conflict resolution prompts or a lockfile to freeze the tree. Pin exact versions ("1.2.3", not "^1.2"). If two packages disagree, BowerPHP will likely just pick one rather than warn you — diff the resulting tree against a known-good Bower install if correctness matters.

Many packages ship no bower.json. Real Bower tolerated this, guessing the main file from the repo root; BowerPHP's subset handling is stricter and may fail or leave you with an empty/useless package directory. Check that the expected dist/ files actually exist after install — a "successful" exit code is not proof. -v/-vv/-vvv is your primary debugging lever; there is no log file.

.bowerrc is parsed as JSON, strictly. Comments and trailing commas that Bower's parser tolerated will break it. Keep it to a single directory key. Also note the directory is created relative to the working directory, not to bower.json — run the binary from the project root or a Process with an explicit cwd.

Don't commit bower_components under public/ and also list it in .gitignore. The most common breakage in inherited projects is a .gitignore entry for public/vendor combined with a deploy that assumes it's present. Pick one: commit the resolved files, or run BowerPHP in the build step. Given the package's state, committing is the safer choice.

Extension points exist but are a trap. It's Symfony Console — commands live in src/, so you can add a command or override the installer. Resist. Forking an archived, zero-dependent repo means owning the whole maintenance burden, including Guzzle/Symfony upgrades, for a tool whose entire purpose is managing software that itself is deprecated. If you need behavior it lacks, the correct move is to extract the resolved assets and move to npm.

Verdict for day-to-day use: treat BowerPHP as a short-lived migration aid, not infrastructure. If you're on a legacy Laravel app with a bower.json you can't yet delete, it's a legitimate stopgap — isolate it in a dev dependency, pin everything, vendor the output, and put a ticket on the board to eliminate it. For greenfield work, skip it entirely; npm, Vite, and laravel-vite-plugin cover the same ground with an actively maintained toolchain and no GitHub API ceiling.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums