# Wigggle UI: a shadcn-style registry of React widgets you copy in

> Wigggle UI is a Next.js site that publishes React components as a copy-and-paste collection built on shadcn and Radix, with a registry.json describing each item so the shadcn CLI can install it. The components are copied into your own codebase rather than consumed as a dependency, and the site itself is the demo.

**wigggle-ui/ui** — A beautiful collection of copy-and-paste widgets for your next project.

- Repository: https://github.com/wigggle-ui/ui
- Website: https://wigggle-ui.vercel.app
- Stars: 901 · Forks: 54
- Language: TypeScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/wigggle-ui-ui

## A registry, not a package

Wigggle UI describes itself as a beautiful collection of copy-and-paste widgets for your next project, and the demo site is at wigggle-ui.vercel.app.

The repository layout shows the mechanism. There is a registry.json at the root, a registry/ directory, a components/ directory, and an app/ directory holding the Next.js site that displays them. The components.json file at the root is the shadcn configuration, which points at the component path and the aliases the CLI should use.

That combination, a registry.json plus components.json, is the shadcn registry format. The shadcn CLI reads a registry entry and copies the source files into your project rather than adding a dependency. The package.json confirms it with a build:registry script that runs shadcn build and then a script to copy the registry output.

```json
    "build:registry": "shadcn build && tsx ./scripts/copy-registry.mts",
```

So the thing being published is not a library. It is a set of files with a manifest that tells a CLI where to find them, and the npm package is marked private, which means nothing is installed from npm to get the widgets.

That model has an obvious appeal and an obvious cost. The appeal is that the code ends up in your repository and you own it. The cost is the same one: every widget you copy is a widget you now read, review and maintain, and the upstream fixes arrive as diffs you have to apply yourself, or not at all.

## Built on shadcn, Radix and a lot of small utilities

The dependency list is long and it tells you exactly what the components are made of.

The foundation is shadcn itself at 4.21.4, plus a dozen individual Radix packages covering the primitives a component library needs: avatar, dialog, dropdown-menu, label, popover, progress, scroll-area, select, separator, slider, slot, switch, tabs and tooltip. There is also the umbrella radix-ui package at 1.7.0 and @base-ui/react at 1.8.0, which is a different headless component library that appears alongside Radix rather than instead of it.

The rest of the list is the interesting part for anyone assessing how portable a widget is. cmdk for command palettes, embla-carousel-react for carousels, jotai for state, lucide-react for icons, motion for animation at 14.0.0, next-themes for light and dark switching, recharts at 3.8.0 for charts, shiki for syntax highlighting, class-variance-authority, clsx and tailwind-merge for class handling, and the small cn package at 0.4.0 that combines the last three. There is web-haptics at 0.0.6, which is a physical haptic feedback API, and @ncdai/react-wheel-picker from the same author as the OpenPanel sponsor link.

The version numbers are worth noticing too. Next.js is at 16.4.0 and React at 19.3.0, both exact pins rather than ranges, which tells you the registry is built and verified against a specific pair.

Two dependencies are of the analytics and marketing kind rather than the UI kind: @vercel/analytics, @openpanel/nextjs and @wandry/analytics-sdk. The OpenPanel package is the same product as the sponsor badge in the readme, so the site is instrumented with its sponsor's analytics.

The MDX stack, @mdx-js/loader, @mdx-js/react, @next/mdx and hast-util-to-jsx-runtime, is what lets each widget's demo page be written as a Markdown document with live components in it.

## The site is the documentation and the demo at once

The app/ directory holds the Next.js site, and there is an mdx-components.tsx at the root, which is what wires the MDX content to the React components.

This is the part of the model that works well. A copy-and-paste registry has an obvious problem, which is that a static screenshot tells you nothing about how a component behaves, so the demo site has to carry the documentation burden. Here the demo site is a full application, built with Next.js, with the MDX pipeline, the Tailwind setup through postcss.config.mjs and a .prettierrc for the repository's own formatting.

The scripts are the ordinary Next.js ones. next dev, next build, next start, and eslint as the lint task.

```json
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint"
```

There is a proxy.ts at the root, which in a Next.js application is where a rewrite or redirect layer would sit, and a constants/ directory alongside lib/, hooks/, types/ and config/.

The .agents/ directory at the root, together with AGENTS.md and skills-lock.json, indicates the project keeps agent instructions and skills in the repository, which is the same pattern you see in projects that expect coding assistants to contribute to them.

The repository also carries a pnpm-workspace.yaml alongside both a package-lock.json and a pnpm-lock.yaml, which is an odd pair. The package manager field in package.json pins the project to one of them, and the other lock file is probably left over, but it is the kind of inconsistency that makes a lock file untrustworthy, because a contributor running the wrong package manager will produce a different tree without noticing.

## Where the copy-and-paste model strains

