Step by Step: Setting Up a Frontend Workflow for Magento 2

During the last Firegento Hackathon in Paderborn, I worked in a group that concentrated on the improvements in Magento 2’s frontend. Even though an extensive documentation is available, we had our troubles to get started. In order to make it easier to get started with frontend development in Magento 2 in the future, this post shows a step by step guide on how to set up a frontend workflow – and how to avoid possible stumbling blocks that we experienced at the hackathon.

This blog post will not inform about how the frontend mechanisms of Magento 2 work in particular. Instead, it’s supposed to be a help for frontend developers who are – like me – in a transition phase, and who are now asked to create a working initial state.

Since there are already different variants and pitfalls during the installation, I recommend to first read our blogpost about Magento 2 installation and do the installation accordingly.

Please remember to activate the Developer Mode. Magento 2 should never be run in the Default Mode, which is a hybrid mode that isn’t helpful to anyone really. For further information on modes, take a look at the documentation, or again visit Alan Storm’s blog.

We can now open our browser and take a look at the frontend with it’s shiny Luma theme.

Project’s General Structure

The installation type we chose – “Integrator/Packager” – has all the advantages of Composer. As it’s typical for Composer, all Magento modules are stored in

Your own modules or themes can be added in two ways:

  1. via composer in the vendor folder
  2. via the classic approach in the folders app/code and app/design respectively

Set up Grunt Environment

When the installation is finished, the next step is to setup the Grunt environment. All described steps are covered in the official Magento 2 documentation, although there it’s not as compactly summarised as it is here.

First of all, we need node.js for our stack.

Then we can install the Grunt CLI

followed by the initialisation of the project specific dependencies

To test if everything is correctly installed, use the following call:

Create Theme Files and use them in Magento 2

In Magento 2, themes are stored in the file system in the following pattern:


For a minimal setup, we create a theme which inherits everything from Luma. So we create the following files:

Two trivia we want to change right now, so that we can see right away that we no longer use the original Luma theme:

Then we select the theme in Magento 2’s backend:

Stores > Configuration > Design > Design Theme

Start the Frontend Workflow with Grunt

Before we can really get to work, we need to tell Grunt that we have just created a new theme. And here is the file entry that does the trick:

Afterwards, the following steps should be executed exactly once before starting to work:

  1. Clean static files and caches:
  2. Collect resources and generate static files for our theme:
  3. Initialise the preprocessing:
  4. Afterwards, reload the frontend page!

The first page view might lead to excessively long load times, since Magento 2 starts the preprocessing in the background which means that a great number of files need to be processed.

Voilà! We have successfully changed Magento’s background color and font color in the menu using our own workflow.
From now on, we can start the watch task:

If we change a LESS file, Grunt will automatically update all necessary files so we only have to reload the frontend (with the LiveReload browser plugin installed, you won’t even need to do that manually).

Questions regarding the Magento 2 Frontend Development

Getting started with the development of Magento 2’s frontend can raise many questions: Why have we changed this LESS file in particular? What kind of strange variables are those? What shall I do with all this now? Answering all these questions would go way beyond the scope of this blog post. If you have a concrete question, you are welcome to leave a comment and I’ll do my best to answer them or maybe even write another blog post.

We are all fairly new to working with Magento 2. The templating and preprocessing system, introduced by Magento 2, with its own LESS library is very complex. Even while writing these lines, I am still busy to grasp all background information and dependencies to the full extent. For a better start I highly recommend to study the official documentation.

There is also a documentation of the structure, content, coding standards, etc. of the frontend library, stored right inside the source files: lib/web/css/docs/source/

Trouble Shooting

Changing Files

In some cases (e.g. adding new files) it might be necessary to initialize everything again:

General “unidentified” problems

The following checklist should reset the system and make changes visible:

  1. Delete the static files relevant for the theme in:
  2. Delete the Magento caches (Backend, bin/magento CLI or n98-magerun2)
  3. bin/magento setup:static-content:deploy <lang_LANG>
  4. Start Grunt workflow


I would like to thank Maria Kern for her friendly adjustment of some missent thoughts.

Sandro Wagner

Autor: Sandro Wagner

