MinimalHtml 0.0.1-alpha.14
dotnet add package MinimalHtml --version 0.0.1-alpha.14
NuGet\Install-Package MinimalHtml -Version 0.0.1-alpha.14
<PackageReference Include="MinimalHtml" Version="0.0.1-alpha.14" />
<PackageVersion Include="MinimalHtml" Version="0.0.1-alpha.14" />
<PackageReference Include="MinimalHtml" />
paket add MinimalHtml --version 0.0.1-alpha.14
#r "nuget: MinimalHtml, 0.0.1-alpha.14"
#:package MinimalHtml@0.0.1-alpha.14
#addin nuget:?package=MinimalHtml&version=0.0.1-alpha.14&prerelease
#tool nuget:?package=MinimalHtml&version=0.0.1-alpha.14&prerelease
MinimalHtml
A high-performance, AOT-compatible HTML template library for .NET 10 that leverages C# StringInterpolationHandler and System.IO.Pipelines for efficient streaming HTML generation.
Features
- 🚀 High Performance: Direct
PipeWriterstreaming with minimal allocations - 🔒 AOT Compatible: Full support for Native AOT compilation
- 🛡️ XSS Protection: Automatic HTML encoding for all interpolated values
- 🎨 IDE Support: Full HTML syntax highlighting in JetBrains Rider, plus HTML tokenization, hover docs, and autocomplete in VS Code via the HTML# extension
Quick Start
Installation
dotnet add package MinimalHtml
dotnet add package MinimalHtml.AspNetCore # For ASP.NET Core integration
Basic Usage
using MinimalHtml;
// Define a template as a static method or property
public static readonly Template<User> UserTemplate =
(writer, user) => writer.Html($"""
<div class="user-card">
<h2>{user.Name}</h2>
<p>{user.Email}</p>
</div>
""");
// Use in ASP.NET Core
app.MapGet("/user/{id}", (int id, UserService users) =>
{
var user = users.GetById(id);
return Results.Html(UserTemplate, user);
});
Security
All template interpolations are automatically HTML-encoded to prevent XSS attacks:
var userInput = "<script>alert('xss')</script>";
writer.Html($"<p>User said: {userInput}</p>");
// Outputs: <p>User said: <script>alert('xss')</script></p>
Performance
MinimalHtml is designed for maximum performance:
- Streaming templates: Improved Time to First Byte (TTFB) by sending content as it's generated (example)
- Zero allocation string literals: Cached as UTF-8 byte arrays
- Direct PipeWriter streaming: No intermediate string building
- Source generation: Templates pre-compiled when possible
- AOT friendly: No runtime compilation or reflection
Template Caching Setup
For optimal performance, enable UTF-8 byte array caching of string literals using the source generator:
- Create a template cache class:
using MinimalHtml;
public static partial class TemplateCache
{
[FillTemplateCache]
public static partial void Cache();
}
- Initialize the cache in your Program.cs:
// Initialize template cache for optimal performance (skip in debug for Hot Reload compatibility)
#if !DEBUG
TemplateCache.Cache();
#endif
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => Results.Html($"<h1>Hello World!</h1>"));
app.Run();
The source generator will automatically populate this class with cached UTF-8 byte arrays for all string literals found in your templates, significantly improving performance by eliminating encoding overhead.
Vite integration
MinimalHtml.Vite (NuGet) + @minimalhtml/vite (npm) pair the .NET runtime with a Vite-built frontend. The NuGet package reads Vite's manifest.json to resolve hashed asset URLs, integrity hashes, and import maps. The npm plugin discovers entry points from your .cs files via marker comments and emits the manifest with SHA-384 SRI hashes.
Install
dotnet add package MinimalHtml.Vite
pnpm add -D @minimalhtml/vite vite
Vite config
// vite.config.ts
import { defineConfig } from "vite";
import minimalHtml from "@minimalhtml/vite";
export default defineConfig({
plugins: [minimalHtml()],
});
Program.cs
using MinimalHtml.Vite;
builder.Services.RegisterViteAssets(importmapPath: ".vite/importmap.json");
RegisterViteAssets registers a GetAsset delegate (resolves id → Asset { Src, Integrity, Imports }) and a WriteImportMap delegate (emits the <script type="importmap"> tag).
Marker convention
Tag any string literal that names an asset with /*vite*/. The plugin scans .cs files for the marker and feeds matching literals to Vite's input list.
public static Template Head = Assets.Style(/*vite*/"styles/main.css");
public static Template Init = Assets.Script(/*vite*/"scripts/main.ts");
Assets.Script / Assets.Style here are application-level helpers around GetAsset — see the sample app for examples that emit <script integrity="..." crossorigin="anonymous"> and preload <link> tags from imports.
See @minimalhtml/vite README for plugin options (custom marker, scan globs, import-map and integrity tuning) and the sample app for a working setup.
Benchmarks
Rendering a list of 100 products (based on the Fluid benchmark suite):
| Template engine | Mean | Allocated |
|---|---|---|
| Fluid | 346.4 μs | 32.77 KB |
| MinimalHtml | 117.8 μs | 6.57 KB |
MinimalHtml renders ~2.9× faster and allocates ~5× less memory.
<sub>BenchmarkDotNet v0.15.2, .NET 10.0.6, Windows 11, X64 RyuJIT AVX2. InvocationCount=1, UnrollFactor=1.</sub>
Run the included benchmarks yourself:
dotnet run --project benchmark/MinimalHtml.Benchmarks.csproj -c Release
Requirements
- .NET 10.0 or later
- C# 14.0 or later
License
This project is licensed under the MIT License. See the LICENSE file for details.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on MinimalHtml:
| Package | Downloads |
|---|---|
|
MinimalHtml.AspNetCore
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.0.1-alpha.14 | 87 | 5/15/2026 |
| 0.0.1-alpha.13 | 61 | 5/15/2026 |
| 0.0.1-alpha.12 | 66 | 5/15/2026 |
| 0.0.1-alpha.11 | 109 | 5/15/2026 |
| 0.0.1-alpha.10 | 76 | 5/15/2026 |
| 0.0.1-alpha.9 | 96 | 5/9/2026 |
| 0.0.1-alpha.8 | 137 | 4/17/2026 |
| 0.0.1-alpha.7 | 82 | 4/17/2026 |
| 0.0.1-alpha.6 | 74 | 4/17/2026 |
| 0.0.1-alpha.5 | 106 | 4/12/2026 |
| 0.0.1-alpha.4 | 127 | 2/15/2026 |
| 0.0.1-alpha.2 | 80 | 2/15/2026 |
| 0.0.1-alpha.1 | 254 | 9/22/2025 |
| 0.0.1-alpha.0 | 238 | 9/22/2025 |