Skip to content

Installation

Every component is a source file the shadcn CLI copies into your project. Check the requirements, add the registries once, then install anything in one command. The theme is optional: see Theming.

Requirements and compatibility

  • React 19. Components take ref as a plain prop (no forwardRef), which React 18 doesn't support.
  • Tailwind CSS v4 only. The installed CSS uses v4's cascade layers and theme variables; Tailwind v3 projects are not supported.
  • A components.json (run npx shadcn@latest init if you don't have one) and the @/* import alias pointing at your source root. Tested with shadcn CLI 4.21.0.
  • Bundler or ESM module resolution ("moduleResolution": "bundler" in tsconfig.json, the Next.js and Vite default).
  • Tested in Next.js (Base UI and Radix projects) and Vite (Radix). Other React 19 setups with Tailwind v4, such as React Router or Astro with React, should work but are untested.
  • Current browsers: Notchset uses color-mix(), :has() (Chrome and Edge 111+, Safari 16.4+, Firefox 121+).

1. Add the registries

Add both registries to components.json. The Pro one only works with a token, but adding it now means you never have to touch this file again. With them, @notchset/<name> and @notchset-pro/<name> install the build that matches your style: radix-*, new-york and default get Radix, base-* gets Base UI.

components.json
{
  "registries": {
    "@notchset": "https://notchset.dev/r/{style}/{name}.json",
    "@notchset-pro": {
      "url": "https://notchset.dev/r/pro/{style}/{name}.json",
      "headers": { "Authorization": "Bearer ${NOTCHSET_TOKEN}" }
    }
  }
}

2. Install a component

Free components also install by URL with no setup. The URL names the build, so use the one for your project's primitives (the style in components.json):

Free, Base UI project (base-* style)
npx shadcn@latest add https://notchset.dev/r/button.json https://notchset.dev/r/checkbox.json
Free, Radix project (radix-*, new-york or default style)
npx shadcn@latest add https://notchset.dev/r/radix-nova/button.json https://notchset.dev/r/radix-nova/checkbox.json
Pro: with the registries above (your style picks the build)
npx shadcn@latest add @notchset-pro/password-field

The bare URL always installs the Base UI build, of the item and of its dependencies, so a Radix project needs the /r/radix-nova/ URL or the registries. Pro items need your key in NOTCHSET_TOKEN (see Pro setup).

Components land in components/ui/notchset/ as source you own, with shared code in lib/beautiful-ui/notchset/. The first one also adds Notchset's foundation (its motion timings, keyframes and shared marks (no colours: those come from your shadcn tokens)) to your global stylesheet. Components are styled with Tailwind classes that read your shadcn tokens, so they look right in your palette, and a className you pass is merged last. Component installs don't change your shadcn tokens.

3. Use it

app/page.tsx
import { Button } from "@/components/ui/notchset/button";

export default function Page() {
  return <Button>Create workspace</Button>;
}

Sound (optional)

Notchset components mark their moments (a press, a toggle, a finished run) but ship no audio code: installing them is silent. To hear them in Notchset's analogue voice, install the sound provider and mount it once. The audio engine loads only when a provider is mounted and sound is on, and nothing plays before the first click or key press.

Terminal
npx shadcn@latest add https://notchset.dev/r/notchset-sound.json
app/providers.tsx
"use client";
import { SoundProvider, useSound } from "@/components/ui/notchset/sound-provider";
import { Toggle } from "@/components/ui/notchset/toggle";

// The mute control: any control works; a latch reads as an instrument switch.
function SoundSwitch() {
  const { muted, setMuted } = useSound();
  return (
    <Toggle variant="latch" pressed={!muted} onPressedChange={(on) => setMuted(!on)}>
      SOUND
    </Toggle>
  );
}

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    // clicks="components": only Notchset components answer. The default, "all", adds a tap to every button and link.
    <SoundProvider clicks="components" defaultMuted>
      <SoundSwitch />
      {children}
    </SoundProvider>
  );
}

defaultMuted starts silent until the visitor turns sound on, and the choice is saved in localStorage ("beautiful-ui-sound"). data-sound="off" silences everything inside an element.

Phones and overlays

Components are responsive; App Shell keeps its sidebar a rail below 640px. Overlays (dialogs, menus, popovers) portal to document.body. If you render Notchset inside a scoped container or a shadow root, wrap it in NotchsetPortalContext so overlays keep its tokens.

Next