Svelte / Sapper with Sass!

The Svelte-based web framework Sapper gives us a lot out of the box. Declarative routing, free SSR for every route, baked in support for API routes, and so much more. But if you want to use Sass or Stylus or another preprocessor, you’re on your own. 😕

Image for post
Image for post

There are 3 things we want to do…

  • Parse Sass within <style lang="scss"> tags.
  • Apply a global theme to the entire site and make variables/mixins available everywhere.
  • Get VS Code syntax highlighting support for Sass in .svelte files.

1. Parse <style lang="scss"> tags

First, we need to add a couple NPM modules:

Now modify rollup.config.js to apply the preprocessing:

Import sveltePreprocess

import sveltePreprocess from 'svelte-preprocess';

Setup the preprocessing function

Set it up once near the top of the file so that it can be referenced from both client and server blocks.

Call preprocess from both the client and server blocks

Adding one line inside both blocks:

So now, if you add lang=scssto your style tags within a svelte component, it should happily parse as Sass.

Remember to add lang=”scss” to style tags!

2. Make a global theme and variables/mixins

I like to create a src/styles/ directory with global.scss and theme.scss. The theme.scss will contain variables and mixins which can be imported and used site-wide. The global.scss will also import theme.scss and will use some of those settings to set up the basic layout for the site.

💡 Svelte doesn’t have a good way of creating a truly global scss file that gets used everywhere by default. So don’t bother with setting up a postcss plugin for rollup to try to generate css bundles for you. It’s possible but doesn’t work very well because your variables and mixins won’t be available to your components at all — which kinda ruins one of the big advantages of using Sass in the first place.

Add this to your src/ directory:


* {
box-sizing: border-box;
html, body {
margin: 0;
padding: 0;



Now to apply those, we’ll import global into _layout.svelte like this:

💡 Notice that we added the lang attribute for Sass parsing and also the globalkeyword so these styles will be applied globally.

To use variable/mixins, we can import theme.scss into any Svelte component like this:

3. Fix VS Code syntax

To get VS Code to stop highlighting all the “errors” in your style tags, we need to use the VS Code Svelte extension and tell it to parse SCSS within those tags. So first, install the “Svelte” extension from within VS Code.

Next, create a svelte.config.js at top level of project with:

module.exports = {
preprocess: sveltePreprocess({
scss: {
includePaths: ['src'],
postcss: {
plugins: [require('autoprefixer')],

You may also need to tell the Svelte extension the path to Node. If so, just open VS Code > Preferences > Settings and search for “svelte”. Right at the top, you should see: “Svelte > Language-server: Runtime”. You need to supply your Node path there. To get it, pop open a terminal and type which node, then copy/paste that path there. Mine is: /usr/local/bin/node but yours might be different.

If it still highlights valid SCSS as invalid even after closing and reopening the file, you might try making sure that VS Code also has the “SCSS Style Tag” extension installed.


Yes, it feels like all this work shouldn’t be necessary for something as basic as CSS preprocessing. But the good news is that you probably only need to do it once because you can save this stuff and use it as your boilerplate for the next project. For everything Svelte and Sapper give to us developers, it’s worth it. But it sure would be nice if it were a little easier. ;-)

Written by

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store