Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jjudge's avatar

What problem does elixir solve?

I have tried building a front end using bower/gulp in the past, and got so lost - the tutorials for using these front end tools is so fragmented - it is like everyone just makes it up as they go along, with little common approaches to follow. So I have always ended up just copying a bunch of JS, CSS and image files into the public area and including them on the page. It works, but is hardly ideal as a workflow.

So, I'm trying to navigate this front end stuff again, and have elixir in the mix here. What I don't understand is just how elixir fits into the picture. Bower is the dependency manager - it downloads stuff into a directory. gulp is like a build file - it does stuff with those files to compile, merge and copy them. So what does elixir do? Why do we need it?

From what I have read, it possibly does magic stuff by knowing stuff that I don't have to know and so does stuff the right way without me having to get involved, or something. But that means I understand even less of what is actually going on when gulp is run.

0 likes
24 replies
richwilliamson's avatar

Elixir is just a wrapper to gulp and makes using gulp super easy. Essentially you've got it though Elixir is for compiling your SASS or LESS into CSS and minifying the output. It also does the same for things like CoffeeScript that need compiling. You can also trigger unit tests and merge your stylesheets and js files into one file. All these things are good for front-end websites where you want to reduce the size of your payload and reduce the number of https requests required to load your site.

Although this series has been achieved it might be useful. https://laracasts.com/series/laravel-5-and-the-front-end

In a busy work place it can often be hard to find the time to learn these types of things. It seems everyday there's some new JS library, CSS tool or a new dependency manager for something or other but in taking time out to learn these things you're actually loosing precious time. I've done it myself where just doing things the "old way" seems quicker and easier to get the job done. Try and resist the urge to plow on with your current workflow it will probably benefit you in the long run even if in the short term your running a little slower whilst you get your head around these things.

martinbean's avatar

@consil Elixir is a suite for working with front-end assets, built on the Node.js ecosystem. So Node is used to pull in the components that make up Elixir, just like Composer is used to pull in PHP packages.

Elixir has tasks for common functions such as compiling LESS or Sass, combining JavaScript files etc. If you’ve just worked with vanilla CSS in the past, you may have found yourself with massive style sheets on large projects where a stylesheet starts getting unwieldily, hard to grep etc. LESS and Sass step in here by allowing you to break styles into “components”, that are then compiled into one resultant stylesheet, and optionally minified.

Similarly with JavaScript, instead of having one large “app.js” or “functions.js” file, it allows you to split functions into components, that can then be combined into one, single JavaScript file to minify HTTP requests.

There are other utilities within Elixir, but the above are the most common scenarios.

JeffreyWay's avatar

Think of it like this:

  1. Gulp is a build tool.
  2. You have to write these tasks manually, though. It can take hundreds of lines worth of tasks. Annoying...and you always have to research what to do.
  3. When working across multiple projects, you end up creating Gists for yourself, so that you can reuse them everywhere.
  4. Elixir is a wrapper around Gulp to make common tasks easier. What requires 400 lines with vanilla Gulp ends up being about 3-5 lines with Elixir.
elixir(mix => {
    mix.sass('app.scss')
       .browserify('main.js');
});

Bam.

1 like
jjudge's avatar

Thank you all - I'll do some more research with what you have all given me.

@richwilliamson Yes, I do feel I need to get over this hurdle. It's a touch world being a full stack developer these days, because the "stack" is so deep and so wide, but the stuff we can do now would have taken teams scores of people in size and enormous budgets. When you say Elixir is a wrapper for gulp, is it strictly that way around? Is elixir not more like an extension or plugin of gulp? Maybe I'm just looking at it the wrong way.

@martinbean I've got node, bower etc installed. Those tools have come on a long way in the last year - installation was a mess of dependencies then, and was as smooth as anything this time. Many of the tutorials I see focus a lot on combining the assets, which is great for production, but I think for development I need to just get it to compile and copy the correct files into the correct places. Doing so seems to need a lot of "secret" intimate knowledge of each of the packages involved. I really was not sure if I was just missing something, or that really was the how it worked.

