Dots

Installation

Set up an app with the Dots preset, then add components with the shadcn CLI.

Dots is distributed as code. The shadcn CLI copies each component into your project, where you own and edit it. Dots ships one configuration: React Aria for behavior, the Dots style for the look, Geist and Geist Mono for type and Phosphor for icons.

Create your app

Start from any React app that uses Tailwind CSS v4: Next.js, Vite, React Router, TanStack Start or Astro. For example, with Next.js:

pnpm create next-app@latest my-app --typescript --tailwind --eslint --app

create-next-app already loads Geist and Geist Mono in app/layout.tsx, as --font-geist-sans and --font-geist-mono. init keeps an existing Geist setup as it is, so rename the two variables to --font-sans and --font-mono before you run it. Otherwise the page falls back to the browser's default font.

Or with Vite:

pnpm create vite@latest my-app -- --template react-ts

For Vite, also add Tailwind CSS and the @/* path alias as described in the Vite and Tailwind CSS docs before you continue.

Initialize Dots

Run init with the Dots preset in the root of your app:

pnpm dlx shadcn@latest init --preset https://dots.sendity.net/init?base=aria

The preset is served by this site at /init. It sets up React Aria with the Dots style. It:

  • writes components.json with the dots style and registers the @dots registry namespace, so the CLI fetches Dots items from this site
  • adds the Dots palette (light and dark) as CSS variables to your global CSS file
  • installs Geist (--font-sans, the page font) and Geist Mono (--font-mono, used for code, kbd, pre and samp)
  • installs react-aria-components, @phosphor-icons/react, class-variance-authority and cn

Add components

Add components through the @dots namespace:

pnpm dlx shadcn@latest add @dots/button @dots/field @dots/dialog

Use them

app/page.tsx
import { Button } from "@/components/ui/button"
 
export default function Home() {
  return <Button>Continue</Button>
}

The @dots namespace

init adds this entry to components.json:

components.json
{
  "registries": {
    "@dots": "<origin>/r/{name}.json"
  }
}

<origin> is the site you ran init against. Every Dots item refers to its own dependencies through @dots/<name>, so they always come from the same place. You can browse what is available in Components.

Dark mode

The palette ships light and dark tokens. Add the dark class to <html> to switch, or follow the dark mode guide for your framework.