npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@octanejs/shadcn

v0.0.59

Published

shadcn/ui components for Octane, with Base UI, Radix, and React Aria implementations and an installable source registry.

Readme

@octanejs/shadcn

shadcn/ui for the octane renderer, with Base UI, Radix, and React Aria bases adapted to octane's hooks and native events.

Installation

npm install @octanejs/shadcn
pnpm add @octanejs/shadcn

Upstream pin: shadcn-ui/ui@7c9eaba1 + CLI [email protected].

What ships

  • 44 component families across three bases: the full Tier-1 static set, all 24 radix-backed Tier-2 components, and the first Tier-3 composites (Sidebar with useSidebar/useIsMobile, Field), plus cn() and the default neutral theme tokens (@octanejs/shadcn/theme.css).
  • Two consumption modes: import from the package subpaths, or install components AS SOURCE with the upstream shadcn CLI against the generated registry (registry/ — pnpm registry:build / registry:check).
  • Three primitive bases in one registry, selected the way shadcn selects its own: components.json's style field, substituted into the registry URL. See Installing with the shadcn CLI.
  • Styling flavors: components are migrating to the default-Tailwind (utilities-inlined) flavor — class strings work against any Tailwind v4 build with the shadcn theme tokens. The not-yet-migrated families still carry the upstream cn-* semantic hooks and need a shadcn style sheet (e.g. style-nova). status.json lists exactly which families are which.

Component coverage

The coverage table tracks the families ported for each primitive base. Switching style changes which primitive a component uses. Each base retains its upstream API; for example, Base UI Navigation Menu exposes a Positioner that owns its viewport, and Base UI Select aliases its hostless Root.

The Base UI wrappers target @octanejs/base-ui's Base UI 1.8.0 API, including Select, Navigation Menu, and Scroll Area from the 4.21.0 registry with Nova utilities. Combobox is outside this package's current family inventory.

All three bases use [email protected], matching the upstream update. Existing Octane adaptations and styling remain intact; @octanejs/shadcn/cn re-exports the same helper.

44 families — Radix 44/44 · React Aria 33/44 · Base UI 43/44

✅ ported · — not ported yet (fair game) · ⛔ blocked, see notes below

| Family | Radix | React Aria | Base UI | | --- | :---: | :---: | :---: | | accordion | ✅ | ✅ | ✅ | | alert | ✅ | ✅ | ✅ | | alert-dialog | ✅ | ✅ | ✅ | | aspect-ratio | ✅ | ✅ | ✅ | | avatar | ✅ | ✅ | ✅ | | badge | ✅ | ✅ | ✅ | | breadcrumb | ✅ | ✅ | ✅ | | button | ✅ | ✅ | ✅ | | card | ✅ | ✅ | ✅ | | checkbox | ✅ | ✅ | ✅ | | collapsible | ✅ | ✅ | ✅ | | context-menu | ✅ | ⛔ | ✅ | | dialog | ✅ | ✅ | ✅ | | dropdown-menu | ✅ | ⛔ | ✅ | | empty | ✅ | ✅ | ✅ | | field | ✅ | ✅ | ✅ | | hover-card | ✅ | ⛔ | ✅ | | input | ✅ | ✅ | ✅ | | item | ✅ | ✅ | ✅ | | kbd | ✅ | ✅ | ✅ | | label | ✅ | ✅ | ✅ | | menubar | ✅ | ⛔ | ✅ | | native-select | ✅ | ✅ | ✅ | | navigation-menu | ✅ | ⛔ | ✅ | | pagination | ✅ | ✅ | ✅ | | popover | ✅ | ✅ | ✅ | | progress | ✅ | ⛔ | ✅ | | radio-group | ✅ | ✅ | ✅ | | scroll-area | ✅ | ✅ | ✅ | | select | ✅ | ⛔ | ✅ | | separator | ✅ | ✅ | ✅ | | sheet | ✅ | ✅ | ✅ | | sidebar | ✅ | ⛔ | ✅ | | skeleton | ✅ | ✅ | ✅ | | slider | ✅ | ✅ | ✅ | | sonner | ✅ | ⛔ | ⛔ | | spinner | ✅ | ✅ | ✅ | | switch | ✅ | ✅ | ✅ | | table | ✅ | ✅ | ✅ | | tabs | ✅ | ✅ | ✅ | | textarea | ✅ | ✅ | ✅ | | toggle | ✅ | ✅ | ✅ | | toggle-group | ✅ | ⛔ | ✅ | | tooltip | ✅ | ⛔ | ✅ |