@JeffreyWay I think you have hit the nail on the head here. I like to understand how things work - internally I work visually, and if I cannot "feel" the shape of the code, I get lost very quickly. This is probably why I'm having difficulties - those 100 lines of gulp are what I need to understand, but it's the five lines of elixir that is actually exposed. Just making that leap between, say, installing a Datatables bower package, and knowing what elixir commands to type into gulp so it does the right thing (whatever that is - presumably known only after digging into the docs) is to me two ends that just don't join up, at this stage. But knowing this unknown is half of knowing, so I know where to look now :-)

I'm going to bed now with a tablet to do a bit more research into this. I'm not a front-end designer, so am really just interested in the functionality, but if I can set up the workflow so a designer can have their way with the bootstrap + various tools that I need to use, with the least of effort, then I think this is going to be worthwhile. Now, off to dream of electric sheep and gulpy-bower elixirs...


PS @martinbean some help you gave me a few weeks ago turned into a lightening talk at PHPNE this week, in which I blasted everyone with far too much information on jobs, commands, events, schedulers etc. Slides are up if you are interested github.com/judgej (not sure if you were there or not - saw your name on the list).

1 like
secondman's avatar

@consil

Yeah do the research on it for sure, Elixir is a LIFESAVER for me, it saves so much time and page load on your project.

For example in the current project I'm working on Elixir does the following:

  1. Copies 116 various image, font, and JSON files
  2. Compiles 110 .less files to a single css file
  3. Compiles 32 javascript files into a single javascript file
  4. Does a version build of each for cache-busting when you make changes

All in just over 6.5 seconds.

With the --production flag it minifies all the css and javascript as well, which takes about 1 minute or so.

Even with all that css and js my current PageSpeed and YSlow scores on my production server are both 100.

It's well worth the time to learn it.

-V

jjudge's avatar

So is it fair to say it is a tool that gulp uses to do various things that you would normally have had to do with a dozen different tools previously? So whether you want to compile sass or less, move some files, merge or minimise some scripts or styles, there is just one tool here that handles the more complicated tools that it wraps? So @vkronlein - guzzle gulp does those things for you, but elixir makes it many times easier to set up?

This would be similar in concept to the scheduler, where you call just one scheduling command every minute, and then laravel makes it easier to define the schedules in a fluent way (in PHP) and invokes each command for you when they are due to run that minute.

secondman's avatar

Hi @consil

Yes you're exactly right (though I'm sure you meant Gulp as opposed to guzzle, that's a different package for HTTP requests)

As @JeffreyWay said, Elixir is a wrapper for Gulp. Think of it this way. Laravel is a wrapper for Symfony 2. Of course there is much more to it than just Symfony 2 (or 3 actually now), but the same idea applies. Laravel uses many packages from Symfony to do what it does. Elixir is the same, it uses many NodeJS packages to simplify your build process, it's just written in Javascript.

NodeJS == PHP

NPM == Composer

Elixir == Laravel

Gulp == Symfony 3

Just as you mentioned, the same way scheduler gives you shortcuts and makes running cron jobs simple, Elixir does the same with your build environment.

Here is my entire Gulpfile for my current project that I mentioned earlier:

var elixir = require('laravel-elixir');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Sass
 | file for our application, as well as publishing vendor resources.
 |
 */

