# Vendor a component

Source: https://lumeo.nativ.sh/docs/guides/vendor-a-component

# Vendor a component

The Lumeo NuGet gives you every component for free — but sometimes you want to _own the source_. The `lumeo` CLI copies a component's `.razor` file straight into your project — rewritten to your namespace, yours to edit — exactly the way [shadcn/ui](https://ui.shadcn.com) does for React. This guide takes a brand-new Blazor project from zero to a vendored, editable `Button`.

## Before you start

Install the CLI as a global `dotnet` tool. It exposes a single command, `lumeo`.

dotnet tool install -g Lumeo.Cli
lumeo --help

This walkthrough assumes a fresh Blazor WebAssembly app that already references the `Lumeo` NuGet (`<PackageReference Include="Lumeo" />`). That is the default, recommended setup — the package ships the CSS tokens, utility classes and JS interop the vendored source needs, so there is nothing extra to wire up. (No Lumeo package? See [Go fully standalone](docs/guides/go-standalone), which vendors the runtime too.)

## Step 1 — Initialize

From your project root, run `lumeo init`. It walks up looking for a `.csproj`, detects the Lumeo package, and writes a `lumeo.json`. The namespace is auto-derived from your project (`<AssemblyName>.Components`); pass `--namespace` / `--path` to override, or `-y` to accept every default without prompts.

$ lumeo init
Lumeo NuGet detected - no extra CSS/JS setup needed.

OK Wrote lumeo.json
  namespace       VendorDemo.Components
  componentsPath  Components/Ui
  registry        https://lumeo.nativ.sh/registry.json

Next: lumeo add button

The resulting `lumeo.json` is the CLI's memory of your project — where components land, which registry to pull from, and which components are installed at what version.

{
  "namespace": "VendorDemo.Components",
  "componentsPath": "Components/Ui",
  "registry": "https://lumeo.nativ.sh/registry.json",
  "components": {},
  "standalone": false
}

## Step 2 — Add a component

`lumeo add button` fetches `Button.razor` from the registry, rewrites its `@namespace` to yours, and writes it under your components path. Dependencies are resolved automatically — `Button` pulls in `Spinner` for its loading state — and the tool records every install in `lumeo.json`.

$ lumeo add button
  +   Components\\Ui\\Button\\Button.razor
  +   Components\\Ui\\Spinner\\Spinner.razor

OK Added Button (+1 dep) - 2 files written to Components/Ui/

CSS variables used:
  --color-accent, --color-accent-foreground, --color-background, --color-destructive,
  --color-destructive-foreground, --color-input, --color-primary, --color-primary-foreground,
  --color-ring, --color-secondary, --color-secondary-foreground, --radius

## What landed where

Each component becomes a folder under `Components/Ui/` (your configured `componentsPath`). The `.gitkeep` and `README.md` are seeded by `init`.

Components/Ui/
├─ .gitkeep
├─ README.md
├─ Button/
│  └─ Button.razor
└─ Spinner/
   └─ Spinner.razor

The very first line of the vendored file proves the rebrand — it is _your_ namespace now, not `Lumeo`:

@namespace VendorDemo.Components
@implements IAsyncDisposable
@inject Lumeo.Services.IComponentInteropService Interop

Reference it like any local component — bring the namespace into `_Imports.razor` once, then use the tag:

@using VendorDemo.Components

<Button Variant="Button.ButtonVariant.Primary">Save</Button>

## Inspect before you write

Every mutating command has a look-first mode, so nothing is a surprise:

Command

What it does

lumeo list

List every available component grouped by category. Filter with `--category Forms`.

lumeo view button

Print the component's source to stdout without writing anything.

lumeo add button --dry-run

Show which files _would_ be written — no changes made.

lumeo info

Print project state: config paths, registry, and every installed component with its version.

If a file already exists, `add` prompts `[o]verwrite  [s]kip  [d]iff  [a]ll-overwrite  [A]bort`. For non-interactive runs use `--force` (overwrite all) or `--skip-existing`.

## Staying current: diff & update

Because you own the file, updates are opt-in. Two commands keep you in control:

-   `lumeo diff button` — compare your files against the registry version. A freshly vendored component is _in sync_.
-   `lumeo update button` — pull upstream changes (prompts before touching anything). Add `--check` for a CI-friendly drift report (exit 1 on drift), or omit the name to update everything installed.

$ lumeo diff button

Button: 1 in sync, 0 drifted, 0 missing.

Once you start editing the vendored source, `diff` becomes your drift radar — that is the subject of the next guide.

## See also

-   [Customize a vendored component](docs/guides/customize-a-component) — edit the source and manage drift.
-   [Go fully standalone (eject)](docs/guides/go-standalone) — vendor the runtime, drop the NuGet entirely.
-   [CLI reference](docs/cli) — every command and flag.
-   [Registry](docs/registry) — where component source is served from.