As a trained media designer with a strong focus on frontend development and CMS integration, Sandro Wagner has worked for different leading web agencies and clients, both national and international.
At integer_net, he develops frontend designs for Magento stores, holding the corresponding Magento certificate.

This Post has 20 Comments

  1. Omar says:

    This is exactly what I needed after a week of trying to learn the new frontend workflow. Thank you for simplifying this. I look forward to your future posts.

  2. David says:

    Nice tutorial thank you, I’m having such a pain right trying to create my theme, as I need many css updates.
    This should be working on a remote server, right ?

    I’m having some trouble with grunt exec:mytheme

    >> PHP Parse error: syntax error, unexpected ‘class’ (T_CLASS), expecting identifier (T_STRING) or variable (T_VARIABLE) or ‘{‘ or ‘$’ in /var/www/vhosts/ on line 411
    >> Exited with code: 255.
    Warning: Task “exec:versantedition” failed. Used –force, continuing.

    It seems to explain why grunt watch does not see upload of modified files .. ?

    Any idea on how I could get this solved please ?

    • David says:

      Well, files like Magento_Theme/layout/default.xml now seem to update just fine, but not web/source/css/_theme.less

      • Instead of using _theme.less try another approach: create an _extend.less file in the same place and use it as a bootsrapping file, importing any liked less files. This way you only extend the default styles and can introduce kind of your own little structure.

    • David says:

      I think I know why I have this error, it’s because of my php CLI version, I could read that grunt exec was running

      php bin/magento dev:source-theme:deploy –type=less –locale=en_US –area=frontend –theme=Package/theme

      Where I need to run

      /opt/plesk/php/5.6/bin/php bin/magento dev:source-theme:deploy –type=less –locale=fr_FR –area=frontend –theme=Package/theme

      Any idea on how I could change this in grunt workflow ?

    • David says:

      Well, sorry for all these comments, but I tought I might give some feedback, as it could help others in my case.

      I solved this by changing dev/tools/grunt/configs/combo.js

      On line 19 I changed :

      command = command + ‘php bin/magento dev:source-theme:deploy ‘


      command = command + ‘/opt/plesk/php/5.6/bin/php bin/magento dev:source-theme:deploy ‘

    • Sorry, it’s hard to say remote. But in many cases I would guess on common issues with cached files or env setup in general. Also check your Magento operating mode. The default is neither “developer” nor “production” and may produce weird behaviour. On remote systems you may consider using production mode and have your static files generated on deploy.

      One important note: NEVER EVER edit Magento core files. Only exception for Grunt workflow would be themes.js. If have have to hard code things like you did with your php binary then definitely something is odd about your environment.

      • David says:

        Thanks for the reply. I know I should not have modified that file, but it’s my only solution and how I finally made it work. Problem is that I am on a centos 6 server running plesk 12.5 which is shipped with php 5.3 or 5.5. Plesk supports multiple versions of php, but the CLI when using command lines is the vendor php version.
        I think there is also a solution to change the php CLI for ssh by changing bashrc file on server (alias php=”…”), should be a better solution.. ? I will try it out to be able to leave magento core files untouched.
        Thanks again for this tutorial that was really helpfull.
        Moving from Magento 1 to Magento 2 is quite confusing.

  3. Roy says:

    Thanks for your clear tutorial, this provided the information I needed to get started on setting up a frontend workflow!

    Note for the readers of this tutorial: don’t forget to copy or rename your package.json.sample to package.json and your Gulpfile.js.sample to Gulpfile.js!

  4. David says:

    Thanks again for this tutorial, really helping !
    What would be the best process for multi languages websites please ?

    defines the locale, so I changed it to be able to refresh css for each store view.
    But the process is quite heavy.

    If I put the code 3 times with different locale infos, grunt only takes the last one as the theme name is the same.

    Is there any way grunt can watch and updtae my 3 languages at once ?

    Best regards,

    • Unfortunately not. This is IMHO a major flaw of the Magento 2 concept. To handle your localisations you will have to do the following:

      Create a corresponding object in your theme.js for each loale, for example:

      Then you have to compile each one separately:

      Once initially compiled, watch task could do the job, but I did not use localisation intensively yet. Would have to check it myself.

Leave a comment