lattice-uiStable directionimport latticeThe lattice CLI scaffolds new rbxts/react games, installs primitive packages with their required
peers and providers, and audits an existing project for missing dependencies. It is published to npm
as lattice-ui and exposes two equivalent binaries, lattice and lattice-ui.
Use it when you want package selection, peer resolution and health checks handled for you rather
than editing package.json by hand.
Running the CLI
The CLI requires Node 20+. Run it on demand with npx — no install needed:
npx lattice-ui <command> [options]Or install it globally to get the shorter lattice binary:
pnpm add lattice-uinpm install lattice-uiyarn add lattice-uibun add lattice-uinpm i -g lattice-uilattice <command> [options]Both binaries run the same program. lattice help prints the usage summary, lattice version the
installed version.
npx lattice does not work — npx resolves the published package name, not the binary alias. Always write npx lattice-ui. The short lattice form is for an installed CLI.
Help
Every command has its own help page, and three spellings reach it:
lattice add --helplattice help addA malformed run reaches it too — lattice add --bogus --help prints the add page rather than
complaining about the unknown option first.
A command’s page lists its usage, options and examples. For add, remove and upgrade it also
lists every available component and preset.
Global options
| Prop | Type | Description |
|---|---|---|
| --help, -h | flag | Print usage. As the first argument it short-circuits any command; after a command name it prints that command's page. |
| --version, -v | flag | Print the installed CLI version. |
| --verbose | flag | Stream debug logging, per-file copy output, and the package manager's own output live instead of buffering it. |
| --yes, -y | flag | Accept defaults and skip prompts. Accepted by every command that prompts. |
An unknown option is a usage error, but not a bare one: the CLI suggests the closest valid name and points at the relevant help page.
Unknown option for add: --prest Did you mean --preset? Run `lattice add --help` to see the supported options.The same suggestion machinery covers command, component and preset names, so lattice add dialogg
proposes dialog. Names are validated before a package manager is resolved, so a typo cannot
surface an unrelated package-manager error first.
Terminal behavior
| Variable | Effect |
|---|---|
NO_COLOR | Disables colored output when set to any non-empty value. Wins over FORCE_COLOR. |
FORCE_COLOR | Forces color through a pipe. Any value except 0 enables it. |
NO_HYPERLINK | Disables OSC 8 hyperlinks. |
FORCE_HYPERLINK | Forces hyperlinks on. Any value except 0 enables it. |
Colour honours the NO_COLOR/FORCE_COLOR contract first, then falls back to TTY detection.
TERM=dumb always disables it.
Project paths and package names print as OSC 8 hyperlinks, shortened against the working
directory and ~. They are off automatically under CI and outside a terminal, since a few
terminals print the raw escape sequence.
When output is not a terminal the CLI drops to a flat ASCII layout, so everything below about the connected-run layout applies to interactive terminals only.
Output
Each run prints as one connected flow. A vertical gutter threads the header, each titled block and the closing verdict. Rows inside a block get tree branches, and the elapsed time lands on the last line. Counts live in the heading of the block they describe.
Commands also report which package manager they resolved and why.
While a progress spinner is running, the package manager’s own output is buffered and surfaced only
if the command fails. Pass --verbose to stream it live instead.
The flag was documented by the logger but never parsed, so logger.debug and the verbose file-copy logging were unreachable before 0.7.0.
Interactive prompts
Selection prompts are keyboard-driven.
| Key | Action |
|---|---|
↑ / ↓, or k / j | Move the cursor |
Space | Toggle the highlighted option |
a | Select all |
n | Select none |
Enter | Confirm |
Ctrl-C or Esc | Cancel |
The list scrolls when it is taller than the terminal, keeping the cursor in view. Cancelling restores the cursor and takes the terminal out of raw mode.
Commands
| Command | Purpose |
|---|---|
create | Scaffold a new project from the rbxts template. |
init | Add Lattice to an existing project. |
add | Install component packages plus their peers and required providers. |
remove | Remove selected component packages. |
upgrade | Upgrade installed @lattice-ui/* packages. |
doctor | Audit lockfiles, peers, and provider expectations. |
help / version | Print usage or the CLI version. |
create
Scaffolds a new project into an optional [project-path] (defaults to the current directory) from the rbxts template.
npx lattice-ui create my-game --pm npm --git --no-lint| Prop | Type | Description |
|---|---|---|
| [project-path] | positional | Target directory for the new project. At most one is accepted; defaults to the current directory. |
| --yes, -y | flag | Accept defaults and skip interactive prompts. |
| --pm | <pnpm | npm | yarn> | Force a package manager instead of auto-detecting one. |
| --git | flag | Initialize a git repository in the new project. |
| --template | <rbxts> | Project template to scaffold from. Currently rbxts. |
| --lint | flag | Include the lint setup. Conflicts with --no-lint. |
| --no-lint | flag | Skip the lint setup. Conflicts with --lint. |
init
Initializes Lattice inside an existing project. Unlike create, it accepts no positional path and no --git/--no-lint flags, and it supports --dry-run.
npx lattice-ui init --dry-runinit is also the migration path off the 0.6.1 rename. Before merging the template it rewrites any
pre-0.6.1 package names to their react- replacements, such as @lattice-ui/dialog to
@lattice-ui/react-dialog and @lattice-ui/core to @lattice-ui/react-runtime. Dropping the old
name matters — leaving both makes the two copies resolve side by side, which npm rejects on peer
resolution.
If the install fails, init and create roll their file changes back rather than leaving a
half-written scaffold.
| Prop | Type | Description |
|---|---|---|
| --yes, -y | flag | Accept defaults and skip prompts. |
| --dry-run | flag | Show what would change without writing files. |
| --pm | <pnpm | npm | yarn> | Force a package manager instead of auto-detecting one. |
| --template | <rbxts> | Template to initialize from. |
| --lint | flag | Include the lint setup. |
add
Installs one or more component packages with everything they need. Pass component names, comma- or
space-separated, and --preset groups. With neither, and without --yes, add prompts
interactively. lattice add --help lists every available component and preset.
npx lattice-ui add dialog,toast --preset overlayFor each component the CLI gathers its npm package, its peers and any required providers, then installs the set minus whatever is already present. Optional providers are suggested but not installed.
| Prop | Type | Description |
|---|---|---|
| [name...] | positional | Component names to add. Comma-separated lists are split (e.g. dialog,toast). |
| --preset | <preset...> | Add every component in a preset. Repeatable and comma-separated. |
| --pm | <pnpm | npm | yarn> | Force a package manager instead of auto-detecting one. |
| --yes, -y | flag | Skip the install confirmation prompt. |
| --dry-run | flag | Print the planned install command without changing anything. |
remove
Removes the selected component packages. Accepts the same selection inputs and flags as add.
npx lattice-ui remove dialog --dry-run| Prop | Type | Description |
|---|---|---|
| [name...] | positional | Component names to remove (comma- or space-separated). |
| --preset | <preset...> | Remove every component in a preset. |
| --pm | <pnpm | npm | yarn> | Force a package manager. |
| --yes, -y | flag | Skip the confirmation prompt. |
| --dry-run | flag | Preview the changes without applying them. |
upgrade
Upgrades installed @lattice-ui/* packages, with the same selection inputs and flags as add and
remove. Pre-0.6.1 names are skipped rather than upgraded — run init to rewrite them first.
npx lattice-ui upgrade --dry-run| Prop | Type | Description |
|---|---|---|
| [name...] | positional | Specific packages to upgrade. Omit to consider all installed @lattice-ui packages. |
| --preset | <preset...> | Upgrade every component in a preset. |
| --pm | <pnpm | npm | yarn> | Force a package manager. |
| --yes, -y | flag | Skip the confirmation prompt. |
| --dry-run | flag | Preview the upgrade without applying it. |
doctor
Audits the project and reports issues without changing anything, then finishes with recommended commands. It checks for:
| Check | Level |
|---|---|
| Missing or duplicated lockfile | warn |
A packageManager field that disagrees with the resolved manager | warn |
No @lattice-ui component packages installed at all | warn |
| A pre-0.6.1 package name that no longer receives releases | error |
A typescript major other than the one roblox-ts compiles with | warn |
An @lattice-ui package that is installed but not in the CLI registry | warn |
| A missing peer, or a missing optional provider | warn |
| A missing required provider | error |
Errors exit non-zero. Warnings do not.
npx lattice-ui doctor| Prop | Type | Description |
|---|---|---|
| --pm | <pnpm | npm | yarn> | Force the package manager used for the audit instead of auto-detecting. |
Presets
Presets are named bundles of components so you can install a related set in one go with --preset.
| Preset | Components |
|---|---|
overlay | popover, tooltip, dialog, toast |
form | checkbox, radio-group, switch, text-field, textarea |
Package manager resolution
With --pm omitted, the CLI resolves a package manager from the project lockfile or installed
managers. doctor surfaces resolution problems: a missing lockfile, multiple lockfiles, or a
packageManager field that does not match.
The resolved manager is also pinned into the project as a devEngines.packageManager entry.
add, remove and upgrade reapply it before they touch dependencies. A pin naming a different
manager warns and repins. Both managers refuse to install when the pin names the other one.
Every component declares the peers it needs and, for layered primitives, optional providers such as @lattice-ui/react-layer’s PortalProvider. add installs peers and required providers but only suggests optional ones — wire those up yourself when you want portal-mounted content.
Dry runs
init, add, remove and upgrade all accept --dry-run, which prints the exact package-manager
command it would run and reports what it would do.