CLI

Install blocks into your project and keep them updated without losing your customisations.

The CLI writes blocks straight into your repository and — unlike a copy-and-paste workflow — remembers what it wrote, so later updates can be merged into code you have since edited.

Configuration

init writes toro.json at your project root:

paths decides where files land; aliases decides what import prefix the written code uses. They are separate because the two are not always the same shape in a monorepo.

Signing in

Paste the seat key from your account. It is stored in ~/.toro/auth.json with 0600 permissions, along with a device id generated for this machine.

In CI or a container, set TORO_LICENSE_KEY instead — the environment always wins over the stored file. You rarely need this: installed blocks are committed to your repository, so your build never talks to the registry.

Use as many machines as you like

Devices are recorded so your account page can show where a key is being used, and so we can spot one key shared across a whole team. There is no device cap — a licence is per person, and one person legitimately has a laptop, a desktop and a devcontainer.

Commands

CommandWhat it does
initWrite toro.json
login / logoutStore or remove your seat key
listShow the whole catalogue (no licence needed)
search <query>Find a block by name or description (no licence needed)
add <names...>Install blocks and their registry dependencies
diffShow what an update would change
updateApply updates, merging your local edits

Updates that survive customisation

This is the part worth understanding, because most registry CLIs — shadcn's included — simply overwrite the file and leave you to diff it by hand.

add records a SHA-256 of every file as it was written in toro.lock.json:

When you run update, each file takes one of three routes:

  • Hash still matches — you never touched it, so it is overwritten silently.
  • Hash differs — you customised it. The CLI re-fetches the exact version you installed from the registry, uses it as the base of a three-way merge, and applies the upstream change around your edits.
  • File is gone — you deleted it, so it is recreated.

Published versions are immutable, which is what makes the merge base retrievable months later.

Where both sides changed the same region, you get the same <<<<<<< / ======= / >>>>>>> markers as a rebase, including the base text so you can see what upstream was changing from. Everything else merges cleanly.

Chakra UI v3 is required

add reads your package.json and refuses to install against Chakra v2. Blocks depend on v3 token semantics — colorPalette, bg.panel, the l1/l2/l3 radii — and on v2 they do not error, they just render subtly wrong. Better to stop at install time.

Without a licence

list and search work for anyone. add will tell you what the block is and where to buy it: