Latticegetting started

Installation

Add a Lattice UI primitive to an rbxts/react app, by hand or with the lattice CLI.

Lattice UI is a set of headless primitives for rbxts/react. Each ships as its own @lattice-ui/react-<name> package. It owns the tricky interaction work, such as open state, focus, layering and motion, and leaves the visuals to you.

The rest of getting started uses Dialog as the worked example, so @lattice-ui/react-dialog is a good place to start.

Prerequisites

Lattice UI runs on rbxts/react, so the React runtime should already be available.

React runtime
import React from "@rbxts/react";
import ReactRoblox from "@rbxts/react-roblox";

@rbxts/react and @rbxts/react-roblox are peer dependencies of every primitive (^17.3.7-ts.1) and are not bundled — install them yourself.

Install a package

pnpm add @lattice-ui/react-dialog

Install one primitive at a time. Each pulls in the foundations it needs — every primitive depends on @lattice-ui/react-runtime, and Dialog also brings react-focus, react-layer and react-motion.

Import the primitive
import { Dialog } from "@lattice-ui/react-dialog";

Use the lattice CLI

The lattice CLI installs primitives for you, adds the @rbxts/react peers, and resolves your package manager from the project lockfile. It needs Node 20+ and runs straight from npm.

Add a primitive
npx lattice-ui add dialog

The argument is the registry name (dialog), which the CLI maps to @lattice-ui/react-dialog. Add several at once, space- or comma-separated, or pull in a preset: overlay bundles popover, tooltip, dialog and toast, form bundles checkbox, radio-group, switch, text-field and textarea. See the CLI reference.

Add multiple primitives and a preset
npx lattice-ui add dialog toast --preset overlay

add with no names and no --preset prompts interactively, and --dry-run prints the exact install command without touching anything.

It also scaffolds and maintains projects. lattice create starts a new rbxts project and lattice init wires the toolchain into an existing one. lattice remove and lattice upgrade keep primitives in sync, and lattice doctor checks the setup.

Verify it works

Render the minimum useful surface to confirm the import resolves and the primitive mounts:

smoke-test.tsx
import React from "@rbxts/react";
import { Dialog } from "@lattice-ui/react-dialog";
export function SmokeTest() {
return (
<Dialog.Root defaultOpen>
<Dialog.Portal>
<Dialog.Content>
<textlabel
BackgroundTransparency={1}
Size={UDim2.fromOffset(220, 40)}
Text="Lattice UI is installed"
/>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
}

Next step

Build a real, controlled surface in Your first dialog.