elixir(function(mix) {
    
    /**
     * First let's copy all of our fonts to the assets directory.
     */
    mix.copy(
        'resources/assets/fonts', 
        'public/assets/fonts'
    );

    /**
     * This is some stupid shit, but we also have to copy all the
     * fonts to the build/assets/fonts directory for versioning. :(
     */
    mix.copy(
        'resources/assets/fonts', 
        'public/build/assets/fonts'
    );

    /**
     * Let's copy our images, most of these are for the demo
     * so we'll need to weed through them when we're ready.
     */
    mix.copy(
        'resources/assets/img', 
        'public/assets/img'
    );

    /**
     * More stupid shit! Images as well it seems must
     * be located in the build directory.
     */
    mix.copy(
        'resources/assets/img', 
        'public/build/assets/img'
    );

    /**
     * Demo ajax (remove)
     */
    mix.copy(
        'resources/assets/ajax', 
        'public/assets/ajax'
    );

    /**
     * Helper JS. At this point I'm unsure how much of
     * this needs to remain.
     */
    mix.copy([
        'resources/assets/js/quirk/charts.js',
        'resources/assets/js/quirk/dashboard.js',
        'resources/assets/js/quirk/html5shiv.js',
        'resources/assets/js/quirk/map.apple.js',
        'resources/assets/js/quirk/map.bluewater.js',
        'resources/assets/js/quirk/map.mapbox.js',
        'resources/assets/js/quirk/map.shadesofgrey.js',
        'resources/assets/js/quirk/map.shiftworker.js',
        'resources/assets/js/quirk/modernizr.js',
        'resources/assets/js/quirk/respond.js'
    ], 'public/assets/js/');

    /**
     * Less mix some css, "less" get it? =)
     */
    mix.less(
        'app.less', 
        'public/assets/css/app.css'
    );

    /**
     * Build the application.
     */
    mix.scripts([
        'quirk/plugins/jquery.js',
        'quirk/plugins/ui.js',
        'quirk/plugins/touch-punch.js',
        'quirk/plugins/bootstrap.js',
        'quirk/plugins/handlebars.js',
        'quirk/plugins/autosize.js',
        'quirk/plugins/select.js',
        'quirk/plugins/toggles.js',
        'quirk/plugins/gritter.js',
        'quirk/plugins/data-tables.js',
        'quirk/plugins/bootstrap-tables.js',
        'quirk/plugins/steps.js',
        'quirk/plugins/maskedinput.js',
        'quirk/plugins/timepicker.js',
        'quirk/plugins/dropzone.js',
        'quirk/plugins/colorpicker.js',
        'quirk/plugins/validate.js',
        'quirk/plugins/summernote.js',
        'quirk/plugins/flot.js',
        'quirk/plugins/flot-resize.js',
        'quirk/plugins/flot-symbol.js',
        'quirk/plugins/flot-crosshair.js',
        'quirk/plugins/flot-categories.js',
        'quirk/plugins/flot-pie.js',
        'quirk/plugins/flot-spline.js',
        'quirk/plugins/knob.js',
        'quirk/plugins/morris.js',
        'quirk/plugins/raphael.js',
        'quirk/plugins/sparkline.js',
        'quirk/plugins/gmaps.js',
        'quirk/plugins/sweetalert.js',
        'quirk/quirk.js'
    ], 'public/assets/js/app.js');

    /**
     * Let's create some cache busting versions.
     */
    mix.version([
        'assets/css/*.css', 
        'assets/js/*.js'
    ]);

});

And given this is a bit verbose simply because all the javascript files need to be in a very specific order so I mix them by hand so to speak.

The cool thing is, you're not forced to stick with the file paths that Elixir comes with our of the box. I've used Elixir in several non-Laravel projects as well, I simply reset all the paths to whatever I want them to be with a config object and we're all good.

Very flexible and very cool!

Hope it helps =)

jjudge's avatar

Would NPM be "composer for node" while bower is "composer for your application"? (Like yum or apt-get vs composer?)

Looking at your gulp file, it makes a lot more sense to me. I need to know what those mix methods do, and that will be the key to understanding how to write my own.

Yes - all this stuff helps a lot. Keep bashing it into my head and it will stick. When it does, I'll do my best to pass it on.

secondman's avatar

I don't use bower so I can't really comment on it too much, it seems to be more like a sub-package manager, in order to install bower, you need to use NPM. Perhaps someone else can expand on it further.

NPM is the package manager for NodeJS, as Composer is a package manager for PHP.

npm install -g bower

composer require laravel/laravel

Same thing, different language.

--V

jjudge's avatar

