# Customize a vendored component

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

# Customize a vendored component

Vendoring is only worth it if you actually change the source. Once a component lives in your project it is a plain `.razor` file — edit it like any other. This guide edits a vendored `Button`, shows how `lumeo diff` surfaces the drift, and how to pull upstream changes _without silently clobbering your edits_.

Picking up from [Vendor a component](docs/guides/vendor-a-component): you have `Components/Ui/Button/Button.razor` and a clean `lumeo diff button`.

## Step 1 — Edit the source

Say your design language calls for pill-shaped, heavier-weight buttons. Open `Button.razor` and change the base classes — swap `rounded-md` for `rounded-full` and `font-medium` for `font-semibold`:

// Components/Ui/Button/Button.razor
- private const string BaseClasses = "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ...";
+ private const string BaseClasses = "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-semibold ...";

That is it. No re-registration, no build step, no fork to maintain — the file is yours. It compiles against the Lumeo package's runtime exactly as before.

## Step 2 — See the drift

`lumeo diff button` compares every file of the component against the registry version and summarizes what moved. Your edited file now reports as drifted:

$ lumeo diff button
  drift   Components\\Ui\\Button\\Button.razor

Button: 0 in sync, 1 drifted, 0 missing.
Run lumeo update button to pull upstream, or lumeo add button --force to reset.

To see the drift line-by-line, run `lumeo add button --diff`. It prints a unified diff and writes nothing — `-` is your local file, `+` is the registry version:

$ lumeo add button --diff
  diff    Components\\Ui\\Button\\Button.razor
  ...
      private string LinkCssClass => Cx.Merge(CssClass, Cx.When(IsLoading || Disabled, "pointer-events-none opacity-50"));

-     private const string BaseClasses = "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-full text-sm font-semibold transition-colors ...";
+     private const string BaseClasses = "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors ...";

      private string? PressEffectClass => PressEffect switch
  ...
  ok      Components\\Ui\\Spinner\\Spinner.razor

PREVIEW Added Button (+1 dep) - 0 files written to Components/Ui/

## Step 3 — Update without losing changes

When Lumeo ships a Button fix upstream, you decide whether and how to take it. Nothing is ever overwritten silently.

### Check for drift in CI

`lumeo update button --check` reports drift and _exits 1_ if any file differs — perfect for a pipeline gate.

$ lumeo update button --check
Button
  drift   Components\\Ui\\Button\\Button.razor

Drift: 1 file(s) differ from registry.
# exit code 1

### Take upstream interactively

`lumeo update button` stops on every drifted file and asks what to do — so your edit is never lost by default:

$ lumeo update button
Button

Components\\Ui\\Button\\Button.razor has upstream changes.
  \[o\]verwrite  \[s\]kip  \[d\]iff:

-   `[d]iff` — review the change first, then choose.
-   `[s]kip` — keep _your_ file untouched (the safe default for a customized component).
-   `[o]verwrite` — take the upstream version, discarding your edit.

### The reconcile workflow

There is no auto-merge — you own the file, so you own the merge. The dependable pattern for a component you have customized:

1.  Run `lumeo add button --diff` to read exactly what upstream changed.
2.  With your edit committed to git, `[o]verwrite` to land the upstream version, then let `git diff` replay your customization on top — or re-apply the one or two lines by hand.
3.  Or, if your change and theirs do not overlap, `[s]kip` and cherry-pick their hunk manually.

To throw your edits away and snap back to the pristine registry version, use `lumeo update button --force-reset` (or `lumeo add button --force`). Both replace your file wholesale — reach for them only when you want the reset.

## Rules of thumb

-   Commit the vendored files to git _before_ editing — your version history is the real safety net.
-   Keep customizations small and localized; the smaller your diff, the cleaner every future `update`.
-   Run `lumeo update --check` in CI to get told when upstream moves, on your schedule.

## See also

-   [Vendor a component](docs/guides/vendor-a-component) — the starting point for this guide.
-   [Go fully standalone (eject)](docs/guides/go-standalone) — own the runtime too, zero NuGet.
-   [CLI reference](docs/cli) — `diff`, `update`, and every flag.
