shadcn.landing Open editor

ui-kit/shadcn

A shadcn/ui Playground for the Components You Own

Drop in the shadcn/ui components you copy into your own project — Radix primitives styled with Tailwind — and see them render live, with nothing to install.

built onRadix + Tailwind
modelcopy-paste, you own it
frameworkReact
installnone
ui/button.jsx
// src/components/ui/button.jsx — yours to edit
import { Slot } from '@radix-ui/react-slot';
import { cva } from 'class-variance-authority';

const button = cva(
  'inline-flex items-center rounded-md px-4 py-2',
  { variants: { variant: { default: 'bg-slate-900 text-white' } } }
);
shadcn/ui · your component, rendered

01 platform

Why shadcn/ui is components you own, not a dependency

shadcn/ui inverts the usual deal. Instead of installing a component library and theming around it, you copy the component's source into your project and it becomes yours to change. The editor is a good place to see what that feels like.

  • The code is in your project

    A shadcn/ui component lives in src/components/ui, as source you can read and edit, not behind an npm package boundary. There is no wrapper to fight when a design needs something the library did not anticipate.

  • Radix does the hard part

    The behavior — focus traps, keyboard handling, accessibility — comes from Radix primitives underneath, so owning the code does not mean rewriting a dialog's mechanics.

  • Tailwind does the styling

    The look is Tailwind utility classes in that same source, so restyling a component is editing its classes, with the whole utility system available.

  • A real project, not a snippet

    Split components across files, add TypeScript, keep them in ui/, and commit with Git — the shape shadcn/ui expects.

02 deep dive

Copy the component in, then it is yours

The whole idea is ownership, and the editor is where you edit the owned code rather than configure a black box.

You edit the component, not props around it. Change the markup, the classes or the variants directly in ui/button.jsx. There is no theme object mediating between you and the result — the source is the API.

Variants are explicit. shadcn/ui uses class-variance-authority to declare a component's variants as data, so a new size or tone is a line in the same file, visible and yours.

Nothing is hidden in a package. Because the component is source in your tree, the editor shows you exactly what renders, which is the point of the copy-paste model over an installed library.

location
src/components/ui
behavior
Radix primitives
style
Tailwind classes
variants
cva, in-file
usage.jsx
import { Button } from '@/components/ui/button';

export default function App() {
  return <Button variant="default">Save</Button>;
}
import your own component

03 features

What ships with a shadcn/ui project

Everything below is on the moment you open the shadcn/ui editor, which starts with real Radix tabs and a dialog styled into your own ui/ folder.

  • Tailwind, generated live

    The classes on your components are compiled by the official Tailwind browser engine, so restyling is instant with no PostCSS build.

  • Radix from npm

    The Radix primitives shadcn/ui builds on resolve through esm.sh, so the accessible behavior works without a local install.

  • Components in your tree

    The ui/ folder is real source you edit — a file tree, tabs and history around the components you own.

  • TypeScript included

    Write .tsx for typed props and variants; types strip on the fast path, so a typed component costs nothing at runtime.

  • Live preview, four ways

    Full width, split, in device frames or its own tab — so a dialog's focus behavior is something you can actually test.

  • Git and export

    Commit through isomorphic-git and export the project as a zip; the components come with it, because they were always yours.

04 deep dive

Radix primitives, styled with Tailwind

shadcn/ui is really a convention over two libraries, and seeing both work together is what the editor is for.

Radix supplies behavior. A dialog traps focus and closes on escape; a dropdown handles arrow keys; a tabs component manages roving focus — all from unstyled Radix primitives that do the accessibility work.

Tailwind supplies the look. The primitives arrive unstyled, and shadcn/ui dresses them in Tailwind classes, so the same component you can restyle by editing utility classes still behaves correctly.

You get both, and the seam. Because the composed source is in your project, you can see exactly where Radix ends and Tailwind begins — which is the understanding the copy-paste model is meant to give you.