composer is a package manager for PHP applications, rather than PHP itself, I guess, but I get what you mean :-)

So with bower (and I'm still new to this) I would issue something like this:

bower install datatables --save

That would be equivalent to a composer require to bring the datatables package in from the front-end equivalent to packagist, along with any further dependant packages that are needed. They would be dropped into a local bower_components directory (nearly equivalent to the vendor directory). These packages contain all sorts - source, tests, distributable code, sometimes extensions, docs, etc. The next step would be to pull the distributable code from those packages, maybe compiling in the process, and copying the result to the public directories of the project. That, I believe, is where gulp comes in with all its building functionality.

So you do all this without touching bower - I'm interested in how that works. Does bower perhaps just wrap npm? Do you fetch the source packages manually? Or does elixir actually run bower to get all the source packages without you even needing to know that?

davestewart's avatar

I'm a 70/30 front/back end dev, so I was interested to see what Elixir could do, but I couldn't get it running properly when I first tried it. After a couple of hours I got frustrated so just wrote a gulp file to be done with it.

Knowing Node and Gulp is a useful thing in itself, but I get what Elixir aims to achieve, especially when I suspect most people who use it will be far more comfortable with PHP than JS. At some point (when I have time) I will revisit, as I'm sure it's got loads of useful things in it (I just don't like black boxes).

You mentioned you wanted to know what was going on inside the gulp file? Well, here's my standalone gulp I've been using on my current Laravel project:

https://gist.github.com/davestewart/1a1d3c59c090928e1b38

Have a dig about, and see if that's any good to you.

You can run it with the following commands:

gulp
gulp build
gulp build --live

See the comments at the bottom to see the differences

jjudge's avatar

I say the bower_components directory is nearly equivalent to the vendor directory because it is not used at run-time, and so far as I know, does not need to be present on the production server at all. I think there is a lot of confusion about this out there, because I see so many projects on github that include bower_componentsin the front end with assets referenced directly from within that. Or maybe it's just me confused.

davestewart's avatar

Oh, and one last comment - using gulp, if you don't use any of the other tools, is worth it just to get livereload working. It makes immeasurably easier!

davestewart's avatar

I say the bower_components directory is nearly equivalent to the vendor directory because it is not used at run-time, and so far as I know, does not need to be present on the production server at all

It's up to you. Some people add it all in, but the best option would be to use Bower to manage the components outside of the root, then use Gulp to concatenate and minify them all into a vendor.js and vendor.css file.

The only other time you will need to copy stuff out will be if modules have additional assets they need to load, for example libraries like TinyMCE.

secondman's avatar

@consil

Bower isn't involved with Elixir at all. It has nothing to do with it and is not part of the node_modules directory when you pull in Elixir.

The hardest thing to wrap your head around with Elixir is file paths. Since it's been built for Laravel, it expects to find assets within specific directories that are native to Laravel ie: the resources directory.

But as I said, you can easily reset all your paths like so:

elixir.config.assetsPath      = '';
 elixir.config.publicPath      = '';
 elixir.config.css.folder      = '';
 elixir.config.css.sass.folder = '';
 elixir.config.js.folder       = '';

Now you can simply call full paths to your assets, or set up new ones to wherever you like.

It's pretty simple once you work with it for a minute.

davestewart's avatar

@consil - of course you can jump into the node_modules/elixir folder yourself and have a look at the source files. It should all be there, somewhere!

jjudge's avatar

One realisation I have come to, is that the front-end development is not like the back end.

When I need a tool or library in the back end, I generally install it using composer. I know where it lives, how to find the instructions on how to use it, maybe have a few additional (and well documented) steps to create a view or config file. But on the whole there are well-defined ways for the code to be structured and to simply work.

The front end feels like the Wild West by comparison. Tools such as gulp automate many steps needed to develop on the front end, and elixir helps to simplify that a lot by providing a handful of well-defined and common actions in a simple format that cover 99% of common use-cases. But beyond that, you need to source your own libraries (or use bower to make it somewhat easier), fathom out how they work, decide how they are going to be incorporated into your application front end, and how they will interact. You also need to work out how they will be merged and grouped to best effect on your application (you want to load as few assets as possible, but that does not necessarily mean lumping everything into one file because you may only need some sections of that on a small part of your site).

In short, you need to pretty much know what the end-game is as you set it up. My hope was for some simple steps to get bootstrap, datatables, and a few other features installed and ready to use in the standard place with little effort, and then expand on that. But that's not how it works - it's all pretty low-level file copying, merging, moving, compiling etc. albeit with some excellent tools to help.

And that's fine, now I know :-)

So I need to work out exactly what I want my front end assets, tools and libraries to look like, then kind of reverse-engineer that to the source packages and custom assets using elixir, bower and gulp. It's a different approach to the back-end PHP stuff, where you don't always know what the final product will look like, but you can start building it from the foundations upwards, even then.

Bear in mind my view is one from a mainly back-end developer who just wants some standard functionality to sit on the front end, to do pretty normal UI stuff with the user and administrator. So I don't have intimate knowledge of a dozen JS libraries at my fingertips, but instead just dip my toes in when I need to.

davestewart's avatar

Depending on the size of your site, you'll generally settle on a kit of parts that works, then once set up, you don't really need to think about it again.

I will generally have a minified vendor.js and a scripts.js file, that way the watch task on your user scripts doesn't have to constantly compile all your vendor code, and the vendor.js file generally remains the same for caching purposes.

But you are right - front and back end are very different. I am always suspicious of developers who label themselves as "full stack" these days. 10 years ago, you could be, but these days both disciplines are so complex that you need to be really experienced and up-to-date to justify that title; otherwise you're just a guy who does one side really well, but writes average or even terrible code on the other side, that guys like me (front end) or guys like you (back end) have to maintain. I've had jobs which have been an exercise in face-palming and explaining to PMs why this new feature that has been sold in to the client can't be reasonably achieved in the time and budget decided by someone further up the chain, because the architecture and current implementation blows.

jjudge's avatar

Totally understand and agree. I'm looking for two things here:

  1. The right way to set up a front-end framework (as in a way to structure the elements that make up the front end, not which JavaScript framework of the day to choose). I want there to be a place for everything and everything I need in its place, so a designer can finish the job off without any surprises.
  2. To install and configure enough front-end functionality to provide a decent enough user interface to perform the tasks the application is intended to support. The intention is to use tried and trusted libraries and packages with just a little glue, where possible. I can write the glue, but would not even dream about trying to reinvent any wheels here.

There was an interesting discussion on reddit the other day. A desktop developer decided he wanted to become a web developer, and ended up with a list of about 25 technologies that he understood he had to master to do this. He was shocked and was asking if he really had to know all that stuff. The answers came in from the full spectrum of use-cases, from no - just start with a few and do simple things, to yes, a full-stack developer needs to have an appreciation of all of them to know how to put an application together.

The truth, I think, lies somewhere in the middle. A single developer can put together an amazing application these days, as there are so many years of giant's shoulders to stand on (to mis-quote). I can create a searchable AJAX data table that references a model, provides privileges, decent security, and works across a range of browsers and devices, in no time at all. Maybe without the libraries and code developers before me have created, it would have taken a month, but it is just a few hours now. That doesn't mean it has not taken many years of personal experience to get here, but single-developer complex applications can be put together, and look and function in a pretty polished way. But it's tough. Cramming a brain with so many skills does not give you the time to shine in any of them. This is where teams with specialisations come in to their own. Collaborative working is pretty much a must if you are not already working in a larger organisation or team.

Anyway - I'm rambling now, as I often do. So to summarise - I write great back end, and need to be able to write average front end that the great front-end developer can pick up and run with, without wanting to kill me. That's why I'm here, and asking questions, and hopefully taking what I learn to others to learn from too :-)

jjudge's avatar

@davestewart on the practical side, keeping a bunch of front-end custom functions together, but organised a separate files, seems to be nice and easy using elixir. Elixir can then do the merging, compiling (sass/less) and minimising with some simple settings, and that keeps the front-end in the browser nice and clean and fast loading.

davestewart's avatar

Hey @consil - good ramble! Always nice to listen to other developer's thoughts. This post did the rounds a while ago and is extremely valid:

You know there's nothing wrong with setting up a site without concatenation and minification (for vendor files at least); some big sites do it. That way you know where everything is, it's easy to look at the source to see what libraries you're using, and easy to add functionality just by editing the HTML.

However, saving the requests is certainly a bonus, and the benefits of a build system and live reload in particular soon trump the learning curve.

I was developing on a big site for Sainsburys last year and we used Browserify, which was pretty great, although you had to get used to wrapping your JS with the module syntax. The way it works is by physically navigating all the require(some/lib.js) calls and concatenating the JS into one large file, then saving that as the bundle you require in the site. I haven't had a site that I've felt is complex enough that I've thought I've needed to go that way, but it's really neat. You have to handle CSS separately, of course.

With regards to "a place for everything" for small-medium sites I tend to put all my front end modules in public/vendor, each in their separate folders, then reference their vendor/package/dist files directly in the HTML. Usually there's only 5 - 10 libs, and they're cached after the first load, so I don't see it as particularly bad practice (but I'm possibly being a bit lazy!).

As mentioned, the other option would be to have all these managed by bower, and to list the dist files in your gulpfile.

Of course my user JS and CSS will all be stored above the root in multiple files and will be concatenated to assets/js and assets/css.

Looking back at the thread, I thought @vkronlein's answer was great, especially when using just Elixir. I might look back at that myself, as I had trouble getting Gulp running on even a simple project.

On a side note, and with regards to a place for everything, I have the following custom L5 setup, where I put all folders that I see as being strictly support within a parent folder:

/app
/public
/resources
/support
    /bootstrap
    /config
    /database
    /node_modules
    /packages
    /storage
    /temp
    /tests
    gulpfile.js
    ide_helper.php
    package.json
/vendor

I have to use a custom App class to set this up, but I find it much easier to work on sites as there's not a gazillion folders getting in my way.

You could also put bower_modules here, or even create a new top-level folder called build or such like and stick all your node, gulp and bower stuff in there:

/app
/build
    /bower_modules
    /node_modules
    gulpfile.js
    package.json
/public
/resources
/support
    /bootstrap
    /config
    /database
    /packages
    /storage
    /temp
    /tests
    ide_helper.php
/vendor

I could probably move more to the support folder if I wanted, but it's a good start!

mehany's avatar
What problem does elixir solve?

Simply what Jeffery showed in his example code. It will reduce the amount of lines needed to write gulp tasks and it will install a ton of gulp plugins that people normally manually install.

For clarity, here is an example code for a sass task in pure gulp

Gulp version

  var gulp = require('gulp'),
         sass = require('gulp-sass');

  gulp.task('sass', function () {  // initialize a task named "sass"
      gulp.src('/path/to/sass/directory/**/*.scss')  // specify the source directory or files
        .pipe(sourcemaps.init())  // generate a source mapfor the generated css file
        .pipe(sass().on('error', sass.logError)) // handle errors
       .pipe(sourcemaps.write('./')) // specify the place where the source map should be written in respect to the "destination " directory
       .pipe(gulp.dest('/destination/')); // specify the destination
 });

Elixir version

var elixir = require('laravel-elixir');
elixir(function(mix) {
    mix.sass([  // initialize a task named "sass"
        '**/*.scss',  // specify the source directory  or file
    ], 'public/assets/css'); // specify the destination
});

In the above example we saved 3 lines of code

now elixir will also generate the source map and handle the errors for you. Imo it is a great tool for anyone that does not want to bother with learning the manny different gulp plugins and how they should be ordered. I personally use Gulp before Elixir existed and I prefer using Plain Gulp tasks.

Please or to participate in this conversation.