PHP
Article

Bower vs BowerPHP

By Bruno Skvorc

On October 28th, 2014, puppies all over the world spontaneously burst into flames – or so the community would have you believe. What happened was the reveal of BowerPHP (I shy from calling anything “alpha” a release), and here’s why it wasn’t anything nearly as apocalyptic as some would have you believe.

What?

BowerPHP is a PHP version of Bower, the NodeJS based front end package manager. We covered Bower before somewhat, but in essence, you use it to install front end libraries like jQuery, Angular or Foundation much in the same way you use Composer for PHP dependencies. You define a Bower file with dependencies, run bower install, and watch the magic happen.

The packages will usually be installed in a bower_components folder which is created if it doesn’t exist, and you can either link to them directly, or pull them through some additional concatenation/minification filters before doing so to reduce the number of requests and download size.

So… why a PHP version of it, if a Node version exists? Good question – but before answering it, let’s install BowerPHP and use it to pull in some packages.

Installing

I’ll be using our official Homestead Improved box. If you don’t want to, you don’t have to, but it’s the simplest way to get started following along.

To make BowerPHP globally available to our system, we execute the following:

composer global require "beelab/bowerphp 0.1.*@alpha"

Wait, what? That’s it?

Yep.

We installed in seconds what would have taken us minutes with NPM, if it would have worked at all in a VM hosted on Windows.

Execute bowerphp to see if it works.

Using

To see an example use case, let’s try it out. We’ll create a “Hello World”index.html file in a project folder accessible from the browser, in our case, Code/Laravel/public via homestead.app:8000.

cd ~/Code
mkdir -p Laravel/public
cd Laravel/public
echo "Hello World" > index.html

Visiting homestead.app:8000/ in the browser should display “Hello World” now.

Let’s install Foundation.

bowerphp install foundation

Uhh… what? No problems? But.. I’m running a Vagrant box inside Windows! Where are the warnings, the bugs, the permission problems? Where are all the errors caused by NPM’s clumsy directory structure? BowerPHP installed Foundation for me in fifteen seconds flat.

Let’s see if everything works fine by including the assets in our HTML. Replace the contents of index.html with the following:

<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>MY_APP</title>
    <meta name="description" content="MY_DESCRIPTION">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->

    <link rel="stylesheet" href="bower_components/foundation/css/normalize.css">
    <link rel="stylesheet" href="bower_components/foundation/css/foundation.css" />

    <script src="bower_components/foundation/js/vendor/modernizr.js"></script>
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->

<div class="off-canvas-wrap" data-offcanvas>
    <div class="inner-wrap">
        <nav class="tab-bar">
            <section class="left-small">
                <a class="left-off-canvas-toggle menu-icon" href="#"><span></span></a>
            </section>

            <section class="middle tab-bar-section">
                <h1 class="title">MY_APP</h1>
            </section>

            <section class="right-small">
                <a class="right-off-canvas-toggle menu-icon" href="#"><span></span></a>
            </section>
        </nav>

        <aside class="left-off-canvas-menu">
            <ul class="off-canvas-list">
                <li><label>Sections</label></li>
                <li><a href="#">Dashboard</a></li>
                <li><a href="#">Author List</a></li>
            </ul>
        </aside>

        <aside class="right-off-canvas-menu">
            <ul class="off-canvas-list">
                <li><label>Users</label></li>
                <li><a href="#">Hari Seldon</a></li>
                <li><a href="#">...</a></li>
            </ul>
        </aside>

        <section class="main-section" id="content">
            <div id="charts"></div>
            <div class="panel"><p>Hello</p></div>
        </section>

        <a class="exit-off-canvas"></a>

    </div>
</div>

<script src="bower_components/jquery/dist/jquery.min.js"></script>

<script src="bower_components/foundation/js/foundation.min.js"></script>
<script src="bower_components/foundation/js/foundation/foundation.offcanvas.js"></script>

<script>
    $(document).foundation();
</script>

</body>
</html>

Open the page in your browser to check if it works:

Why it’s Awesome

So to answer our question above – why a PHP version of a JS tool? Because it’s needed. Granted, it’s not needed by many, and I as someone who suffered through symlink and filepath-hell with NPM on Windows probably appreciate it more than most, but I’m still thrilled it exists, and want it to grow. If you’re looking for a more direct list of pros and cons in a Bower vs BowerPHP fight:

Pros of BowerPHP:

  • No need to use JS
  • Compatible with VMs hosted on Windows
  • Really fast
  • Easy to install
  • Highly portable alongside your PHP apps – write a Bowerfile, add BowerPHP to your composer.json file and put bowerphp install into Composer’s post-install-script block, and you’ll have your project’s front end installed alongside backend immediately after a single composer install – without ever touching Node, or even knowing it exists on the system

