# Bundle Facts

Source: https://lumeo.nativ.sh/docs/bundle-facts

Performance

# How Lumeo stays at 0 KB

What the browser actually downloads — brotli-compressed assembly size, measured 2026-05-13 (rc.45).

## Per-package breakdown

Install only the satellites you use. Each row shows the brotli-compressed size that package adds to your published WASM app.

Lumeocore — 135 components

400 KB

Lumeo.Chartsopt-in satellite

120 KB

Lumeo.DataGridopt-in satellite

100 KB

Lumeo.Editoropt-in satellite

26 KB

Lumeo.Motionopt-in satellite

18 KB

Lumeo.Scheduleropt-in satellite

16 KB

Lumeo.Ganttopt-in satellite

12 KB

## What's actually in the core .nupkg

The .nupkg contains more than what reaches the browser. Here's the full inventory.

Lumeo.dll

400 KB brotli

1.9 MB raw IL → 400 KB after WASM linker trimming + brotli compression. This is the only file the browser downloads from the Lumeo package.

lumeo.css

49 KB

Theme tokens, dark-mode variable swaps, and component-scoped styles. Generated by Tailwind v4 at build time — no CSS-in-JS, no runtime style injection.

components.js

57 KB

Focus traps, scroll lock, element measurement, and third-party canvas wrappers. JS is reserved for what Blazor genuinely cannot do in pure Razor.

Build props + symbols

~50 KB

MSBuild .props integration (auto-imports lumeo.css + components.js), PDB symbols for debugging. Never reaches the browser.

Total: ~556 KB compressed in the .nupkg — matches the NuGet "Download package" badge. The 400 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.

Newtonsoft.Json

AutoMapper

ReactiveUI

Theme-provider JS

CSS-in-JS runtime

Bootstrap CSS

jQuery

MudBlazor dependency tree

Telerik runtime

Syncfusion bloat

Runtime reflection helpers

Source generators in core hot path

Newtonsoft.Json

AutoMapper

ReactiveUI

Theme-provider JS

CSS-in-JS runtime

Bootstrap CSS

Newtonsoft.Json

AutoMapper

ReactiveUI

Theme-provider JS

CSS-in-JS runtime

Bootstrap CSS

jQuery

MudBlazor dependency tree

Telerik runtime

Syncfusion bloat

Runtime reflection helpers

Source generators in core hot path

Newtonsoft.Json

AutoMapper

ReactiveUI

Theme-provider JS

CSS-in-JS runtime

Bootstrap CSS

## How it compares

Brotli-compressed DLL size for the core package of each library.

Library

Core brotli size

Note

You

Lumeo (core)

400 KB

Brotli DLL — measured 2026-05-13 (rc.45)

FluentUI Blazor

~500 KB

Approximate; varies by component set referenced

MudBlazor

~600 KB

Approximate; typical published-app measurement

Radzen Blazor

~700 KB

Approximate; includes bundled JS interop

Telerik UI Blazor

~1 MB+

Estimate; runtime licensing + JS runtime included

\* Approximate brotli sizes for the core library DLL of each project at their latest stable release as of 2026. Independent verification recommended — numbers vary by build configuration and linker trimming.

## 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.

120 KB

### Charts

Lumeo.Charts

ECharts lazy-loaded only when a chart component mounts — never included unless you reference the package.

100 KB

### DataGrid

Lumeo.DataGrid

ClosedXML + QuestPDF are pulled in only when the package is referenced. Full virtualization, group-by, and export — on demand.

26 KB

### 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.35 MB for the core .nupkg — here's what that actually means.

Why isn't .nupkg size the right number?

What does WASM linker trimming do?

How was this measured?

Developer experience

## 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.

What other libs do

Libraries that rely on Blazor's per-component .razor.css isolation generate a new scoped-class hash on every change, force the SDK to re-emit the static-web-assets manifest, and often invalidate browser caches mid-session.

### 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.

What other libs do

MudThemeProvider passes a C# MudTheme record via CascadingValue. Editing colors requires recompiling C#, which triggers a delta-rebuild and re-render of every consuming component — Hot Reload often falls back to full restart.

### 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.

What other libs do

Libraries that wrap every component in a base-class source generator (or AOT-style codegen) re-run the generator on every keystroke — multi-second incremental builds, and Hot Reload often gives up entirely.

### 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.

What other libs do

Reflection-heavy libs (PropertyInfo.GetValue, Activator.CreateInstance in render) cache Type instances that don't refresh on Hot Reload — you get "works after restart" bugs because old reflection caches are still alive.

### 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.

What other libs do

Libs with deep inheritance (MyButton : MudFormComponent<T,U> : MudComponentBase) force the runtime to rebuild the whole class table when a base changes. Hot Reload prints "unable to apply edits" and you lose state.

### 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.

What other libs do

CSS-in-JS libs (or libs shipping a JS theme runtime) need to re-execute JS to recompute styles on every component touch — slower, and sometimes blocked by Blazor's circuit lifecycle.

The net effect

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.

[Get Started](/docs/installation) [GitHub Releases](https://github.com/mberger/lumeo/releases)
