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.
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.
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.
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.
| Command | What it does |
|---|---|
init | Write toro.json |
login / logout | Store or remove your seat key |
list | Show 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 |
diff | Show what an update would change |
update | Apply updates, merging your local edits |
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:
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.
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.
list and search work for anyone. add will tell you what the block is and
where to buy it: