Skip to content
  1. Keyline UI
  2. Installation
Keyline UIComponents
  • Get started
    • Installation
    • Theming
    • Modes
    • Configuration
    • Composition
  • Actions
    • Button
    • Button group
    • Split button
    • Toggle
    • Toggle group
    • Toolbar
    • Menu
    • Menubar
    • Context menu
  • Inputs
    • Field and form
    • Checkbox
    • Checkbox group
    • Radio group
    • Switch
    • Slider
    • Segmented
    • Select
    • Native select
    • Combobox
    • Multiselect
    • Number field
    • OTP field
    • Time field
    • Date picker and calendar
    • Date range
  • Data
    • Table
    • Chart
    • Stat and meter
    • Status and badge
    • Progress
    • Skeleton
    • Empty
    • Avatar
    • Kbd
    • Marker
  • Navigation
    • Tabs
    • Breadcrumb
    • Pagination
    • Nav
    • Navigation menu
    • Command menu
  • Overlays
    • Dialog
    • Alert dialog
    • Drawer
    • Sheet
    • Popover
    • Hover card
    • Tooltip
    • Toast
    • Notice
  • Layout
    • App shell
    • Sidebar
    • Panel
    • Resizable
    • Scroll area
    • Accordion
    • Collapsible
    • Carousel
    • Inspector
    • Item
    • Direction
  • Conversation
    • Message
    • Bubble
    • Message scroller
    • Attachment
    • Questionnaire
  • Blocks
    • Shipments

Installation

Keyline is a shadcn registry. The shadcn CLI copies each component's source into your project, with the components, styles and packages it needs, so the code is yours to read and change. Nothing to clone, build or host: you map the @keyline-ui registry once, then add components by name.

New project

Create a Next.js or Vite app set up for shadcn (pick either):

npx shadcn@latest init -t next
npx shadcn@latest init -t vite

In the new app's folder, map the Keyline registry. This writes one line to components.json:

npx shadcn@latest registry add @keyline-ui=https://keyline-ui.dev/r/{name}.json

Add a component and use it:

npx shadcn@latest add @keyline-ui/button
import { Button } from "@/components/keyline/ui/button"

export default function Page() {
  return <Button>Save</Button>
}

Existing shadcn project

In the folder that holds components.json, map the registry once, then add what you need. Each component page shows its command.

npx shadcn@latest registry add @keyline-ui=https://keyline-ui.dev/r/{name}.json
npx shadcn@latest add @keyline-ui/dialog @keyline-ui/select @keyline-ui/table

The first command adds this to components.json, which you can also write by hand:

{
  "registries": {
    "@keyline-ui": "https://keyline-ui.dev/r/{name}.json"
  }
}

Requirements

  • React 19 and TypeScript.
  • Tailwind CSS 4. Keyline's theme uses @theme inline, which Tailwind 3 does not have.
  • A shadcn project: a components.json with any style and base, and the cn() helper at its utils alias. shadcn init sets both up.
  • Network access to npm and to this site while you run the CLI. Nothing is fetched from this site at runtime.

What installing does

  • Files go to components/keyline/ (ui, lib, and blocks for a block), under src/ when your project uses it, following your components alias. Import them as @/components/keyline/ui/button, with your own alias in place of @.
  • Dependencies come along: the Keyline components a component is built from, Base UI, the fonts, and any library it wraps (for example recharts for Chart), at the version Keyline is tested with.
  • CSS is merged into the stylesheet named in components.json: the theme's --kl-* tokens and each component's own kl- rules. Adding a component again updates its rules in place; it does not add a second copy.
  • Fonts (Atkinson Hyperlegible Next and Mono) are npm packages imported from that stylesheet, so they are bundled with your app.

Your app and Keyline

Keyline's CSS only styles Keyline's own names (--kl-* tokens, kl- classes, data-kl-*attributes). Your shadcn components, body, fonts and tokens look the same as before, and Keyline's Button and shadcn's Button can sit on the same page. Dark mode follows a .dark class on an ancestor, as shadcn's own setups already set it.

To give the whole app Keyline's look, stock shadcn components included, add the opt-in theme:

npx shadcn@latest add @keyline-ui/keyline-shadcn

Next.js and Vite

Interactive components start with "use client";, so a Next.js App Router server page can import and render them. Vite and other bundlers without React Server Components ignore the directive. Other frameworks the shadcn CLI supports work the same way when they meet the requirements above.

Updating

Installed components are your code: nothing changes until you add them again. To take a newer version, re-add it with --overwrite. It replaces the component's files, so commit or keep your own edits first and compare afterwards.

npx shadcn@latest add @keyline-ui/button --overwrite

Without --overwrite, the CLI skips files that are unchanged and asks before replacing one you edited. CSS rules that changed are updated in place; a rule Keyline removed or renamed stays in your stylesheet until you delete it.

Removing

Delete the component's files from components/keyline/. The CLI does not remove CSS, so delete that component's kl- rules from your stylesheet as well, and any packages you no longer use. For configuration, theming and the composition rules, start with Theming and Composition.

Troubleshooting

Each of these was reproduced with shadcn 4.23.

“Unknown registry "@keyline-ui"”

Unknown registry "@keyline-ui". Make sure it is defined under "registries" in your components.json or package.json file.

The project has no @keyline-ui mapping, and the CLI does not know the name on its own. Map the namespace first with the registry command under Existing shadcn project, then add the item again.

The registry command says “already configured”

ℹ Skipped 1 registry: (already configured)
  - @keyline-ui

registry add never replaces a mapping. If @keyline-ui already points somewhere else, the old address stays and items keep coming from it. Open components.json and set registries["@keyline-ui"] to the address shown under Existing shadcn project.

Keyline's items refer to each other as @keyline-ui/<name>, so the mapping needs that exact name.

“Couldn't find tsconfig.json”, or the mapping lands in package.json

The command ran outside a shadcn project. Run it in the folder that holds components.json, or create the project first with shadcn init (see New project). Run outside one, registry add writes the mapping to package.json instead.

The CLI asks to overwrite utils.ts

? The file utils.ts already exists. Would you like to overwrite? › (y/N)

Keyline's items depend on shadcn's cn() helper, and the CLI asks before replacing a utils.ts that differs from its copy. Answer No to keep yours; Keyline only needs it to export cn().

Sheet 2 of 73Keyline UI homeNextTheming
On this page