Lumeo

Lumeo CLI

Sometimes you want to own the source. The Lumeo.Cli tool vendorizes Lumeo components directly into your project — like shadcn/ui does for React. Run lumeo add button and get the .razor file copied into your codebase, rewritten to your namespace. You own it. Edit it freely.

This is an optional path, not a replacement. The Lumeo NuGet remains the default — pull it in and you get every component, every service, every update for free. Reach for the CLI when a component is 80% right and you want to tweak the last 20%.

Install

Install as a global dotnet tool:

dotnet tool install -g Lumeo.Cli --version 3.12.1

The tool exposes a single command, lumeo. Run lumeo --help to see subcommands.

Quickstart

1. Initialize

From your Blazor project root:

lumeo init

You'll be asked for a target namespace (e.g. MyApp.Components) and a components folder (defaults to Components/Ui). The tool writes a lumeo.json:

{ "namespace": "MyApp.Components", "componentsPath": "Components/Ui", "registry": "https://lumeo.nativ.sh/registry/registry.json" }

2. Add a component

lumeo add button

The tool downloads Button.razor, rewrites @namespace Lumeo to @namespace MyApp.Components, and writes it to Components/Ui/Button/Button.razor. Any dependencies (e.g. Spinner for loading state) are resolved and you're prompted to install them too.

3. Use it

@using MyApp.Components <Button Variant="Button.ButtonVariant.Primary">Save</Button>

Setup paths

When you run lumeo init, the CLI walks up from the current directory looking for a .csproj that references the Lumeo NuGet. What happens next depends on the result.

NuGet already installed — default

If <PackageReference Include="Lumeo" /> (or a ProjectReference to the Lumeo library) is found, nothing extra is written. CSS tokens, utility classes, and the JS interop ship with the package. The --with-css / --with-tailwind / --no-assets flags are ignored with a soft warning.

No NuGet — Option 1: pre-built CSS (recommended)

Zero build tooling. The CLI copies Lumeo's pre-compiled stylesheets and JS modules into your wwwroot/:

wwwroot/css/lumeo.css wwwroot/css/lumeo-utilities.css wwwroot/js/theme.js wwwroot/js/components.js

Then add these tags to your index.html or _Host.cshtml:

<link rel="stylesheet" href="css/lumeo.css" /> <link rel="stylesheet" href="css/lumeo-utilities.css" /> <script src="js/theme.js"></script> <script src="js/components.js" type="module"></script>

Pick this path via lumeo init --with-css, or just press 1 when prompted.

No NuGet — Option 2: Tailwind v4 scaffold

If you're already writing Tailwind classes in your own markup, let the CLI wire up Tailwind v4 so it scans both your pages and the vendored Lumeo components. It writes Styles/input.css:

@import "tailwindcss"; @import "./_content/Lumeo/css/lumeo.css" layer(base); /* tokens */ @source "./**/*.razor"; @source "./Components/Ui/**/*.razor";

and either creates or merges into package.json a pair of scripts + the @tailwindcss/cli devDependency:

"scripts": { "build:css": "tailwindcss -i Styles/input.css -o wwwroot/css/app.css --minify", "watch:css": "tailwindcss -i Styles/input.css -o wwwroot/css/app.css --watch" }

Then:

npm install npm run watch:css

Pick this path via lumeo init --with-tailwind. You'll link css/app.css in your host HTML instead of lumeo.css.

Keeping pre-built assets fresh

When Lumeo ships CSS/JS tweaks, run lumeo update-assets. It re-downloads the files listed under assets.files in lumeo.json and prompts per-file on drift — the same flow as lumeo update <component>. Only runs when assets.mode == "prebuilt"; Tailwind users rebuild their own bundle.

Commands

lumeo init

Creates lumeo.json in the current directory and scaffolds README.md + .gitkeep under the components folder. Interactive by default: if a .csproj is present, the <RootNamespace> (or the filename) is auto-detected and suggested as the default — just press Enter to accept.

--namespace <ns> Target namespace (skips prompt). --path <path> Components folder (skips prompt). --registry <url> Override registry URL. --yes, -y Accept all defaults, skip prompts (CI mode). --force Overwrite existing lumeo.json. --with-css Copy Lumeo's pre-built CSS/JS into wwwroot/. --with-tailwind Scaffold Tailwind v4 (Styles/input.css + package.json). --no-assets Skip asset setup entirely. --local Copy assets from a local Lumeo checkout (dev only).

lumeo update-assets

Refreshes the copied CSS/JS files (applies only when assets.mode == "prebuilt"). Walks the same files init --with-css wrote and prompts per-file on drift — overwrite, skip, or view a diff. Tailwind and skip modes are no-ops (tailwind users rebuild via npm run build:css).

--local Read assets from a local Lumeo checkout. --force Overwrite all files without prompting. --dry-run Print what would happen; don't touch the filesystem.

lumeo add <component>

Downloads a component (and its registry-declared dependencies), rewrites its namespace, and writes files under componentsPath. Records the install in lumeo.json so update / remove know what's installed. When a target file already exists you get a per-file prompt — overwrite, skip, view diff, all-overwrite, or abort.

Each registry entry includes a nugetPackage field that maps the component to its NuGet package. When you run lumeo add chart, the CLI checks whether Lumeo.Charts is already referenced in your .csproj. If not, it prompts: "Lumeo.Charts is required for this component — install it now?" Confirming runs dotnet add package Lumeo.Charts before copying the component files. This applies to all five satellites: Lumeo.Charts, Lumeo.DataGrid, Lumeo.Editor, Lumeo.Scheduler, and Lumeo.Gantt. Components in the core Lumeo package skip this check.

