Rush StackShopBlogEvents

Sass plugin

Plugin package:@rushstack/heft-sass-plugin
Plugin name:sass-plugin implemented by SassPlugin.ts
Plugin config file:sass.json
heft.json options:(none)

This plugin generates TypeScript typings for CSS styles. It supports three different stylesheet formats:

When to use it

We recommend using Sass for any TypeScript web application that uses CSS styles. The .scss file format is the recommended choice because its syntax is a proper superset of plain CSS.

How it works

Suppose your CSS styles are defined in a file like this:


$marginValue: 20px;

.label {
margin-bottom: $marginValue;

Before Heft invokes the TypeScript compiler, the sass-plugin can generate a temporary file containing type declarations:


// This file was generated by a tool. Modifying it will produce unexpected behavior
export interface IExportStyles {
label: string;
declare const strings: IExportStyles;
export default strings;

This enables the styles.label style to be imported like this:


import * as React from 'react';
import styles from './my-styles.scss';

export class ExampleApp extends React.Component {
public render(): React.ReactNode {
return <p className={styles.label}>Example text</p>;

The typical approach used by toolchains such as create-react-app will produce an untyped styles object. This can be error-prone. Heft's generated .d.ts file provides full IntelliSense for style names, and enables the compiler to catch common mistakes such as misspelled identifiers.

The .d.ts file is generated using @rushstack/typings-generator. You can reuse this library to implement custom Heft plugins that generate typings for other resources besides CSS.

The sass-plugin will automatically generate typings for any files under the src folder with supported file extension (.css, .scss, and .sass). Its behavior can be customized using the sass.json config file, but in most cases the default behavior is sufficient.

The build-tests/heft-sass-test project provides examples of .css, .scss, and .sass imports.

package.json dependencies

If you are using @rushstack/heft-web-rig, then Sass will already be loaded and configured.

Otherwise, you'll need to add the plugin package to your project:

# If you are using Rush, run this shell command in your project folder:
rush add --package @rushstack/heft-sass-plugin --dev

Because the plugin only generates TypeScript typings, your project will need additional configuration to invoke the Sass processor for transpiling styles. The specifics depend on your bundling configuration. For a complete example using Webpack, take a look at the heft-web-rig project folder.


If Sass is not already being provided by a rig, your heft.json config file might invoke it like in this example:

<project folder>/config/heft.json

"$schema": "",

. . .
"phasesByName": {
"build": {
"cleanFiles": [
{ "sourcePath": "dist" },
{ "sourcePath": "lib" },
{ "sourcePath": "lib-amd" },
{ "sourcePath": "lib-commonjs" },
{ "sourcePath": "lib-es6" }
"tasksByName": {
"sass": {
"taskPlugin": {
"pluginPackage": "@rushstack/heft-sass-plugin"
"typescript": {
"taskDependencies": ["sass"],
"taskPlugin": {
"pluginPackage": "@rushstack/heft-typescript-plugin"
"webpack": {
"taskDependencies": ["typescript"],
"taskPlugin": {
"pluginPackage": "@rushstack/heft-webpack5-plugin"
. . .

Reference the generated typings by adding temp/sass-ts to the rootDirs setting in your compiler configuration:


"$schema": "",

"compilerOptions": {
"rootDirs": ["src/", "temp/sass-ts/"],
. . .

Make sure that the staticAssetsToCopy setting your typescript.json file is configured to copy the .css, .scss, and .sass file extensions.

See also