Set up & configure Grunt for Magento 2 theming
Getting your developing tooling is important for efficient Magento 2 theming, and a crucial part of that process is setting up & configuring Grunt for LESS & CSS compilation.
What is Grunt?
Grunt is an automator that performs repetitive tasks for you such as minifcation, compilation, unit testing, linting, etc. It is similar to a lot of other tools out there such as Gulp, Webpack & Vite.
Normally when you write CSS, a task runner is not needed. But Magento uses Less, which extends CSS to add support for variables, mixins, nesting, math operations, functions & more.
Before continuing, if you are using docker-magento, all of these steps have already been taken care of for you! All you need to do is run
bin/setup-grunt, and the installation & configuration of Grunt is magically done for you.
You can skip ahead to the Run Grunt commands section if you wish, just remember to prefix grunt with
bin/ to use Grunt within the Docker container. But if you’d like to know how the Grunt setup works, just keep following along.
Assuming we already have Node.js installed on our machine, we can install the
grunt command line globally with:
npm install -g grunt-cli
Before running grunt, we’ll also need to install some prerequisite packages. Magento comes with a few files in the root of your project:
We’ll need to copy all of these files to the same locations, but without the
cp package.json.sample package.json
cp Gruntfile.js.sample Gruntfile.js
cp grunt-config.js.sample grunt-config.js
After doing so, all NPM dependencies can be installed with:
This looks at the
package.json file that we just created, and installs all dependencies in that file.
Configure Grunt for Magento
Grunt works from a
Gruntfile, which is basically a configuration file that contains a function with a list of instructions that Grunt executes. If we take a look at this file in the root of our Magento folder, we’ll see that it contains a lot of configuration and tooling to get it working with Magento.
Now let’s open up the
grunt-config.js file. This file defines the location to look for to find the theme configuration file.
Notice that it is set to:
This value is just fine, but we need to create this file. We’ll do that by going to the
dev/tools/grunt/configs directory. This directory contains files that will define all core Magento tasks that Grunt will execute.
We’ll go ahead and create that
local-themes file. Let's do that by copying the
themes.js file in this directory over to
local-themes.js. This safesguards any changes we make, so they don’t get overridden by core updates.
Run Grunt commands
At this point, Grunt can be executed. We can do this by running
grunt from the command line. If you are running
docker-magento, be sure to prefix the command with a
When you run this command, it executes the function exported from the
Gruntfile, which isn’t particularly useful at the moment.
Let’s go back to the
dev/tools/grunt/configs folder, and we’ll see some other files in here such as
exec, and so on. Each of these files exports a function that is executed when the related name is passed to
Here is a list of common Grunt actions that are used in Magento frontend development, and when to use each:
|Removes all theme related static files in the
|Runs grunt clean, but also creates symlinks and all related directories for Less source files within the
var/view_preprocessed directories. You can also use
grunt exec:<theme> to do this only for a specific theme.
|Compiles Less files into CSS files using the symlinks that were generated from the
grunt exec command. You can also use
grunt less:<theme> to do this only for a specific theme.
|Tracks the changes in the source files, recompiles CSS files, and reloads the page in the browser.
clean.js to look at an example. This file loads the themes, which for us comes from that
local-themes.js file, and sets some config values for each theme.
It then defines some more configuration that tells Grunt what to do for each of these themes.
This command essentially purges all view caches in Magento, for each of those defined themes. Pretty neat, right?
Now, let's run:
This command will take quite a bit longer to run, and that’s because besides running the clean command for each theme, it also compiles all of the related styles for each Magento theme. There’s a lot of magic going on behind the scenes that we’ll get to later.
We can also execute tasks for a specific theme by typing a colon, followed by the name of the theme, such as:
This will execute the grunt tasks, but only for the Luma theme.
If you wish to have Grunt automatically listen for changes to execute upon, you can do so with the
watch command, which can be ran with:
Rather than making a stylesheet update and running
grunt exec every time you update a file, you can have the Grunt script, standing by, watching for filesystem changes. When a file changes, Grunt will automatically run the related
exec command, and just for that specific file. This makes styling way quicker and takes away some of the development burden when compiling styles.
Thrilled to level up in Magento? Explore these 3 options: