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: 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:
- Run
lumeo add button --diffto read exactly what upstream changed. - With your edit committed to git,
[o]verwriteto land the upstream version, then letgit diffreplay your customization on top — or re-apply the one or two lines by hand. - Or, if your change and theirs do not overlap,
[s]kipand 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 --checkin CI to get told when upstream moves, on your schedule.
See also
- Vendor a component — the starting point for this guide.
- Go fully standalone (eject) — own the runtime too, zero NuGet.
- CLI reference —
diff,update, and every flag.