--local Read files from a local Lumeo checkout (dev only). --yes, -y Skip dependency confirmation prompts. --force Overwrite all conflicts without prompting (CI). --skip-existing Silently skip files that already exist. --dry-run Print what would happen; don't touch the filesystem. --overwrite Legacy alias of --force.

lumeo update [<component>]

Refetches a component (or all installed components, when the name is omitted), computes a diff vs. the local vendored copy, and prompts per file: update, skip, or diff. Use --check in CI: exits 1 if any file has drifted, 0 if clean.

--local Read from a local Lumeo checkout. --force Update without prompting. --check Report drift only; exit 1 if drift found. --force-reset Restore to registry version, discarding local edits. --dry-run Print what would happen; don't touch the filesystem.

lumeo remove <component>

Deletes the vendored files for a component and cleans up empty folders. Warns if other installed components depend on it (per the registry's dependencies field) before asking for confirmation.

--force Skip the confirmation prompt. --dry-run Print what would be deleted; don't touch the filesystem.

lumeo list

Prints every component in the registry, grouped by category, with a one-line description. Filter to one category with --category, or emit JSON for tooling with --json.

--local Read from the local registry file. --category <name> Filter to one category (e.g. Forms). --json Dump entries as JSON.

lumeo diff <component>

Compares the vendored copy in your repo against the registry version and reports which files have drifted. Run lumeo update <component> to pull the upstream version (or --force to reset without prompting).

--local Diff against local registry.

lumeo view <component>

Prints a component's source files to stdout without writing anything to disk. Useful for previewing what lumeo add would copy in, or for piping into a diff tool against your own copy.

--local Read sources from a local Lumeo checkout (dev only). --path <dir> Override the components root path (rarely needed).

lumeo info

Prints your project's current Lumeo state: lumeo.json contents, installed components and their drift status, active theme preset, and the registry version the project resolves against. Pass --json for machine-readable output (CI / tooling).

--json Emit machine-readable JSON instead of pretty text.

lumeo apply <preset-or-flags>

Applies a theme preset to the project — writes lumeo.json theme defaults and refreshes wwwroot/lumeo-theme.json so the runtime matches. Accepts a 6-character preset code (e.g. lumeo apply ab12cd) or individual flags. The deprecated lumeo theme apply alias still works for backwards compat.

--preset <code> 6-char preset code (alternative to positional arg). --theme <name> default | blue | orange | green | rose | zinc | violet | amber | teal --style <name> default | new-york --base <color> slate | gray | zinc | neutral | stone --radius <n> 0 | 0.25 | 0.5 | 0.75 | 1 --font <name> system | inter | geist | ibm-plex-sans | jetbrains-mono | fira-code --icons <name> lucide | bootstrap | fluentui | font-awesome | google-material | material-design | ionicons | devicon | flag-icons --only <list> Only apply named keys (comma-separated). --dry-run Preview the resulting lumeo.json without writing. --yes Skip the confirmation prompt. --silent Suppress non-essential output.

lumeo preset encode

Generates a 6-character preset code from individual flags so you can share a theme as a single token (e.g. paste into a README or pass to lumeo apply). Pass --command to print the full lumeo apply --preset <code> line instead of just the code.

--theme / --style / --base / --radius / --font / --icons See `lumeo apply` for accepted values. --menu-color <name> Sidebar background color override. --menu-accent <name> Sidebar active-item accent color override. --dark Encode dark mode as the default. --command Print `lumeo apply --preset <code>` instead of just the code.

The lumeo.json manifest

After running lumeo add, the config grows an components map recording what's installed. It's used by update, remove, and diff. The map is optional — if missing, the CLI falls back to scanning componentsPath to infer installed components (so older lumeo.json files keep working).

{ "namespace": "MyApp.Components", "componentsPath": "Components/Ui", "registry": "https://lumeo.nativ.sh/registry/registry.json", "assets": { "mode": "prebuilt", "version": "2.0.0", "files": [ "wwwroot/css/lumeo.css", "wwwroot/css/lumeo-utilities.css", "wwwroot/js/theme.js", "wwwroot/js/components.js" ] }, "components": { "button": { "version": "2.0.0", "files": ["UI/Button/Button.razor"] }, "spinner": { "version": "2.0.0", "files": ["UI/Spinner/Spinner.razor"] } } }

assets.mode is one of "prebuilt" (Option 1 — copied CSS/JS), "tailwind" (Option 2 — Styles/input.css + package.json), or "none" (skipped). When the NuGet is detected, the whole assets block is omitted.

Tradeoffs: NuGet vs vendor

Both paths are first-class. Pick per project, or mix them — nothing in the CLI prevents you from keeping the NuGet reference alongside a few vendored components.

NuGet — the default

  • Auto-updatedotnet add package Lumeo and bump versions for bug fixes.
  • Smaller codebase — no component source files to maintain in your repo.
  • Services included — Toast, Overlay, Theme, etc. live in the package and just work.
  • Best for — most apps; shipping quickly; standard theming.

Vendor — for the last 20%

  • You own the source — diverge freely; no "waiting for a PR to merge".
  • No black-box overrides — edit markup, add slots, change behavior.
  • Opt-in updateslumeo diff shows drift, you decide when to pull.
  • Best for — design systems; component libraries built on Lumeo; heavily customized UIs.

What the CLI can and can't vendor

Only presentation components.razor and their code-behind .cs files — can be vendored. Runtime services still require a reference to the Lumeo NuGet package:

  • ToastService, OverlayService, ThemeService, KeyboardShortcutService, ComponentInteropService.
  • JavaScript interop modules (_content/Lumeo/js/*).
  • Pre-compiled CSS (lumeo.css, lumeo-utilities.css).
  • The [LumeoForm] source generator.

In practice: keep the NuGet reference; vendor the components you want to customize; delete any that you fully own.