The easy wayto shadcn.

Hand-stitched wrappers over shadcn/ui that swap nested children for flat props. Eighty percent of your UI ships with one tag. The other twenty — drop down to the primitive. No lock-in. No black box.

Install any componentshadcn CLI
$ pnpm dlx shadcn@latest add @easy-shadcn/card

Paste into any shadcn-ready repo

A small library on purpose. Each component earns its way in by collapsing a recurring shadcn pattern into something you'd type without thinking.

30
components
and growing
80/20
by design
no slot abuse
01
line install
shadcn CLI
100%
yours
MIT, copy & own

Less wrapping.
More shipping.

The same card. Same behavior. Same primitive underneath. Pull once and watch the ladder fold flat.

card.tsx · raw shadcn/ui · 13 ln
1<Card>
2 <CardHeader>
3 <CardTitle>New invoice</CardTitle>
4 <CardDescription>Due in 14 days.</CardDescription>
5 <CardAction>
6 <Button variant="ghost">Edit</Button>
7 </CardAction>
8 </CardHeader>
9 <CardContent>Net 30 · $1,240.00</CardContent>
10 <CardFooter>
11 <Button>Send</Button>
12 </CardFooter>
13</Card>

Reduction: 13 → 7 lines · same primitives

Need the other 20%? Use the primitive →

Twenty-eight stops.
Four lines.

We don't ship a component until it collapses a real pattern. If you've copy-pasted a shadcn structure three times this month, it belongs here.

ALine A

Content & layout

  1. A01

    Accordion

    Items array in. Expandable panels out. No nested triple per row.

    @easy-shadcn/accordion
  2. A02

    Alert

    Status banners with title, description and action. One tag.

    @easy-shadcn/alert
  3. A03

    Avatar

    src + fallback, plus a badge slot. Initials when the image 404s.

    @easy-shadcn/avatar
  4. A04

    Breadcrumb

    Trail of items in. Auto current page and collapsing ellipsis out.

    @easy-shadcn/breadcrumb
  5. A05

    Card

    Flat slots for title, description, action and footer.

    @easy-shadcn/card
  6. A06

    Empty

    Media, title, description and content. No compound scaffolding.

    @easy-shadcn/empty
  7. A07

    Progress

    value in, bar out — null for indeterminate. Label included.

    @easy-shadcn/progress
  8. A08

    Sidebar

    One nav tree, desktop offcanvas and mobile sheet — shell included.

    @easy-shadcn/sidebar
  9. A09

    Tabs

    Items array in. Tabs out. Heterogeneous? Use the primitive.

    @easy-shadcn/tabs
  10. A10

    Tooltip

    Wrap an element, pass content. Its own provider — zero setup.

    @easy-shadcn/tooltip

BLine B

Forms & input

  1. B01

    Calendar

    Three-view month/year navigation. No more native dropdowns.

    @easy-shadcn/calendar
  2. B02

    Checkbox

    A box and its label, in one tag. Disabled and all.

    @easy-shadcn/checkbox
  3. B03

    Checkbox Group

    Items array in, checked values out. Per-item disabled included.

    @easy-shadcn/checkbox-group
  4. B04

    Choice Group

    Single or multiple, radio, checkbox, or toggle — one value model.

    @easy-shadcn/choice-group
  5. B05

    Combobox

    Type to filter items, pick one. Custom filter and empty states.

    @easy-shadcn/combobox
  6. B06

    Date Picker

    Single, multiple, range, inline-input — one component.

    @easy-shadcn/date-picker
  7. B07

    Field

    Label, control, description, error — correctly wired together.

    @easy-shadcn/field
  8. B08

    Input Group

    Start and end addons around an input. No flex gymnastics.

    @easy-shadcn/input-group
  9. B09

    Input OTP

    One real input. Slots, groups, and separators generated.

    @easy-shadcn/input-otp
  10. B10

    Radio Group

    Options array in. Wired-up radio rows out. Labels and a11y included.

    @easy-shadcn/radio-group
  11. B11

    Select

    Items, value, async search. The state machine, fully owned.

    @easy-shadcn/select
  12. B12

    Slider

    A labeled slider with showValue. No markup per mark.

    @easy-shadcn/slider
  13. B13

    Switch

    A labeled toggle. Checked state without ceremony.

    @easy-shadcn/switch

CLine C

Overlays & dialogs

  1. C01

    Alert Dialog

    Confirm the dangerous thing. Async onConfirm, destructive variant.

    @easy-shadcn/alert-dialog
  2. C02

    Dropdown Menu

    Menu items as data — icons, shortcuts, destructive rows.

    @easy-shadcn/dropdown-menu
  3. C03

    Context Menu

    Right-click target in. Flat actions at the pointer out.

    @easy-shadcn/context-menu
  4. C04

    Menu

    Persistent nav from one tree. Selection, submenus, groups, keys.

    @easy-shadcn/menu
  5. C05

    Modal

    Imperative alert & confirm, ready for command palettes.

    @easy-shadcn/modal
  6. C06

    Popover

    Trigger and content, anchored. Placement without plumbing.

    @easy-shadcn/popover
  7. C07

    Sheet

    An edge panel with title, description, footer — pick a side.

    @easy-shadcn/sheet

DLine D

Data & actions

  1. D01

    Async Button

    Returns a Promise? It handles loading, icons and anti-flash.

    @easy-shadcn/async-button
  2. D02

    Pagination

    Client state or route links — two modes, never mixed.

    @easy-shadcn/pagination
  3. D03

    Table

    columns + dataSource + rowKey. Row selection with per-row control.

    @easy-shadcn/table

Modals, by command.

The registry gives you components to copy. This one is a real npm package: an imperative modal manager whose promise settles with whatever the user decided.

npm@easy-shadcn/command-modaltsx
const modal = useModal(ConfirmDialog)

// somewhere in a handler:
const ok = await modal.show({ orderId: "A-1042" })
if (ok) await archiveOrder(orderId)
  • Imperativeshow(), hide(), resolve(value) — from anywhere.
  • Promise-basedawait the modal; get the user's answer back.
  • UI-agnosticAdapters for shadcn (default) and antd v6.
  • Zero dependenciesReact ≥ 18. Strictly typed. MIT.
$ pnpm add @easy-shadcn/command-modalRead the docs

The eighty/twenty
principle, in writing.

IRule 1 / 3

Flat props, not nested children.

One prop per slot. No more <CardHeader><CardTitle> ladders. Eighty percent of layouts ship with one tag.

IIRule 2 / 3

Composition stays primitive.

Compose layer never grows render props or slot objects. Need the other twenty? Drop down to components/ui/* — the door is unlocked.

IIIRule 3 / 3

Your code, your repo.

Installed through the shadcn CLI. Every component lives inside your project, fully owned and trivially patched. No black box.

"Every prop is a debt. We pay it back by leaving the primitive unlocked — so the twenty percent of users who need more don't have to fight us for it."
— The library author, in the house rules

Stop wrapping.
Start shipping.

Install any componentshadcn CLI
$ pnpm dlx shadcn@latest add @easy-shadcn/card

One command. The code lands in your repo.