behavior
@radix-ui/*
style
Tailwind utilities
glue
your ui/ source
a11y
from Radix
ui/dialog.jsx
import * as Dialog from '@radix-ui/react-dialog';

<Dialog.Overlay className="fixed inset-0 bg-black/50" />
<Dialog.Content className="fixed left-1/2 top-1/2 …">

</Dialog.Content>
Radix behavior, Tailwind classes

05 workflow

From a copied component to a styled dialog

No install, no bundler, no dev server — the whole loop from a component in your ui/ folder to a working, styled dialog.

shadcn-ui — xcodx
  • new project → shadcn/ui
  • created src/components/ui/* · Radix via esm.sh
  • edit button.jsx variant classes
  • Tailwind regenerated · button restyled live
  • open the dialog, tab through it
  • focus trapped, escape closes — Radix behavior
  • git commit -m "own the button + dialog"
  • [main c40b7d2] own the button + dialog · 4 files
  • You edit the source

    Restyling is changing classes in a file you own, not passing props to a package you cannot see into.

  • The same loop on a tablet

    React, Tailwind and Radix run client-side, so an iPad renders and tests the components the same way a laptop does.

  • It leaves with you

    Export the zip and the components are ordinary source, because the copy-paste model never locked them in.

06 ecosystem

shadcn/ui among the component kits

shadcn/ui is one of several component approaches the editor runs — the same tab compiles React, Tailwind and Radix together, per file.

  • React
  • Vue
  • Angular
  • Svelte
  • SolidJS
  • Lit
  • HTMX
  • Vite
  • TypeScript
  • JavaScript
  • HTML
  • CSS
  • SCSS
  • Less
  • Pug
  • Tailwind
  • Bootstrap
  • Vuetify
  • Ant Design
  • shadcn/ui
  • Phaser
  • Node.js
  • Python
  • Java
  • C++
  • C#
  • Go
  • Rust
  • Ruby
  • PHP
  • Kotlin
  • Swift
  • SQL
  • Bash

07 languages

What the editor compiles around shadcn/ui

A shadcn/ui project sits beside everything else the editor compiles in the browser, renders natively, or runs on demand.

Compiled in your browser11

Zero build step. Transform runs on a Web Worker, so typing never blocks.

  • JSX
  • TSX
  • TypeScript
  • Vue SFC
  • Svelte
  • Angular (JIT)
  • SolidJS
  • SCSS
  • Sass
  • Less
  • Pug

Rendered natively8

Straight to the live preview, no transform in the way.

  • HTML
  • CSS
  • JavaScript
  • JSON
  • Markdown
  • Jupyter (.ipynb)
  • SVG
  • YAML

Executed on demand22

70+ languages run through a self-hosted Piston engine. stdout, stderr, images and tracebacks land in the console.

  • Python
  • Java
  • C
  • C++
  • C#
  • Go
  • Rust
  • Ruby
  • PHP
  • Kotlin
  • Swift
  • Lua
  • Scala
  • Perl
  • Haskell
  • Elixir
  • Dart
  • R
  • Julia
  • SQLite
  • Bash
  • PowerShell

08 questions

shadcn/ui in the browser — common questions

Do I install shadcn/ui as a package?

No, and that is the model. shadcn/ui components are copied into your project as source you own, built on Radix primitives and Tailwind. Here the Radix packages resolve from npm through esm.sh and Tailwind is generated by its browser engine, so nothing needs a local install.

Can I edit the components?

Yes — that is the point. The components live in src/components/ui as real source, so restyling is editing Tailwind classes and adding a variant is a line of class-variance-authority, all in files you control rather than behind a package boundary.

Does the Radix behavior work here?

Yes. Focus traps, keyboard navigation and accessible roles come from the real Radix primitives resolved from npm, so a dialog, dropdown or tabs component behaves correctly, not just looks correct.

Is Tailwind required, and does it work?

Yes and yes. shadcn/ui styles its components with Tailwind utilities, and the official Tailwind browser engine generates them live here, so editing a component's classes restyles it immediately with no build.

Can I use TypeScript?

Yes. Write .tsx for typed props and variants; the types are stripped on the fast pass that compiles the code, so a typed component adds no runtime cost.

Can I take the components to my own project?

Yes. Export the project as a zip and the ui/ components are ordinary source, because the copy-paste model means you owned them all along — there is no dependency to reinstall.

Do I need to install anything to use XCODX Studio?

No. XCODX Studio is a browser-based IDE — the editor, the compilers and the preview all run client-side. There is no download, no package manager to set up and no configuration file to write. Opening the editor is the whole setup step.

Where is my code stored?

In your own browser. Projects, file history and Git objects live in local storage on your device and are never uploaded to a server. That also means XCODX works offline: it is a Progressive Web App, so you can install it and keep coding with no connection.

Is XCODX Studio free?

Yes. The editor, the live preview, the 70+ language runtimes, npm installs, Git and the integrated terminal are all free to use.

Can I use XCODX on a tablet or Chromebook?

Yes. The editor is a responsive web app, so a Chromebook, an iPad or an Android tablet gets the same compilers and the same preview a laptop does — there is no desktop-only build, because there is no build to install at all. The layout adapts to the screen rather than shrinking a desktop UI into it.

Can I export a project or move it to my own machine?

Yes. Export the whole project as a zip with its folder structure intact and open it locally, or commit it and push. It is ordinary source on disk from that point on — no proprietary format and no lock-in, which is also why importing an existing repository from GitHub works the same way in reverse.