10 / Docs
Install Command
The install line for a library, switchable between package managers, with the runner and the installer kept apart.
npx shadcn@latest add Tinkerers-Labs/mischief-ui/hold-buttonRunning a package and adding one are different verbs, so they come from different tables.
"use client"
import { InstallCommand } from "mischief-ui/install-command"
export function InstallCommandDemo() {
return (
<InstallCommand
className="w-full max-w-lg"
add="mischief-ui"
note="Running a package and adding one are different verbs, so they come from different tables."
prompt="Read https://ui.tinkererslabs.com/md/hold-button.md, then add it to this project."
run="shadcn@latest add Tinkerers-Labs/mischief-ui/hold-button"
/>
)
}Installation
Copy the source into your project, or keep it behind a package.
npx shadcn@latest add Tinkerers-Labs/mischief-ui/install-commandimport { InstallCommand } from "mischief-ui/install-command"Or paste it in yourself. The source imports the shared cn helper from @/lib/utils, so point that at your own copy.
"use client" import * as React from "react"import { Check, Clipboard, Terminal } from "lucide-react"import { cn } from "@/lib/utils" export type PackageManager = "npm" | "pnpm" | "yarn" | "bun" /** A labelled thing to copy, when the built-in verbs do not fit. */export type InstallTab = { id: string label: string value: string /** Wrap rather than scroll, for anything that is not one line. */Usage
export function Install() {
return (
<InstallCommand
run="shadcn@latest add tabs"
add="my-lib"
prompt="Read the docs, then add Tabs to this project."
/>
)
}Running something, or adding it
The two props are two different verbs, and a block can offer either or both. run is a one-off execution -- a generator, a registry command -- and add is a dependency going into package.json. Each manager has its own word for each, and picking a manager applies to whichever verb is showing.
| Manager | run | add |
|---|---|---|
npm | npx | npm install |
pnpm | pnpm dlx | pnpm add |
yarn | yarn dlx | yarn add |
bun | bunx --bun | bun add |
Pass the arguments without the verb -- shadcn@latest add tabs, not npx shadcn@latest add tabs -- and the block builds the whole line. Choosing pnpm and then switching to the package option gives pnpm add rather than snapping back to the default.
When it is not an install
The package managers are the common case, not the only one. A block that offers a skill, a server config, and a curl call is the same thing -- a few labelled snippets and one copy button -- but none of them is npm install. Pass tabs and they replace the managers entirely.
<InstallCommand
tabs={[
{ id: "skill", label: "skill", value: skillCommand },
{ id: "mcp", label: "mcp", value: serverConfig, wrap: true },
{ id: "curl", label: "curl", value: curlCall },
]}
/>The agent option
prompt adds a third choice that is not a command at all: an instruction to paste into a coding agent. It sits beside the shell commands because that is now one of the ways people install things, and copying it uses the same control.
<InstallCommand
run="shadcn@latest add tabs"
add="mischief-ui"
prompt={`Read ${docsUrl} and add this component to my project.`}
/>Only the options you supply are offered, so a block with just add shows no manager row at all and no empty tabs.
API
tabsInstallTab[]Your own tabs, which replace the package managers entirely.defaultTabstringWhich of those opens first. Defaults to the first.runstringArguments for a one-off runner, such as shadcn@latest add tabs.addstringPackages to add as a dependency.promptstringAn instruction to paste into a coding agent, offered beside the commands.managers, defaultManagerPackageManager[], PackageManagerWhich package managers to offer and which leads. Defaults to npm.packageLabel, promptLabel, notestring, string, ReactNodeCopy for the two extra options and the line beneath.InstallTab
idstringUnique within the set. What defaultTab names.labelstringThe tab as shown.valuestringWhat is displayed and copied.wrapbooleanWrap rather than scroll, for more than one line.Accessibility
The options are a labelled group of toggle buttons reporting their pressed state, so the current choice is announced rather than shown only by a border. Running a package and adding a dependency are separate verbs, so they come from separate tables instead of one being derived from the other by rewriting a string. Only the options you supply are rendered, and a prompt wraps rather than scrolling sideways.