Access Employees

EmbeddedSass.Net: Sass Integrated with MSBuild for .NET Projects

Published in by Gustavo Mauricio de Barros

EmbeddedSass.Net: Sass Integrated with MSBuild for .NET Projects EmbeddedSass.Net: Sass Integrated with MSBuild for .NET Projects

Why Use Sass

Plain CSS is sufficient for small projects, but it can become repetitive and difficult to organize as an application grows. Colors, spacing values, breakpoints, and component rules often end up duplicated across multiple files, making simple changes more time-consuming than they should be.

Sass makes organizing your project much easier. It provides features such as variables and functions, making the code more structured and reusable. Sass is ultimately converted into standard CSS that browsers can interpret normally, while the source code remains cleaner, better organized, and easier to maintain.

Another major advantage, in my opinion, is the ability to keep separate files for each module in your system while producing a single minified output file, without having to declare multiple CSS links in the browser.

$primary-color: #6750a4;
$spacing: 1rem;

.button {
  padding: $spacing;
  background: $primary-color;

  &:hover {
    opacity: 0.9;
  }
}

A major pain point for developers who are not part of the JavaScript ecosystem is having to create and maintain a separate pipeline solely to compile .scss files. In many projects, this means installing Node.js, adding configuration files, and creating specific CI/CD steps.

That is why I created EmbeddedSass.Net. Its purpose is to bring Sass compilation closer to the tools that are already part of .NET development. Several libraries are already available, such as AspNetCore.SassCompiler, but at the time this article was written, none of them implemented the Embedded Sass Protocol.

What Is EmbeddedSass.Net?

EmbeddedSass.Net is a .NET implementation of the Embedded Sass Protocol.

The Embedded Sass Protocol defines bidirectional communication between the Sass compiler and a host language. The host requests compilations from Dart Sass and can provide features such as importers, custom functions, and dependency resolution.

This communication uses structured messages, which are typically exchanged with the compiler running as a separate process. This allows the host to use the official compiler without having to reimplement the Sass language.

In practice, EmbeddedSass.Net implements this protocol for the .NET ecosystem, allowing Sass compilation to be controlled through APIs and tools familiar to C# developers. This enables both build integrations and more customized use cases within applications and development tools.

The protocol specification is available at this link. One particularly interesting detail is that it provides a .proto file that can be used by any programming language to generate the communication classes.

Sass Integrated with MSBuild

Another major advantage of the library is the EmbeddedSass.Net.MsBuild package.

<ItemGroup>
  <PackageReference Include="EmbeddedSass.Net.MsBuild"
                    PrivateAssets="all" />
</ItemGroup>

This library compiles Sass files before ASP.NET Core processes the static web assets. It also includes the required compiler, so Sass does not need to be installed separately on the development machine or in the build environment.

Compilation becomes part of the project’s standard commands:

dotnet build
dotnet publish

As a result, your CI/CD pipeline does not need to install anything from the well-known npm dependency hell. For teams that already use MSBuild and the .NET SDK commands, there is no need to introduce an additional step solely to prepare CSS files.

Build-Time Compilation

By default, the library searches for .scss and .sass files inside the Sass directory. The goal is to provide a simple initial configuration that works without requiring multiple project properties.

Sass/
├── _variables.scss
├── _buttons.scss
└── site.scss

Files whose names begin with _ are treated as partials and do not generate individual CSS files. They can be imported or used by other Sass files responsible for producing the final output.

For example, the site.scss file is compiled to:

wwwroot/css/site.css

In Debug builds, the integration generates expanded CSS and source maps, making the output easier to read and debug in the browser. In other configurations, such as Release, it generates compressed CSS without source maps by default, reducing the size of the published files.

The input directories, output paths, and load paths can also be customized directly in the .csproj file. This allows the default convention to be adapted to the project’s existing structure.

Runtime Compilation

EmbeddedSass.Net can also compile Sass while the application is running. This feature is useful for generating dynamic themes or CSS based on settings stored in a database.


using EmbeddedSass;
using EmbeddedSass.Compiler;

var options = new SassCompilerOptions()
    .UseBundledDartSass();

await using var compiler = new SassCompiler(options);

var result = await compiler.CompileStringAsync("""
    $primary-color: #6750a4;

    .button {
        background: $primary-color;
    }
    """);

Console.WriteLine(result.Css);

The generated CSS is available through the Css property and can be saved to a file, stored in a cache, or returned directly by an endpoint.

This mode is recommended when the styles depend on data that is only available at runtime. For static files, the MSBuild integration remains the simpler option.

Benchmarks

In the benchmarks performed, EmbeddedSass.Net achieved a compilation time that was 91.8% lower than AspNetCore.SassCompiler and 98.9% lower than DartSassHost. It was approximately 12 times and 87 times faster, respectively, than the other solutions available on the market.

When to Use It

EmbeddedSass.Net.MsBuild is especially useful for ASP.NET Core projects that serve static files directly.

It is also a suitable option for libraries and applications whose development and publishing environments already depend on the .NET SDK. One example is JJMasterData, which uses EmbeddedSass.Net to compile its styles into a single jjmasterdata.css file.

Conclusion

The source code, documentation, and examples are available on GitHub. Do not forget to leave a star ⭐:

github.com/gumbarros/embeddedsass.net

More articles from this author

Polymorphism in EF Core

Published in

Polymorphism in EF Core with Star Wars droids: Learn how to model and query polymorphic entities using TPH, TPT, and TPC strategies with practical C# examples inspired by Star Wars droids for efficient and maintainable database design.

READ MORE
← Return to start