Blocked

| Base | Family | Reason | | --- | --- | --- | | Base UI | sonner | needs next-themes, which has no octane binding | | React Aria | context-menu | no counterpart in upstream’s aria base | | React Aria | dropdown-menu | no counterpart in upstream’s aria base | | React Aria | hover-card | no counterpart in upstream’s aria base | | React Aria | menubar | no counterpart in upstream’s aria base | | React Aria | navigation-menu | no counterpart in upstream’s aria base | | React Aria | progress | no counterpart in upstream’s aria base | | React Aria | select | needs input-group | | React Aria | sidebar | no counterpart in upstream’s aria base | | React Aria | sonner | needs next-themes, which has no octane binding | | React Aria | toggle-group | no counterpart in upstream’s aria base | | React Aria | tooltip | no counterpart in upstream’s aria base |

The table is generated from the sources by pnpm coverage:build and gated by coverage:check, so it cannot drift as families land.

Installing with the shadcn CLI

The registry is consumed by the upstream shadcn CLI — nothing octane-specific is required on the consumer side.

Add the registry to your components.json and pick a base with style:

{
  "style": "base-nova", // base-nova | radix-nova | aria-nova
  "registries": {
    "@octane": "https://octanejs.dev/r/styles/{style}/{name}.json"
  }
}
npx shadcn add @octane/button

{style} and {name} are the only placeholders the CLI substitutes, and it never parses the style string — so the base is chosen entirely by which tree the registry serves. This is the same mechanism shadcn uses upstream, where its own registry is <host>/styles/{style}/{name}.json.

| style | Primitives | Families | | --- | --- | --- | | base-nova (default) | @octanejs/base-ui | 43 | | radix-nova | @octanejs/radix | 44 | | aria-nova | @octanejs/aria | 33 |

The bases currently ship different family counts; see the coverage table for remaining ports. Switching style changes which primitive a component is built on; the data-slot contract and component names stay identical, so your markup and styling do not change.

A registry URL without the {style} segment resolves to the default style, so https://octanejs.dev/r/{name}.json serves the Base UI variant.

Serving it locally

pnpm --dir packages/shadcn registry:build   # regenerate from src/
pnpm --dir packages/shadcn registry:serve   # http://localhost:4517

Then point components.json at http://localhost:4517/styles/{style}/{name}.json, which is what playground/octane does.

Importing from the package

There is no barrel entry. Every family has its own subpath, so an app pulls in only what it uses — the Radix base at the bare name, the others under their base:

// Radix base (the bare subpaths)
import { Button } from '@octanejs/shadcn/Button';
import { Dialog, DialogContent, DialogTitle } from '@octanejs/shadcn/Dialog';

// React Aria base
import { Button } from '@octanejs/shadcn/react-aria/Button';

// Base UI base
import {
	AlertDialog,
	AlertDialogAction,
	AlertDialogCancel,
	AlertDialogContent,
	AlertDialogDescription,
	AlertDialogFooter,
	AlertDialogHeader,
	AlertDialogMedia,
	AlertDialogTitle,
	AlertDialogTrigger,
} from '@octanejs/shadcn/base-ui/AlertDialog';

import '@octanejs/shadcn/theme.css';

Subpaths are PascalCase and map to the family, not the export: AlertDialogTrigger and its siblings all come from .../AlertDialog. cn lives at @octanejs/shadcn/cn, shared types at @octanejs/shadcn/types, and useIsMobile at @octanejs/shadcn/hooks/use-mobile.

Octane adaptations are uniform and documented per file: no "use client", refs as props, native events (onInput per keystroke), asChild and Portal children composed as element descriptors, and children forwarding through the compiler's {props.children} lowering.

Evidence

Behavioral (jsdom), SSR, hydration-adoption, and differential suites — the differential rig byte-compares fixtures against the vendored pinned upstream React sources running real radix-ui. The full ledger (supported surface, divergences, SSR status, flavor migration state) lives in status.json and the generated bindings status table; scope and phase history in docs/shadcn-port-plan.md.