Cons of BowerPHP:

  • there might come a time when Bower will leave BowerPHP behind with some esoteric future functionality

I honestly can’t think of any other cons. Can you? Let me know.

Conclusion

BowerPHP is pretty cool. It’s an ambitious “reinvention of the wheel” but this time, the wheel’s shape and form stayed the same – just the material changed from balsa wood to oak, and oh boy does it turn better. The community pushback against this project reminded me of what Beau spoke at Forum PHP – persisting until you find support, and here’s hoping that this post of praise and high fives lets the team know they’re not alone in the need for Node-less Node tools, and that they should keep doing what they’re doing.

With BowerPHP, we get the ability to install our front end assets as simply as we do with back end packages – and combined with Assetic for filtering, minification and other magic, BowerPHP becomes your front end hypertool.

What do you think about BowerPHP? Useless project or much needed tool? Why? Tell us in the comments!

Free Guide:

7 Habits of Successful CTOs

"What makes a great CTO?" Engineering skills? Business savvy? An innate tendency to channel a mythical creature (ahem, unicorn)? All of the above? Discover the top traits of the most successful CTOs in this free guide.

  • http://blog.blacksonic.info/ Blacksonic

    is there any pro on linux?

    • http://aurielle.cz/ Aurielle

      You still don’t have to install node :D

      • Vladimir López

        Why you hate node so much? Node is an awesome technology

        • http://about.me/mikeschinkel MikeSchinkel

          Not hate. Just not prefer. Node has a comparative steep learning curve if you spend 90% of every work day in PhpStorm.

  • HotDang

    Don’t care.

    • http://dextructables.com/ Judas Borbón

      I just spoke with the development team of BowerPHP and they say they will halt the project because you don’t care about it.

      • HotDang

        Did you forget to inform them that my opinion really doesn’t matter?

      • http://www.dev-metal.com/ Chris

        @Judas Borbon: :) BEST comment on the internet! I had to make a screenshot. *slow clap*

      • http://heera.it/ Sheikh Heera

        lol… It’s 5:56 am here (just the morning) and this comment made me lough loudly… :-)

  • Massimiliano Arione

    I’m the main developer of BowerPHP. We started the project just because we needed bower on a machine without node (out of our control, of course). We never meant to replace bower. BowerPHP currently needs some dev love, I hope to see many contributions! :-)

    • Tatsh

      I am not sure why you guys did not copy the dependencies over from a sever you do control and can have Node on it (make a release distribution tarball). That is what we do. Node is not on most of our web servers.

    • http://www.dev-metal.com/ Chris

      You have started something that might become a serious standard in the PHP world. Thanks man, this is gold!

    • Fedor

      Good call.

    • Billy J Figueroa

      I’m glad you did, thanks man!

  • hot_rush

    can i use grunt/gulp/etc without node?

    • http://www.bitfalls.com/ Bruno Skvorc

      Nope. There are other task runners for PHP though.

      • Martin Zajíc

        Which need node or native applications installed over npm or something. So if you using gulp with bower or something it’s better to stick with it. (Or you can use NAPA instead of bower)

        • http://www.bitfalls.com/ Bruno Skvorc

          Not all of them, some are through-and-through PHP

          • Martin Zajíc

            Well if you need something advance you always need NODE or JAVA (well i rather choose node)

            I know two tusk runners for php Robo and bldr. And they are good maybe for run unit tests or clear cache folders. When it comes to compare with gulp they are useless.

            Either way I don’t see point, doing this kind of “forks” like bowerphp when you should use separate server for building your apps, where you node and other stuff. There is no point to have nodejs installed on only php server.

          • http://www.bitfalls.com/ Bruno Skvorc

            Could you elaborate on why they would be useless and only good for clearing cache or running tests?

          • Martin Zajíc

            Maybe I didn’t use right word for it. They are good tools as any (although with comparison to gulp :) ). Problem is the ecosystem, with nodejs, ruby,… I just install package manager maybe some global dependencies with it and I’m done. Just add packages to config and install. With php I need to add packages to config too, but mostly the tools are just wrappers around another tools which have to be installed separately (node,java,ruby,…). And that’t some more work on every environment setup.

            An example: (I’m developing mostly apps based on AngularJS and Symfony2)
            Browserify->AutoAnotation->AutoPolyfiller->Uglify,
            Less->autoprefixer->minify, Compression of images, Sprites, HTML2JS, Livereload

            And It’s just few lines of code, and all environment is setup in few minutes. Actually more time takes composer to download php packages and install it.

            So far I newer seen something like this under PHP task managers, mostly it’s just tests, clearing, concat and uglify (with external tools).

          • http://www.bitfalls.com/ Bruno Skvorc

            Assetic can support most of those filters and tools without needing additional non-php stuff installed, but I see what you mean. Still, on machines that can’t support Node or NPM’s amateurish directory structure, something like this that also gets installed in seconds is a godsend.

          • Martin Zajíc

            Well I would like to see this made by assetic :)
            But when it comes to machines that cant support node you don’t have other option.
            Still if you look at https://github.com/kriswallsmith/assetic to readme all “recipes” are including java, node or ruby programs.
            And other thing which is not good on assetic is look at issue list and number of pull requests, progress made on it is quite slow.

  • Kevin Vandenborne

    I’m hoping to use it in the near future, now I don’t have to commit JS libraries in my projects anymore to deploy it. This is fantastic!

    • Tatsh

      You never had to. All you had to do was use a bower.json file. And to avoid having Node on the server, make release tarballs that you deploy to staging/QA for testing, then to production.

      • Kevin Vandenborne

        I might look into that, i currently use springloops or rocketeer for deployment.

        • Tatsh

          Well I’m not trying to get too specific on deployment solutions. I actually use Ansible for most deployment and also set up of my own machines, and my servers tend to receive a tarball rather than using git + bower/composer/npm/sass/compass/etc. It is faster to deploy that way and more secure (no .git, not git command on the server). Has far less dependencies (literally, the tar and gzip commands).

          • http://www.bitfalls.com/ Bruno Skvorc

            Would you consider writing about that?

          • Bruno Seixas

            I would also like to know more.

          • Dionis Spinei

            Specifically creating the tarball part is interesting

          • Tatsh

            Well, it’s really simple in a way. I mentioned the reasons before to do distribution this way but the other reason is because sometimes dependencies disappear. This can happen with Pip, Composer, etc very easily. I have often made a backup of composer.lock and vendor/ directory just in case things get strange the next time I run a composer command that changes vendor/.

            The set-up is:

            * Server contains all release tarballs created. It also creates them. This means it has the necessary items, Git and things like Compass, Node, etc. This is also immensely useful for developers to be able to get a copy of what is in production with generated assets (the tag in Git should show the same exact code). Tar’ing without the .git directories is something like (where thesite is the directory containing the entire site): cd .. && find thesite -type d -name ‘.git’ -exec rm -vfR {} + && tar thesite-$tagname.tar.gz thesite
            * Symlinks to latest tarball with the same file name every time
            * QA (an environment with a lot of debug helpers on)
            * Staging pulls in and untars, moving old code away and then untar’ing (getting the file is done with Rsync over SSH). No debug helpers, but monitoring software is used.
            * Production pulls in and does the same as staging. Monitoring software used to check the release is working.
            * Another script exists to revert code on any host in case the release goes bad

            Another way to do this, I would consider for production but only for small scale (<= 10 machines), is to make new boxes or use an unused instance on AWS, run deployment/provisioning on the boxes then switch them out in the load balancer (ELB). As long as you kill the other boxes once you are sure the release is good this does not cost very much to do. If you keep track of the old boxes, a reversion is easy: just remove all new boxes from the load balancer, and put in the old ones. The reason I like this approach is that it continually proves that the deployment is independent of existing items on the machines (similar to bootstrapping for a unit test). It is not as fast for large deployments compared to swapping code, but I like that getting to a working state is just create a new box and replace the old one rather than try to fix the old one when it could be something out of your control (on AWS I have occasionally got 'bad boxes' that just had to be replaced).

      • Fedor

        Transferring compressed files all around kinda defeats the whole purpose behind package managers, doesn’t it? Just zip up the whole project and dump it on the server, done… oh wait…

        • Tatsh

          The package managers and asset managers/generators (think Compass, Sass) are run in a controlled environment, and not on the production server itself. Generally production servers should be touched the least, especially when things are not considered broken. Uncompressing an archive is minimally invasive compared to using package managers and requires less stuff to be on the production server.

          • Fedor

            assuming your production environment is identical to your dev/test… which is often not the case, hens the managers

          • Tatsh

            No you would generally never do that. The box that generates builds always builds in production mode (minified JS and CSS, optimised images, optimised autoloader from Composer, etc).

          • Fedor

            Again, that only works if the environment your build on is exactly the same. One wrong path and you’re gonna wanna kill yourself troubleshooting minified files.

  • matt@piwik

    Thanks for creating BowerPHP it will be very useful! FYI we tried it at Piwik but it work out of the box – https://github.com/piwik/piwik/blob/master/bower.json
    We will likely try again to use bowerPHP for Piwik in a few months. It would be useful to us as it will allow Piwik Plugins written in PHP to handle their JS dependencies without having to install nodejs on their dev machine. Ftw

  • dmtrsslvdr

    There is a composer plugin which works as a NPM/Bower Dependency Manager for Composer that allow you to manage project assets (css, js, etc) in your `composer.json` without installing npm or bower.

    This is the way Yii 2 framework is installing it’s assets.

  • http://www.bitfalls.com/ Bruno Skvorc

    This is pretty cool, but one clear advantage of bowerphp over this is that components get installed into bower_components, thus automatically being compatible with projects that do have to use bower. Still, good stuff, I’ll check this out.

  • Keith Penderis

    I can imagine this to be helpful for beginners on php that really just do not want to be dealing with node and all that kinda keeps your package management learning curve a bit down, I do still find it quite a difficult concept and think this might just have more people properly trying to implement it even in small projects just because now they can.

  • boen_robot

    I don’t get it…
    What’s the difference between publishing an NPM/Bower asset package, and installing it with Composer vs. making the assets themselves be a Composer package? Any benefit/drawback from one approach vs. the other?
    Can anyone enlighten me on this probably basic (yet apparently not so obvious) thing?

    • http://www.bitfalls.com/ Bruno Skvorc

      If I understand your question, Composer installs things into the /vendor folder, which is not public. BowerPHP installs them into bower_components, following all the exact same practices normal Bower does, thus making them both immediately usable by the project you’re working on, and compatible with Bower-friendly environments. In a nutshell, it’s not really possible to install assets with Composer without getting really hacky, at least as far as I can tell.

      • http://heera.it/ Sheikh Heera

        Probably this will help to develop a PHP package which requires both composer and JS packages within one place.

      • boen_robot

        Ah, so the crux of the problem being solved is that “vendor” is supposed to be private (above a web root), while assets are supposed to be public (at or inside a web root). Got it. Thanks.

      • http://about.me/mikeschinkel MikeSchinkel

        Seems like Bower would not be needed if Ccomposer were more flexible?

  • Bruno Seixas

    I think that having options are always a great thing, so having the possibility of using Bower without Node can be helpful.

  • http://www.schmutzka.eu/ Tomáš Votruba

    I guess every technology that one doesn’t understand/use, is not so awesome.

  • http://www.schmutzka.eu/ Tomáš Votruba

    Great article, thanks for spreading the word!

  • Sugato Sengupta

    ” In his free time, he writes tutorials on his blog and stalks Google’s job vacancy boards.” – Freaking hilarious :p

  • http://www.bitfalls.com/ Bruno Skvorc

    If you look at NPM, the file-path-too-long issue has been open for years, and NPM is backed by a huge corporation and many more people. So I would argue progress is slower there. Yes, Assetic has some ruby deps (sass, compass), but no Java, and node is entirely optional – you can implement all the filters in PHP easily. It does, in fact, work out of the box on PHP machines, and that’s all that matters. Of course, if I was developing a front end app ONLY, then I’d definitely go PHP-free and wouldn’t use Assetic or BowerPHP or anything similar, but if I’m working on a PHP app and there’s a good PHP alternative to anything Node based, I will definitely choose that.

  • Abdul Malik Ikhsan

    awesome post! the composer installation need to be updated imo, some assets can’t be loaded with “0.1.*@alpha”, so it should be “1.0.*@dev” instead.

  • freddy96

    Hey anyone knows about LongPathTool??
    I am using it I think its an awesome tool..

  • Billy J Figueroa

    Oh this is awesome. I was just looking at some of the “front end” packages on bower and thought to my self…oh boy. I was looking on how to try to make this work with node, but this seems just right. I wish guys would make some of the other tools like yeoman for php. I want to use those tools but don’t want to have to hack stuff to get a nice working flow with php.

    Massimiliano Arione thank you very much for this!

    oh and for those wondering how to get minification and a bunch of other stuff you can actually purchase codekit. It is a GUI. It doesn’t give you the control that something like grunt gives you but its nice

  • zoltanradics

    If Ruby developers has no problem with Bower on NodeJS, why it’s a problem for PHP developers? (ofcourse without any offsense) I do not understand Bower why makes sense on your server. In our development workflow Bower is only on our local machine and we use Gulp to build and deploy. But we do not need Gulp and Bower on our servers. I do not understand the point of this project.

    • http://about.me/mikeschinkel MikeSchinkel

      If you don’t understand it then it is not for you.

      • zoltanradics

        I realized that. Probably becouse i rarely use PHP. As i put a note in my last comment, i was not offensive. i am not a PHP hater but still do not understand why Bower makes sense on the server side. Instead of lecture me, help me to find out what is the use case. I am coming from the frontend development world where we use Bower with JS and the way we use, we don’t need it on the server side.

Recommended
Sponsors
Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.