# Simplifying Asset Compilation with Laravel Mix

> Laravel Mix provides a fluent API that lets you compile JavaScript and CSS assets without writing Webpack configuration from scratch.

- Published: 2017-05-07
- Category: Tools & Technologies
- Tags: Laravel
- Reading time: 3 min read
- Source: https://www.muhammetsafak.com.tr/en/blog/simplifying-asset-compilation-with-laravel-mix/
- Language: en-US
- Author: Muhammet Şafak

---
Most people who try to learn Webpack hit the same wall: the config file. Loaders, plugins, resolve rules — everything is configurable, but the price of that flexibility can be a `webpack.config.js` that eats hours on every new project. Laravel Mix exists to make that complexity invisible.

**Laravel Mix** is a tool built on top of [Webpack](/en/blog/migrating-to-webpack-from-gulp-to-module-bundling/) that exposes a fluent API. It was developed by Jeffrey Way for the Laravel ecosystem, but it has no hard Laravel dependency — you can use it in any Node.js project. In January 2017 it became the default asset compilation tool shipped with Laravel 5.4.

## Installation

If you are starting from a Laravel 5.4 project, Mix is already listed in `package.json`. Install everything with:

```bash
npm install
```

That is all. Webpack and all its dependencies come along for the ride.

## webpack.mix.js

Configuration lives in `webpack.mix.js`. The minimal setup looks like this:

```javascript
const mix = require('laravel-mix');

mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css');
```

Those two lines do a lot: `app.js` gets bundled with Webpack and written to `public/js/app.js`; `app.scss` gets compiled through the Sass (SCSS) compiler and written to `public/css/app.css`. Vendor prefixes for CSS are added automatically.

## Development and production modes

`package.json` ships with ready-made scripts:

```bash
npm run dev      # Compile for development
npm run watch    # Watch files and recompile on change
npm run production  # Minified, production-ready build
```

Running `npm run production` minifies the output files. Mix makes cache busting easy: call `mix.version()` and it appends a content hash to each filename.

`npm run watch` is invaluable during the development loop. Save a SCSS file and Mix recompiles immediately, sparing you the chore of triggering Webpack by hand on every change.

## Versioning

```javascript
mix.js('resources/assets/js/app.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .version();
```

In your Blade templates, the `mix()` helper resolves the correct versioned URL:

```blade
<script src="{{ mix('js/app.js') }}"></script>
<link rel="stylesheet" href="{{ mix('css/app.css') }}">
```

With this in place, browsers always fetch the latest file on each deployment — stale-cache problems disappear.

Behind the scenes, `mix()` reads `public/mix-manifest.json`, a file Mix regenerates on every build. It maps each logical asset path to its hashed filename. You always write `mix('js/app.js')` in your templates; Mix figures out the real URL.

## Vue single-file components

Compiling `.vue` components requires no extra configuration — Mix supports them out of the box:

```javascript
mix.js('resources/assets/js/app.js', 'public/js');
// .vue components can be imported inside app.js
```

Vue loader setup and Babel transpiling — both handled behind the scenes.

This is where Mix genuinely shines. Compiling `.vue` files with raw Webpack would require configuring `vue-loader`, `vue-template-compiler`, and Babel. Mix collapses all of that into a single line. When I decide to use Vue in a new project, I no longer need to touch any configuration.

## Multiple output files

Mix is not limited to a single entry point. You can produce separate bundles for different pages:

```javascript
mix.js('resources/assets/js/app.js', 'public/js')
   .js('resources/assets/js/admin.js', 'public/js')
   .sass('resources/assets/sass/app.scss', 'public/css')
   .sass('resources/assets/sass/admin.scss', 'public/css');
```

Keeping the admin panel JavaScript separate from the public-facing bundle means regular users never download admin code they will never use. Mix makes this split easy; there was no need to write separate Webpack configurations.

## Browsersync

To auto-refresh the browser during development:

```javascript
mix.browserSync('myapp.test');
```

This reloads the browser whenever a file changes. Paired with [Laravel Homestead](/en/blog/consistent-dev-environment-with-laravel-homestead/), it noticeably tightens the development loop.

## Direct comparison with raw Webpack

Because Mix abstracts everything, you rarely need to open `webpack.config.js`. When you do need to reach through the abstraction, `mix.webpackConfig({})` lets you merge directly into the underlying Webpack configuration. Full control is available whenever you need it.

In practice, I have never needed to go beyond "compile SCSS and bundle JS" on any project I have worked on. Mix handles that scenario with room to spare, and the time I would have spent reading Webpack documentation goes toward the actual work instead.
