element

Using element

Pull UI source from any public GitHub catalog into your project. The CLI copies files in, installs npm packages the element declares, and writes metadata so you can update or remove them later.

Publishing your own catalog? See Publishing.

Install

No global install required

Run everything through npx. Start by listing what a catalog offers, then add interactively or by name.

sh
npx @levi-putna/element@latest list levi-putna/elements
sh
# Interactive: browse and pick an element + path
npx @levi-putna/element@latest add levi-putna/elements

# Install a specific element
npx @levi-putna/element@latest add levi-putna/elements --element button

# Install into a chosen directory
npx @levi-putna/element@latest add levi-putna/elements --element button --path components/ui

# Skip every prompt (including overwrites)
npx @levi-putna/element@latest add levi-putna/elements --element button -y

# Full GitHub URL or a branch
npx @levi-putna/element@latest add https://github.com/levi-putna/elements
npx @levi-putna/element@latest add levi-putna/elements@develop --element badge

Optional: set GITHUB_TOKEN if you hit API rate limits or need private repos.

What happens on add

Plan first, then write

  1. Fetch the catalog (registry/ or elements/) from GitHub.
  2. Resolve the selected element and its elementDependencies / registryDependencies recursively in the same catalog. Missing names are skipped with a warning.
  3. Union every npm dependencies / devDependencies across that tree; skip packages already declared in your package.json.
  4. Detect install paths from config and existing sidecars.
  5. Show a plan: requested vs dependency elements, files (+ create / ~ overwrite / = skip), and npm packages.
  6. On confirm: install missing npm packages, write files, write sidecars, update the lockfile.

Package manager is detected from lockfiles / packageManager. Yarn is preferred when the signal is ambiguous. Publishing your own catalog with deps? See Publishing → Dependencies.

Commands

Everyday commands

CommandDescription
initCreate .element/config.json in the current project
list <owner/repo>Browse elements available in a remote catalog
add <owner/repo> [options]Install elements and their element dependencies
installedShow the lockfile and detected install paths
update [name]Re-fetch installed elements from their lockfile sources
remove <name>Remove files, sidecar, and lock entry for an element

Flags for add

PropTypeDefaultDescription
--element, -eflag-Install a specific element (skips the interactive picker)
--path, -pflag-Override the install directory
--yes, -yflag-Skip all prompts, overwrite conflicts, and use the default path
--overwrite, -oflag-Overwrite existing files (still confirms the plan unless -y)
--silent, -sflag-Quiet spinners and logs
sh
# Interactive: browse and pick an element + path
npx @levi-putna/element@latest add levi-putna/elements

# Install a specific element
npx @levi-putna/element@latest add levi-putna/elements --element button

# Install into a chosen directory
npx @levi-putna/element@latest add levi-putna/elements --element button --path components/ui

# Skip every prompt (including overwrites)
npx @levi-putna/element@latest add levi-putna/elements --element button -y

# Full GitHub URL or a branch
npx @levi-putna/element@latest add https://github.com/levi-putna/elements
npx @levi-putna/element@latest add levi-putna/elements@develop --element badge

Manage

See what's installed, update, remove

Installed elements are tracked in .element/lock.json. Update re-fetches from the recorded source; remove deletes the files, sidecar, and lock entry.

sh
npx @levi-putna/element@latest installed
npx @levi-putna/element@latest update
npx @levi-putna/element@latest update button
npx @levi-putna/element@latest remove button

Project store

.element/ and sidecars

Created by init or on first add:

text
.element/
  config.json    # known paths, defaultPath, packageManager
  lock.json      # installed elements → source provenance

config.json

json
{
  "paths": {
    "components/ui": 3,
    "ui/elements": 1
  },
  "defaultPath": "components/ui",
  "packageManager": "yarn"
}

lock.json

json
{
  "elements": {
    "button": {
      "repo": "levi-putna/elements",
      "branch": "main",
      "catalogRoot": "registry",
      "installPath": "components/ui",
      "files": ["button.tsx"],
      "installedAt": "2026-08-12T00:00:00.000Z"
    }
  }
}

Sidecar (next to the installed files)

Written as button.element.json beside the component. Sidecars are how the CLI discovers which directories you already use for elements.

json
{
  "name": "button",
  "source": {
    "repo": "levi-putna/elements",
    "branch": "main",
    "catalogRoot": "registry",
    "path": "registry/button"
  },
  "installedAt": "2026-08-12T00:00:00.000Z",
  "dependencies": ["@base-ui/react", "class-variance-authority", "lucide-react"],
  "devDependencies": [],
  "elementDependencies": ["utils"],
  "files": ["button.tsx"],
  "description": "…"
}

Paths

How install path is chosen

OrderRule
1--path if you pass it
2.element/config.json paths / defaultPath
3Scan for *.element.json / .element and group by parent directory
4Interactive: offer every detected path, plus custom
5With -y: defaultPath, else most-used path, else components/ui

Differing existing files are marked ~ overwrite and warned before confirm. Identical content is skipped. -y skips prompts and overwrites; -o overwrites without per-file asks but still shows the plan confirm unless -y.

On this site

Documented elements you can install

These registry elements have live docs under Elements. Each page includes the same copy-ready command.

Ready to share your own components? Publish a catalog →