Add your first component
One command, what it will put in your project, and nothing else to read.
Overview
This is the sixty-second path. If you want the reasoning, the safety rules and the review checks, Quick start is the longer version. If you want to know what the command will actually write into your repository before you run it, that is here too, at the bottom.
Shipped, and no published host yet
status-pill is implemented and its registry item carries the whole of its
source, so the command below is a real one rather than a sketch. What is
missing is somewhere to fetch it from by default: there is no npm package and
there will not be one, and opsinjs.pensievelabs.org is not serving yet, so
@opsinjs resolves only once you point it at a host that is serving.
components.json has the entry. The
component is shipped: the API may change in any release, and it was
audited against WCAG 2.2 AA by its own authors rather than an independent
reviewer (see ADR 0025),
and it has had no clinical review, so use it in a prototype and not in
front of a patient.
Run one command
npx shadcn@latest add @opsinjs/status-pillThat is the whole path. No provider to mount, no plugin to register, no
tailwind.config to edit. opsinjs is Tailwind v4 and CSS-variable native, so
the tokens arrive as CSS.
Know what it writes
Three files, so it is not a surprise:
<aliases.ui>/status-pill.tsx the component source is yours now, edit freely
<aliases.lib>/opsinjs.ts units, categories, error codes: what every component reads
<aliases.lib>/status.ts the four clinical levels, their words and their glyphsThe item declares those destinations as @ui/… and @lib/…, so where they
actually land is whatever your components.json aliases say. In a default
shadcn project, that is components/ui/status-pill.tsx and lib/. Two things
the command does not write, and both are commonly assumed. It writes no CSS:
the token layer is a separate registry item and
Presets has it. And it does not add the @opsinjs
entry to components.json. That entry is the precondition for the command
resolving at all, so you add it first, by hand.
The only entry added to package.json is lucide-react, which is where the
level glyphs come from and which any project with iconLibrary set to lucide
already has. That is the icon library opsinjs assumes. opsinjs distributes
source you own, not a package you upgrade. That is a deliberate trade: you
get to change anything, and in exchange you take on the merge when we change it.
Upgrading is how that merge is made survivable.
Verify it worked
Three checks, in order of how much they tell you:
- The file is there and it compiles. It landed where
aliases.uipoints, it imports cleanly, and your typechecker is quiet. If the only complaint is@/lib/utils,shadcn initwas never run in this project: the registry does not ship that file and every copied component importscnfrom it. - The tokens resolved. Render one pill and inspect it: its background should come from a custom property in the opsinjs status scope, not from a literal colour. If you see a hard-coded hex, the token layer was not imported.
- It survives greyscale. Switch your display or your devtools to greyscale. The pill must still say which level it is, in words and by its icon. If it does not, the token layer loaded but the component is being used wrongly. Colour is never the only carrier of clinical status.
Nobody has walked this path end to end against a published registry host. Every
step below was verified against a local registry server, so what is unverified is
the one thing a reader cannot substitute for themselves: that @opsinjs resolves,
that the item fetches over the network, and that the file shadcn add writes is
byte for byte the file this repository serves.
Troubleshooting
Unknown registry @opsinjs. components.json has no registries entry
mapping the namespace to a URL. Nothing preconfigures it and the CLI has no
default for it, so this is the first thing to check; see
components.json. A DNS or network failure
rather than an unknown-registry error means the entry is there and points at
opsinjs.pensievelabs.org, which is not serving yet.
The component renders unstyled. The token layer is not imported, or it is imported before Tailwind. CSS order in opsinjs is load-bearing and the exact position is specified in Next.js and Tailwind v4.
Tailwind classes inside the copied file do nothing. Tailwind v4 scans sources
declared with @source. A file copied into a directory Tailwind is not watching
produces exactly this symptom. See
Monorepo for the @source lines.
Next
- Quick start has the same command with the reasoning attached.
- StatusPill is the specification, including the three things it must never be used for.
- Clinical status semantics says what the four levels mean before you assign one.
Quick start
Build a result card that shows one value, its reference range and its clinical status, from three components that are implemented and installable.
Is opsinjs right for this project?
An honest fit checklist that will tell you no. It names the three kinds of product opsinjs actively refuses to serve.