Three practical problems, and they are the reason registries like this are usually treated as a starting point rather than a dependency.

The first is the update path. When you copy a widget, you get a snapshot. If upstream fixes a focus trap or a hydration bug, that fix exists in the registry and not in your repository, and the only way to get it is to diff manually. Over a few years you accumulate copies of the same component that have drifted apart in different ways, and at that point the registry stops being a source and becomes an archaeology project.

The second is the dependency footprint of a single widget. A carousel that pulls in embla-carousel-react, cmdk that pulls in a command palette implementation, a chart that pulls in recharts at 3.8.0, and so on. Copying three widgets can mean adding several runtime dependencies to a project that had none. The registry makes the components free in terms of code ownership, but the transitive packages still arrive through your package.json.

The third is the styling contract. These components assume Tailwind with a particular token setup, and they assume shadcn's CSS variables and the cn helper for class merging. Dropping one into a project that styles differently means either adopting the shadcn setup or rewriting the component, and at that point you have copied it in order to replace it.

None of this makes the model bad, it makes it conditional. It works well for a project already on Tailwind and shadcn conventions, and poorly for anything else. And because the model is copy rather than install, the only real protections you have are the licence and the review you do before copying.

## The licence question, and the people to ask

The licensing is stated plainly. Licensed under the MIT license, with a LICENSE.md at the repository root, and the readme points at it directly.

MIT is about as permissive as a licence gets, and for a component library that you copy rather than install, permissive is the right choice. The attribution requirement means you keep the copyright notice in the files you copy. This is not legal advice, but with MIT the practical obligations when you lift a widget are minimal.

The support channel is a GitHub issue tracker, with the readme asking for questions, comments or feedback through an issue. There is no support contract, no service level agreement and no email address, which is the usual arrangement for a community registry.

The sponsors section is worth a mention because it explains the project's shape. OpenPanel is a sponsor and appears both as a light and a dark badge, and Vercel is listed as a sponsor through its OSS program. The OpenPanel badges carry a UTM parameter naming react-wheel-picker, which suggests the sponsor arrangement is partly a per-component deal.

That does not affect the licence or the quality of the components, and it does not mean the maintainers are absent. It does mean that the sustainability of the project is partly a commercial arrangement, which is worth knowing if you are planning to depend on the registry continuing to exist and to keep the components current. A registry whose maintenance is tied to sponsorship may change shape when the sponsorship does.

For support, there is a Discord badge and a GitHub Discussions link in the readme, so the community channels exist alongside the issue tracker.

## Conclusion

Wigggle UI suits a React developer who wants a well made component rather than a library dependency, because the copy-and-paste model means the code is yours to change and there is nothing to keep in sync. It does not suit a team that wants a versioned component package with changelogs and fixes, since copied code is code you now maintain, and it does not suit a project outside React, since the registry is entirely React and Tailwind based. Before adopting anything from it, read the component source rather than the demo, because the demo shows the happy path only, and check which Radix primitives a given widget depends on before copying it into a codebase that already has its own.

## FAQ

### What is Wigggle UI?

It is a collection of copy-and-paste React widgets published as a shadcn-style registry, with the site at wigggle-ui.vercel.app acting as both the demo and the documentation. The components are built on shadcn, Radix UI and Tailwind, and they are copied into your own codebase rather than installed from npm.

### How are the Wigggle UI components installed?

The repository root holds a registry.json describing each item and a components.json pointing at the component path and aliases, which is the shadcn registry format. The build:registry script runs shadcn build and then copies the registry output with tsx ./scripts/copy-registry.mts.

### What do the Wigggle UI components depend on?

The package manifest lists shadcn at 4.21.4, a set of individual Radix primitives, plus cmdk, embla-carousel-react, jotai, lucide-react, motion, next-themes, recharts, shiki, class-variance-authority, clsx, tailwind-merge and the cn helper. Next.js is pinned at 16.4.0 and React at 19.3.0.

### What licence does Wigggle UI use?

MIT, stated in the readme with a LICENSE.md file in the repository root. The project is supported by OpenPanel and by the Vercel OSS program, and questions and feedback are handled through the GitHub issue tracker, Discord and GitHub Discussions.

### How is the Wigggle UI demo site built?

With Next.js, since the app/ directory holds the site and mdx-components.tsx wires MDX content to the components. The scripts are next dev, next build, next start and eslint, and the site uses Tailwind through postcss.config.mjs. The last push was on 2026-10-10 and the package version is 0.5.0.

## Sources

- [Issues](https://github.com/wigggle-ui/ui/issues)
- [License: MIT](https://github.com/wigggle-ui/ui/blob/main/LICENSE)
- [Project website](https://wigggle-ui.vercel.app)
- [README](https://github.com/wigggle-ui/ui/blob/main/README.md)
- [wigggle-ui/ui on GitHub](https://github.com/wigggle-ui/ui)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wigggle-ui-ui
