BootstrapEmail.Net
2.0.0
dotnet add package BootstrapEmail.Net --version 2.0.0
NuGet\Install-Package BootstrapEmail.Net -Version 2.0.0
<PackageReference Include="BootstrapEmail.Net" Version="2.0.0" />
<PackageVersion Include="BootstrapEmail.Net" Version="2.0.0" />
<PackageReference Include="BootstrapEmail.Net" />
paket add BootstrapEmail.Net --version 2.0.0
#r "nuget: BootstrapEmail.Net, 2.0.0"
#:package BootstrapEmail.Net@2.0.0
#addin nuget:?package=BootstrapEmail.Net&version=2.0.0
#tool nuget:?package=BootstrapEmail.Net&version=2.0.0
BootstrapEmail.NET

If you know Bootstrap, you know Bootstrap Email.
BootstrapEmail.NET is the .NET version of Bootstrap Email, converted from Ruby. Write emails with the Bootstrap classes you already know, and it compiles them into the table-based HTML with inline styles that email clients need.
For example, this button:
<a href="https://example.com" class="btn btn-primary">Confirm</a>
compiles to this (some styles shortened):
<table class="btn btn-primary" role="presentation" border="0" cellpadding="0" cellspacing="0" style="border-radius: 6px; ...">
<tbody>
<tr>
<td align="center" bgcolor="#0d6efd" style="border-radius: 6px; ...">
<a href="https://example.com" style="background-color: #0D6EFD; color: #FFFFFF; ...">Confirm</a>
</td>
</tr>
</tbody>
</table>
See the Bootstrap Email documentation for the available components and utilities.
Contents
- Requirements
- Use the library
- Use the command line
- Configuration
- Custom styles
- Files created at runtime
- Upgrading to 2.0
- Development
- License
Requirements
- .NET 9 or .NET 10
- Any operating system supported by .NET. No Dart Sass binary or other native runtime is needed.
Use the library
Install the package:
dotnet add package BootstrapEmail.Net
Compile a string and get the HTML back:
using BootstrapEmail.Net;
var bsEmail = new BootstrapEmailCompiler();
var html = bsEmail.Compile(
"<a href='#' class='btn btn-primary'>Some Button</a>",
string.Empty,
InputType.String);
The other input types write to files and return an empty string:
// Compile email.html and save it to out.html
bsEmail.Compile("email.html", "out.html", InputType.File);
// Compile email.html and save it to compiled/email.html
bsEmail.Compile("email.html", string.Empty, InputType.File);
// Compile all .html files in the current directory and save them to compiled/
bsEmail.Compile(string.Empty, string.Empty, InputType.File);
// Compile the files matching a pattern and save them to a directory
bsEmail.Compile("emails/*", "emails/compiled", InputType.Pattern);
To change the defaults, pass a ConfigStore:
var bsEmail = new BootstrapEmailCompiler(new ConfigStore { CompileOnlyBody = true });
Use the command line
The CLI is a .NET tool that installs the bootstrap-email command:
dotnet tool install --global BootstrapEmail.Net.Cli
To update it, run dotnet tool update --global BootstrapEmail.Net.Cli.
| Option | Long form | Description |
|---|---|---|
-f |
--file |
File to compile. Saved to compiled/ next to the file, unless --destination is set. |
-s |
--string |
HTML string to compile. The result is written to the console. |
-p |
--pattern |
Pattern of files to compile, relative to the current directory. Requires --destination. |
-d |
--destination |
Output file for --file, or output directory for --pattern. |
-t |
--text |
Return the plain text version of the email. |
-c |
--config |
Path to a JSON configuration file. |
-v |
--version |
Show the version. |
-h |
--help |
Show the help. |
Without any input option, it compiles the HTML piped to it and writes the result to the console. If nothing is piped, it compiles all .html files in the current directory and saves them to compiled/:
cat input.html | bootstrap-email
bootstrap-email
Compile one file:
bootstrap-email -f email.html -d out.html
Compile the files matching a pattern. Quote the pattern so that your shell doesn't expand it:
bootstrap-email -p 'emails/*' -d emails/compiled
Compile a string:
bootstrap-email -s '<a href="#" class="btn btn-primary">Some Button</a>'
Save the plain text version of an email:
bootstrap-email -t -f email.html -d email.txt
Use a configuration file:
bootstrap-email -c bootstrap-email.json -f email.html
Configuration
The library takes these settings as ConfigStore properties, and the CLI reads them from a JSON file with the same names:
{
"sass_email_location": "styles",
"sass_email_string": "my-email.scss",
"sass_log_enabled": true
}
| Setting | Default | Description |
|---|---|---|
sass_email_string |
bootstrap-email.scss |
File name of the Sass file for the inlined styles. |
sass_email_location |
Directory of that file. Defaults to sass_location. |
|
sass_head_string |
bootstrap-head.scss |
File name of the Sass file for the styles in the <head>. |
sass_head_location |
Directory of that file. Defaults to sass_location. |
|
sass_location |
core/ |
Directory of the core Sass files, templates and layout, relative to the current directory. |
sass_cache_location |
Directory of the Sass cache. Defaults to .sass-cache/<name of the Sass file> in the current directory. |
|
sass_log_enabled |
false |
Log to the console when Sass gets compiled. |
layout_file |
layout.html.erb |
Layout file in sass_location. It's applied unless the input already has a <head> with content. |
CssEmailPath |
CSS file to use instead of the compiled inlined styles, relative to the current directory. | |
CssHeadPath |
CSS file to use instead of the compiled <head> styles, relative to the current directory. |
|
CompileOnlyBody |
false |
Return only the content of the <body>. |
plain_text |
false |
Return a plain text version of the email. Output files keep their name unless you set a destination. |
Custom styles
The default stylesheets are included precompiled, so compiling an email normally doesn't run Sass at all. There are two ways to customize them:
- Use your own Sass file. Copy
core/bootstrap-email.scss(see Files created at runtime), add your styles, and pointsass_email_locationandsass_email_stringat the copy. You can also edit the files incore/directly. - Use your own CSS file. Set
CssEmailPathorCssHeadPath. The file replaces the Bootstrap Email styles instead of adding to them, and no Sass is compiled.
Custom Sass is compiled in managed code with DartSassHost and Jint. The first compile takes several seconds, and the result is cached until the Sass files change. To clear the cache, call ClearSassCache().
Files created at runtime
Bootstrap Email creates these in the current directory, which therefore has to be writable:
| Path | Content |
|---|---|
core/ |
The Sass files, templates and layout, unpacked on the first compile if the directory doesn't exist. |
.sass-cache/ |
Compiled custom Sass. |
compiled/ |
Output files, if no destination is set. |
An existing core/ directory is never updated. Delete it after upgrading so that the new version can unpack its files, and keep a copy of any changes you made in it.
Upgrading to 2.0
- Rename
BootstrapEmailtoBootstrapEmailCompiler. - Remove any
DartSass.Native.*package references. Sass is now compiled in managed code, so the Dart Sass runtime is no longer needed. - Remove
ConfigStore.DartSassNativeType. There is no replacement, because no runtime has to be selected. StyleTypeis nowBootstrapEmail.Net.StyleType, instead of the type fromCitizen17.DartSass.- The CLI option
--textno longer takes a value. plain_textnow also applies to file and pattern input, not just strings.- Pattern input now compiles the content of the matching files. Earlier versions compiled the file path by mistake.
Development
dotnet test BootstrapEmail.Net.slnx
The precompiled CSS in BootstrapEmailNet/precompiled/ has to match the core Sass files, and a test fails if it doesn't. After changing the Sass files or updating DartSassHost, regenerate the CSS and rebuild:
BOOTSTRAP_EMAIL_UPDATE_PRECOMPILED=1 dotnet test BootstrapEmailNet.Tests/BootstrapEmail.Net.Tests.csproj -f net10.0 --filter "FullyQualifiedName~PrecompiledCssMatchesCoreSass"
In PowerShell, set the variable first with $env:BOOTSTRAP_EMAIL_UPDATE_PRECOMPILED = 1.
License
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AngleSharp (>= 1.9.1)
- DartSassHost (>= 2.0.14)
- ExCSS (>= 4.3.2)
- HtmlAgilityPack (>= 1.13.1)
- JavaScriptEngineSwitcher.Jint (>= 3.35.3)
- PreMailer.Net (>= 2.7.4)
-
net9.0
- AngleSharp (>= 1.9.1)
- DartSassHost (>= 2.0.14)
- ExCSS (>= 4.3.2)
- HtmlAgilityPack (>= 1.13.1)
- JavaScriptEngineSwitcher.Jint (>= 3.35.3)
- PreMailer.Net (>= 2.7.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.0 | 43 | 11/6/2026 |
| 1.7.3 | 118 | 10/20/2026 |
| 1.7.2 | 177 | 8/11/2026 |
| 1.7.1 | 156 | 8/11/2026 |
| 1.7.0 | 150 | 8/8/2026 |
| 1.5.5 | 345 | 5/24/2025 |
| 1.5.4 | 749 | 2/22/2025 |
| 1.5.3 | 1,959 | 5/11/2024 |
| 1.5.2 | 321 | 5/1/2024 |
| 1.5.1 | 399 | 4/25/2024 |
| 1.5.0 | 323 | 4/20/2024 |
| 1.4.5 | 307 | 4/14/2024 |
| 1.4.4 | 300 | 4/12/2024 |
| 1.4.3 | 293 | 4/11/2024 |
| 1.4.2 | 420 | 4/10/2024 |
| 1.4.1 | 435 | 11/28/2023 |
| 1.4.0 | 330 | 9/30/2023 |
## 2.0.0
- Sass is now compiled in managed code with DartSassHost and Jint, so no platform specific Dart Sass runtime is needed
- the default stylesheets are included precompiled, only custom Sass gets compiled
- **Breaking:** removed `ConfigStore.DartSassNativeType`, and the `DartSass.Native.*` packages are no longer used
- **Breaking:** `StyleType` is now `BootstrapEmail.Net.StyleType` instead of the Citizen17.DartSass type
- **Breaking:** renamed the `BootstrapEmail` class to `BootstrapEmailCompiler`, because `new BootstrapEmail()` didn't compile next to the namespace of the same name
- **Breaking:** the CLI option `--text` is now a flag that takes no value
- fixed pattern input compiling the file path instead of the file content
- `plain_text` now applies to file and pattern input as well
- the CLI now reads from stdin, and `--text` returns the plain text version
- the CLI now reports an error if `--pattern` is used without `--destination`
- corrected the CLI help
## 1.5.5
- updated to DartSass 1.89.0