How do I setup for theme development?

So I’ve been looking into Quark and searching a lot, but can’t find or figure out the definitive answer. I wouldn’t want to do something and then realize it should’ve been done a different way.

Lets say I’d like to use Spectre CSS. Do I download all repo to /user/themes/myTheme/scss? But that doesn’t seem right, because, according to docs, all compiled CSS goes to /dist folder. And then I’d want to customize by changing variables. So I guess the more correct way would be something like Quark has /scss/spectre and /scss/theme, but then again - how do I set up the build and watch processes?

I’m not planning on publishing the theme - it’ll be purely customized theme for my personal website. How do I set up everything to make development as easy as possible?

I’m not new to backend or front-end, but I always struggle setting up the environment to develop :frowning: Thanks for any advices

So I guess the more correct way would be something like Quark has /scss/spectre and /scss/theme , but then again - how do I set up the build and watch processes?

Install sass/scss

Setup the build/watch process

scss --sourcemap=auto --watch ../workspace/scss:../workspace/css

ps: …/workspace is your relative path to css/scss

It’s not always had to be like this. If you use Gantry5 plugins, they ship with scss processor (leafo).

@Karmalakas, I’m a Bootstrap user, but out of curiosity I had a look at Spectre’s website about customisation.

My setup would be as follows.


  • Install nodejs + npm if not already
  • In your themes folder create folder /build
  • Copy package.json from Spectre’s repo into the /build folder.
    • Inside package.json rename the package from ‘spectre.css’ to ‘my-theme’.
      If not, you will get an npm error in the next step.
  • Inside the /build folder, run $ npm install -save-dev spectre.css
    This will install everything from Spectre into folder build/node_modules/spectre.css
  • Create folder /build/src.
  • Inside /build/src create files _spectre.scss, _variables.scss and style.scss:
    • _spectre.scss:
      Copy content from node_modules/spectre.css/src/spectre.scss
      • Append to all @import statements ‘node_modules/spectre.css/src/’, like @import "node_modules/spectre.css/src/variables";
      • You can comment out any module you do not need in your theme
    • _variables.scss:
      Contains some variable to override the default variables from Spectre, defined in node_modules.spectre.css/src/_variables.scss
    • style.scss:
      Imports files _spectre.scss and _variables.scss and contains the styling of your theme.
      @import "variables";
      @import "spectre.scss";
      // You themes styling goes here
  • Copy /node_modules/spectre.css/gulpfile.js into /build
    • Replace line 18: .pipe(gulp.dest('./dist')) with .pipe(gulp.dest('../css'))
    • Replace line 23, .pipe(gulp.dest('./dist')); with .pipe(gulp.dest('../css'));
  • Inside folder /build, run $ npx gulp build
    The resulting css files will be in the toplevel folder /css
  • In your themes template base.html.twig use {% do assets.addCss('theme://css/style.min.css') %} to load stylesheet that combines Spectre styles + your style. No other Spectre css files needs to be loaded.

That should be it…

Resulting folder structure:
(only css related files shown)

├── build
│   ├── gulpfile.js
│   ├── package-lock.json
│   ├── package.json
│   └── src
│       ├── _spectre.scss
│       ├── _variables.scss
│       └── style.scss
└── css  <-- contains result of build process
    ├── style.css
    └── style.min.css

Updating Spectre:
When a new version of Spectre arrives, you can run $ npm update to update to the latest packages.
You then might want to check if the new package.json, gulpfile.js, spectre.scss and _variables.scss in /node_modules/spectre.css has some changes you want to copy.

I would create the development folder for my themes/plugins separate from Gravs installation folder and use symlinks to Grav and themes/plugins. This way you can easily update Grav and create folders for each site/theme/plugin you are working on.


  • Inside a fresh Grav installation run bin/grav new-project -s ../site-dev
    This will create folder site-dev which contains symlinks to folders inside the Grav installation.
  • Inside site-dev/user/themes create a symlink to the theme’s folder.
  • Instead of using localhost/grav-admin you would now use localhost/site-dev

Resulting folder structure:

