All docs
Docs/ Building Tools/ Node variants
Building Tools

Node variants

Declare a node variant with overrides='pkg.node'. Replace-capable providers can stand in for the identity; coexist providers remain independently addable.

TL;DRPass overrides="pkg.node" to declare a variant of another node identity. A sole override_mode="replace" provider wins by default; multiple replacers require an explicit project choice. A coexist provider remains addable under its own identity and cannot be selected as a replacement. Engine.set_variant validates and stores the project choice.

A variant is a step that stands in for another node's identity without editing the original package. You point at the target with overrides="pkg.node" and choose how they relate with override_mode. Recall that a node's identity is f"{tool_name}.{fn_name}" — that string is what a variant targets.

Usage#

Python
from lsdtools import Tool, Table

tool = Tool("fastmath")

@tool.shape(overrides="stats.normalize", override_mode="replace")
def normalize(t: Table, column: str) -> Table:
    """A faster drop-in for stats.normalize — same identity, my code."""
    ...
# → wherever "stats.normalize" is used, this provider now runs

replace vs coexist#

  • replace (the declaration default) — a single replace-capable provider wins the identity by default. If several packages declare replacements, LSD retains the original until the project selects one exact provider. Use it for a compatible upgrade or a bug-fixed drop-in.
  • coexist — the original retains the base identity and your step stays independently addable under its own identity. A coexist-only provider cannot be selected as a replacement. Use it when both implementations should remain explicit choices in a pipeline.

An open-pit example: pit_shell#

Suppose a base package declares mim.solid. An open-pit package can offer its own pit-specific step while keeping that generic solid useful, so the declaration coexists:

Python
from lsdtools import Tool, Table

tool = Tool("openpit", label="Open Pit")

@tool.shape(overrides="mim.solid", override_mode="coexist")
def pit_shell(t: Table, ramp_width: float = 30.0) -> Table:
    """An open-pit shell that coexists with mim.solid.
    Add this step under its own identity when a pit-specific shell is wanted."""
    ...

Both mim.solid and openpit.pit_shell remain independently addable. The base identity still resolves to mim.solid under a coexist project selection.

Choosing the active provider#

The former Desktop Package Manager Variants section is no longer part of Project Packages, whose package mutation is activation/deactivation. For a programmatic project choice, open an existing project with Engine.load and use Engine.set_variant:

Python
from lsdtools import Engine

with Engine.load("mine.lsd") as eng:
    eng.set_variant("mim.solid", mode="coexist")
    eng.save()

The example assumes the base and override providers are already loaded. This restores the original identity while keeping the override independently addable. A coexist selection must not include provider.

For a provider declared with override_mode="replace", select it with eng.set_variant(identity, mode="replace", provider=tool_name). The provider key is its Tool name, not its full step identity. The openpit example above declares coexist, so it is not eligible for that replacement call unless the package declaration is changed and loaded in a fresh process.

Save the project to persist the choice. Different projects on the same install can resolve the same identity to different providers. The removed Engine("mine.lsd") constructor form does not open a project; the constructor's first argument is a domain Workspace.

LearnThe Tool object · Entity types · The Package Manager

APITool · Engine · Table

ExamplesA node variant · A complete package

Frequently asked questions

What is the difference between replace and coexist?

One replace-capable provider becomes the default for the target identity; multiple replace providers require an exact project selection. A coexist provider stays available under its own identity while the original remains the base. A project coexist selection has no active provider.

Does a variant edit the original package?

No. A variant targets another node's identity string from its own package; it does not edit the original package. Project selection controls which replace-capable provider resolves that identity.

By LSD Team · Last updated Sep 09, 2026 Ask a question View as Markdown
Type to search every doc, guide, and tutorial.
↑↓ navigate openesc close