How Lumeo stays at 0 KB
What the browser actually downloads — brotli-compressed assembly size, measured 2026-07-11 (4.2.0).
Per-package breakdown
Install only the satellites you use. Each row shows the brotli-compressed size that package adds to your published WASM app.
What's actually in the core .nupkg
The .nupkg contains more than what reaches the browser. Here's the full inventory.
Main Blazor component assembly — 3,076 KB raw IL, zip-compressed to 945 KB inside the .nupkg. The published WASM app brotli-compresses it to the 672 KB the browser actually downloads; the assembly itself is not IL-trimmed internally, so this size is the same whether you use 1 core component or all 143 (see 'What does WASM linker trimming do?' below).
XML documentation comments for every public API. Powers IntelliSense in Visual Studio and Rider. Never included in the WASM publish output.
Static web asset: focus traps, scroll lock, element measurement, and third-party canvas wrappers. Automatically injected into host projects via MSBuild StaticWebAssets.
Tailwind v4 utility bundle, generated at build time from component markup. One flat CSS file — no per-component isolation scopes, no runtime injection.
Theme tokens and dark-mode variable swaps. CSS-only — switching themes is a variable swap, not a C# rebuild.
Roslyn analyzer and source generator for the opt-in [LumeoForm] attribute. Compile-time only — never reaches the browser.
theme.js (5 KB), signature-pad.js (4 KB), toolbar.js (2 KB), README.md (7 KB), MSBuild .props for StaticWebAssets integration (~4 KB), icon.png + .nuspec (~2 KB). Dev-time and discovery artefacts — none reach the browser. Debug symbols ship separately as a .snupkg symbol package and are not included here.
Total: ~1,180 KB in the .nupkg — matches the NuGet "Download package" badge (~1.18 MB). The 672 KB brotli number is just the DLL, which is the only thing the WASM linker ships to the browser.
What's not in core
The dependencies we said no to.
How it compares
Brotli-compressed size of each library's core component DLL — managed code only (see note).
| Library | Core brotli size |
|---|---|
FluentUI Blazor |
302 KB |
You Lumeo (core) |
672 KB |
Radzen Blazor |
1,003 KB |
MudBlazor |
1,318 KB |
Telerik UI Blazor |
1,480 KB |
* Brotli (quality 11) of each library's core component DLL — latest stable as of June 2026,
.NET 10 target (Telerik: .NET 8, its latest published build). Measured 2026-06-29 and
reproducible by brotli-compressing the DLL inside each public .nupkg. This counts the managed
assembly only: it excludes app-specific IL trimming (which shrinks every library in a real
published app) and the JS/CSS static web assets each library ships separately — some
substantial (e.g. Telerik's ~4.8 MB JS bundle, Radzen's multi-theme CSS, and Lumeo's own
components.js + lumeo.css). DLL size reflects managed footprint, not features or final shipped size.
Only the Lumeo row was re-measured on 2026-07-11 against 4.2.0 — 671.6 KiB
(687,723 bytes) brotli of lib/net10.0/Lumeo.dll,
rounded to 672 KB above; every other row remains the 2026-06-29 measurement.
Heavy features are opt-in
Don't need charts? ECharts never touches your build. Don't need a data grid? ClosedXML and QuestPDF aren't downloaded.
Charts
Lumeo.Charts
ECharts lazy-loaded only when a chart component mounts — never included unless you reference the package.
DataGrid
Lumeo.DataGrid
Full virtualization, group-by, and export. Since v3.7.0 the export backend (ClosedXML + QuestPDF, ~1.65 MB brotli) ships in a separate bundled DLL — opt-in lazy-load on WASM keeps it out of the first paint. Lazy setup →
Rich Text Editor
Lumeo.Editor
TipTap JS lazy-loaded at component mount time. The DLL is only 26 KB — the heavy JS only streams when the editor renders.
Why brotli, not .nupkg?
NuGet shows ~1.18 MB for the core .nupkg — here's what that actually means.
Hot Reload that actually works
Six architectural choices that keep dotnet watch
fast and reliable on Lumeo apps — the same choices most Blazor UI libs make differently and pay for in
slow rebuilds, stale styles, or forced full-restart loops.
No Blazor CSS isolation
Lumeo styles every component via Tailwind utility classes composed directly in markup. Tailwind v4 watch mode regenerates the single utility bundle in under 100 ms; the browser swaps it without losing state.
Theme is CSS variables — not a C# object
Switching themes in Lumeo means swapping --color-primary, --color-background, etc. in lumeo.css. No C# rebuild needed. dotnet watch picks up the CSS change and the browser re-paints with the new tokens.
No source generators in the runtime hot path
Lumeo.SourceGenerators only emits code for the opt-in [LumeoForm] attribute. Normal component edits never re-run a generator, so the dotnet watch inner loop is just Roslyn incremental compile + DOM patch.
No reflection in the render path
DataGridColumn<T>.GetValue is a compiled Expression<Func<TItem,object?>> cached per field (rc.44). Component parameters are strongly typed records. Hot Reload can swap method bodies without invalidating any cached type-handle metadata.
CascadingValue composition, not inheritance
Compound components like Select / SelectTrigger / SelectContent share state via a record passed through CascadingValue. Each Razor file is independent and Hot Reload swaps it in isolation.
Razor SDK + Tailwind watch — one CSS bundle
lumeo.css + lumeo-utilities.css are two files generated by Tailwind from your source. dotnet watch + npm run watch:css run in parallel; CSS swaps don't go through Blazor at all. No virtual-DOM diff for visual-only changes.
Edit a Razor component → DOM patches in ~120 ms. Edit
lumeo.css
or a theme variable → CSS swaps in ~50 ms with zero C# rebuild. Edit a Lumeo source-of-truth
record (e.g. DataGridColumn<T>) →
delta build + DOM patch in under a second. No "Hot Reload not supported, restarting"
spinner on the inner loop.
See it for yourself
Add Lumeo to a project, publish it, and measure. We believe the numbers.