Shadcn Registry · Open Source

Every file UI component
your app will ever need.

Copy-paste components for the complete file experience — upload, preview, manage, navigate. First-class Supabase, S3 and Cloudinary support. Zero config.

Upload pipeline

File Drop

drag & drop · browse

ACTIVE

Validate

MIME · size · type

IDLE

Queue

managed upload queue

LIVE

Rejected

error surfaced to UI

ERR

Supabase

RLS-aware · signed URLs

LIVE

AWS S3

presigned · R2 · MinIO

IDLE

Cloudinary

transforms · presets

IDLE

Storage adapters

24+

Components

5

Headless Hooks

3

Storage Adapters

2

Primitive Layers

0

Config Required

Why Shelf UI

Built different.
Because files deserve it.

No other library treats file management as a complete UI domain. Shelf UI does — from the drop zone to the storage adapter.

01

You own every line.

No package lock-in. Components land directly in your codebase via the shadcn registry. Extend, restyle, delete — zero library abstraction in the way.

npx shadcn@latest add @shelf-ui/dropzone
02

Registry native.

Built on the open shadcn registry spec. One command installs any component with all peer dependencies resolved.

03

Headless hooks included.

Every component ships with its underlying hook. Swap the UI for your own — the logic stays.

04

Radix UI or Base UI.

Shelf UI adapts to your existing component foundation, whether your project is built on Radix UI or Base UI. Consistent APIs, no unnecessary rewrites.

05

Tailwind v4 + TypeScript.

Fully typed. CSS variables. Dark mode out of the box. No config files, no wrappers.

06

Animation-free by default.

No Motion/Framer Motion forced on you. CSS transitions ship by default. Add the --motion flag only when you want it.

npx shadcn@latest add @shelf-ui/dropzone --motion
Storage Adapters

Your storage.
One consistent API.

Swap providers without touching your components. The adapter handles everything — auth, uploads, URLs.

Supabase Storage
Live

The Postgres-native choice.

Bucket config, RLS-aware uploads, signed URLs. Plugs into your existing Supabase project with zero extra setup.

  • Row-level security
  • Signed URL generation
  • Bucket management
useStorageProvider('supabase', config)
AWS S3
Live

Works everywhere S3 works.

Presigned URL flow, progress tracking, multipart uploads. Compatible with R2, Backblaze B2, and MinIO out of the box.

  • Presigned URL uploads
  • Multipart support
  • R2 · Backblaze · MinIO
useStorageProvider('s3', config)
Cloudinary
Live

Media transforms, built in.

Upload presets, on-the-fly transformations, auto-optimization. Replace the Cloudinary widget entirely with Shelf UI components.

  • Upload presets
  • On-the-fly transforms
  • Auto format & quality
useStorageProvider('cloudinary', config)

More adapters coming — Firebase Storage, Azure Blob, ImageKit, Uploadthing

Primitive Support

You choose the foundation.
We support both.

Radix UI or Base UI — identical component API regardless. The registry serves the correct version for your choice.

Radix UI
Default
Base UI
Alternative
WAI-ARIA compliance
Shelf UI component API
shadcn/ui support
Composition pattern
asChild
render prop
Package structure
per-component
single pkg
Active maintenance
slowing
full-time
Migration cost
zero

Switch at any time — zero migration cost.

shelf init --primitive=base-ui
Animation layer — your choice
CSS TransitionsDefault

Zero runtime overhead. All animations run purely via CSS — no JS bundle cost, no hydration delay, no forced dependency.

  • No extra dependency
  • Zero bundle cost
  • Works without JS
npx shadcn@latest add @shelf-ui/dropzone
Motion--motion flag

Opt into Motion (formerly Framer Motion) for physics-based springs, drag interactions, and advanced entrance animations.

  • Spring physics & gestures
  • Drag, reorder, layout animate
  • ~30kb gzipped added
npx shadcn@latest add @shelf-ui/dropzone --motion

Same component API. Same props. The animation layer is an implementation detail — switch without touching your code.

Free · Open Source · MIT License

Start building in
60 seconds.

Add your first component. No config, no wrappers, no surprises.
CSS transitions by default. Motion when you want it.