├── grav-admin
├── site-dev
│   └── user/themes/my-theme  <-- symlink to `/themes/my-theme`
├── site-client1
├── site-client2
├── themes
│   ├── my-theme
│   └── other-theme
└── plugins
    ├── my-plugin
    └── other-plugin

Thanks for you both :slight_smile: It still sounds a bit confusing to me and I guess I’ll have to get back to this when I have my page already running (it’s now a priority for me to have a page running and how it looks - second). I guess I’ll stick with CDN Bootstrap for now.

Grav is actually so flexible and easy to start, I would’ve thought it could have package.json and gulp stuff out of the box when creating a new theme. Then you jsut put scss/less files to specified folder and run command to build/watch. Then just add compiled files to your template.

Also it’s a bit weird that themes can’t really share some lib. Or at least I didn’t figure this one out. Anyway… :slight_smile:

Thank you again and I’ll get back to this at some point in the future when I have my page up and running with pure Bootstrap (chose this as I’m already more familiar with it)


In your initial post you mentioned you wanted to be able to change the variables of Spectre, in which case you will have to recompile the Spectre code using the Sass compiler.

Btw, the approach I’ve shown goes with Bootstrap as well. You might want to start with Bootstrap 5, which is in beta right now.

The following approach is much simpler:

If you want to use standard Bootstrap, you could do the following simpler setup:

  • Load Bootstrap css + js from CDN in base.html.twig
  • Create file ‘/themes/mytheme/css/custom.css’
    This is where you can add css to override standard Bootstrap styling
  • Load custom css in base.html.twig using:
    {% do assets.addCss('theme://css/custom.css') %}

With SCSS:
You will need to download the Sass compiler as mentioned by @tacoen. The simplest way is to download the standalone version for your OS.
Then compile the scss into the custom.css which will then be loaded as shown above.

Yes, Spectre was just as an example. I understand with Bootstrap is pretty much the same. I did almost exactly as you suggest with CDN version for now and will play with compiler after I have all the pure Bootstrap templates and content in place :slight_smile: Thanks :wink:

It appears PHP Storm already has all that’s needed to compile SCSS in File Watchers :slight_smile: I think I’ll stick to that. Thanks for you both still - I’ve learned some stuff I didn’t know before :slight_smile:

@Karmalakas, That’s a bit surprising because according the docs of PHP Storm on the use of SCSS you still need to install the sass compiler: npm install -g sass

I don’t have PHP Storm so maybe I’m mistaken…

Hmm… Maybe I did some time ago. I checked and you might be right, app points to /AppData/Roaming/npm/… on my PC. Storm probably detected it automatically, because I just installed trial a few days ago and definitely didn’t change any settings for npm. But still, with Storm there’s no need to run separate watcher or have gulpfile.js and package.json just for that purpose :slight_smile:

@Karmalakas, When you want to adapt Bootstrap or Spectre (eg. their variables as you mentioned in your first post), there is more to it then only watching and compiling scss files:

  • Compiling scss
  • Prefixing to adapt generated css to multiple browsers
  • Removing unused css
  • Minifying css to create *.min.css

For this ‘workflow’, Bootstrap uses npm scripts in its package.json file and Spectre uses gulp.

Only if you are using css from Bootstrap/Spectre loaded from a CDN, and only use scss for some css overriding the default css loaded by the Bootstrap libs, you might be fine with only compiling your on own scss file.

But even so…, the steps mentioned above should also apply to your own code…

Is this still a thing? :open_mouth:

Minifying is also available as watcher in Storm. I’m more a UI guy :smiley: I use command line only if really necessary :sweat_smile: Probably that’s why I find Storm more friendly to achieve what I need in this case :slight_smile:

And what do you mean by unused CSS?


Yes, prefixing is still a thing. Have a look at the package.json of Bootstrap and/or Spectre… They both include ‘autoprefixer’ resp. ‘gulp-autoprefixer’.

Minifiers have many options. And css frameworks may have their specific requirements.

Bootstrap for example uses:

cleancss -O1 --format breakWith=lf --source-map --source-map-inline-sources [stuff deleted]

Try Google on remove unused css

Well… It seems I might need to get back to this after all :slight_smile: But for now I’ll leave it as it is and it works for me (for now at least)

Thank you for your insight as always :wink: