# shadcn-svelte: copy-and-paste Svelte components built on Bits UI and Tailwind

> shadcn-svelte is a community-led Svelte port of shadcn/ui that ships components you copy into your own repository instead of installing as a dependency. It fits Svelte 5 and SvelteKit teams that want to own the markup and keep Tailwind styling under their control.

**huntabyte/shadcn-svelte** — shadcn/ui, but for Svelte. ✨

- Repository: https://github.com/huntabyte/shadcn-svelte
- Website: https://shadcn-svelte.com
- Stars: 9,173 · Forks: 574
- Language: TypeScript
- License: MIT
- Published: 2026-09-21 · Updated: 2026-09-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/huntabyte-shadcn-svelte

## What shadcn-svelte solves for Svelte teams

Most component libraries hand you a package. You import a Button, you get whatever markup the maintainers decided on, and when you need a different padding scale or an extra aria attribute you either wrap it or fork it. shadcn-svelte takes the opposite route. The README describes the project as "Accessible and customizable components that you can copy and paste into your apps" and tells you to "Use this to build your own component library". The component source lands in your repository, so the file is yours.

That matters most for teams already committed to Tailwind. The project's topics list Tailwind CSS, Svelte 5, SvelteKit and Bits UI, so the styling and the accessibility layer are assumed rather than optional. If your design system lives in Tailwind config and utility classes, the copied components slot in without a second styling vocabulary. If it lives in CSS modules or a token pipeline that does not speak Tailwind, the copied files are mostly Tailwind class strings and you will be rewriting them.

The audience is narrow on purpose. This is for Svelte developers who want shadcn/ui's visual language without adopting React, and who are willing to treat their component folder as application code. The README is explicit that this is an "unofficial community-led Svelte port" and that the maintainers are "not affiliated with shadcn", though they note they got his blessing before starting.

## How the copy-in model and the registry fit together

The repository is a pnpm monorepo. The root package.json names it @shadcn-svelte/monorepo and marks it private, with packages/ and sv-addons/ holding the publishable pieces and docs/ holding the documentation site. The scripts show the shape of the build: build:cli compiles the workspace packages, build:docs builds the site, and postinstall runs the CLI build and then syncs the workspace. The engine constraints are pnpm >= 9 and node >= 20, with the package manager pinned to pnpm@10.32.1.

A recent release list includes shadcn-svelte@1.7.0 and @shadcn-svelte/registry@0.1.1, both dated 2026-09-16, plus shadcn-svelte@1.6.1 from 2026-09-04. The separate registry package is the interesting part: the CLI needs a source of component definitions to fetch from, and that is what a registry provides. When you run an add command, the CLI resolves the component name against the registry, pulls the file contents, and writes them into your project. Nothing is added to your dependencies for the component itself.

That is the whole mechanism, and it explains both the appeal and the cost. The appeal is that there is no runtime package boundary between your app and the component. The cost is that the registry entry you copied stops tracking upstream the moment it is written. Later fixes to that component reach you only if you notice them and copy again. The project's changeset directory and release cadence suggest upstream moves, but nothing in the copy-in model pushes those changes into your tree.

## Installing shadcn-svelte and adding a first component

The README points to https://shadcn-svelte.com/docs for setup instructions rather than spelling them out, so treat the documentation site as the source of truth for exact flags. The monorepo itself is built with pnpm, and the root package.json enforces that choice with a preinstall step that runs npx only-allow pnpm, so anyone cloning the repository needs pnpm available before install will proceed.

To work on the project itself rather than consume it, the sequence the scripts imply is a clone followed by an install and a dev run. The dev script uses concurrently to start the workspace packages and then waits on packages/cli/dist/index.mjs before starting the docs app, which is why the CLI has to build successfully first.

```bash
git clone https://github.com/huntabyte/shadcn-svelte.git
cd shadcn-svelte
pnpm install
pnpm dev
```

The postinstall hook builds the CLI and syncs the workspace, so the install step does real work beyond fetching packages. If you only want to use shadcn-svelte in your own app, you do not clone this repository at all. You follow the docs site, add the registry configuration your project needs, and then add components by name. The README does not print the CLI commands itself, so take the exact invocation from the docs site rather than from this article. After the add command, the expectation is that a component file appears in your project's component directory and that you can import it directly. The exact directory and the import alias are set during init, so check the generated config file rather than assuming a path. Because the file is now yours, editing it is the intended workflow, not a workaround.

## Where the copy-in approach breaks down

The clearest limitation is upgrade cost. A copied component has no version. When shadcn-svelte@1.7.0 changes how a component handles focus or keyboard interaction, your copy does not move. You find out by reading release notes or by hitting the bug yourself, and then you diff your edited file against the current registry entry by hand. Teams with many customized components accumulate a maintenance surface that grows with every component they add.

Accessibility is the second area to be honest about. The project's topics list bits-ui, which is the primitive layer the components are built on, and Bits UI is where the harder interaction behaviour lives. shadcn-svelte supplies the styled wrapper around those primitives. That division means the accessibility guarantees you inherit are mostly Bits UI's, and the parts you are most likely to edit when customizing are the parts closest to your users. Editing markup is easy; keeping the ARIA relationships correct after you edit is not.

There is also a fit question. If your team wants a dependency it can bump in a lockfile and forget, this is the wrong tool. If your app is not on Svelte 5, or not on Tailwind, or not on SvelteKit, the copied files will need adaptation that the registry does not account for. And if you need a component the registry does not have, the copy-in model gives you no fallback beyond writing it yourself against Bits UI.

## shadcn-svelte compared with component libraries you install

The natural comparison is with a conventional Svelte component library, where components arrive as a package dependency and update through your package manager. The difference is ownership versus convenience. A package gives you a version number, a changelog and a single command to move forward. shadcn-svelte gives you the source and the responsibility. Neither is strictly better; they fail in different ways. Package upgrades can break your app in one commit. Copied components can drift quietly for a year.

Within the Svelte ecosystem, the choice often comes down to how much visual control you need. If you are building a product where the components are meant to be invisible infrastructure, a package is less work. If the components are part of the product's identity and you expect to restyle them repeatedly, owning the files pays off. The project's own framing supports the second case: the README's instruction to "build your own component library" is a statement about intent, not a description of a drop-in kit.

One practical distinction is that shadcn-svelte is not a single artifact you install. It is a CLI plus a registry plus documentation. The registry package, @shadcn-svelte/registry, is versioned separately from the CLI, which means the definitions the CLI reads and the CLI that reads them can move independently. That is a reasonable design for a content-driven tool, but it also means a component's availability depends on the registry state at the moment you run the command.

## Maintenance, licensing and what to check before adopting

The repository is not archived, and the last push was on 2026-09-21, the same day as the most recent activity reflected in the release list. Releases in the weeks before that include shadcn-svelte@1.7.0 and shadcn-svelte@1.6.1, with the registry package at 0.1.1. That is a project with recent commits and a changeset-driven release process, which the .changeset directory and the ci:publish script confirm.

For your own upgrade cost, the relevant fact is that nothing in the copy-in model automates it. The project publishes new versions; your copied files do not consume them. Budget for periodically re-reading the component in the docs and diffing it against yours, especially after a major release line moves.

The licence is MIT, stated in the root package.json and in LICENSE.md. MIT is permissive, which generally means you can use the code in commercial and closed-source projects provided the licence notice is preserved, but the actual terms are in the licence file and this is not legal advice. The README's licence section notes the project is built by @huntabyte, CokaKoala and the wider community, so attribution expectations are worth reading directly rather than assuming.

Before adopting, verify three things: that the components you need exist in the registry, that the init step wrote a config your project layout agrees with, and that your team accepts owning the copied files. If any of those is a no, the installed-package route is the better fit.

## Conclusion

Adopt shadcn-svelte if you are on Svelte 5 or SvelteKit and want component source you can edit, with Tailwind and Bits UI already wired in. Do not adopt it if you need a versioned dependency that upgrades itself, or if you are not prepared to maintain the copied files. Before committing, check the components you need actually exist in the docs registry, confirm the CLI writes into the path your project uses, and read the MIT licence text in LICENSE.md rather than relying on the README line.

## FAQ

### What is shadcn-svelte?

It is an unofficial community-led Svelte port of shadcn/ui, described in the README as accessible and customizable components you copy and paste into your apps rather than install as a dependency. The project states it is not affiliated with shadcn, though it says it received his blessing before starting.

### How do I install shadcn-svelte?

The README points to https://shadcn-svelte.com/docs for installation instructions rather than listing them. The repository itself is a pnpm monorepo requiring pnpm >= 9 and node >= 20, and its preinstall step enforces pnpm with npx only-allow pnpm.

### How do I use shadcn-svelte in a project?

You run the CLI to initialize configuration and then add components by name, after which the component source is written into your project and imported directly. Because the file is copied rather than installed, editing it is the intended workflow.

### Is shadcn-svelte good?

That depends on whether you want to own component source. It suits teams on Svelte 5, SvelteKit and Tailwind who expect to restyle components, and it is a poor fit for teams that want a versioned dependency they can bump in a lockfile, since copied components do not track upstream releases.

### Does shadcn support Svelte?

shadcn/ui itself is a React project. shadcn-svelte is a separate, community-led Svelte port that the README says is not affiliated with shadcn, so Svelte support comes from this project rather than from shadcn/ui.

### What is the difference between shadcn-svelte and Bits UI?

Bits UI is listed among the project's topics and provides the underlying primitives, while shadcn-svelte supplies the styled component wrappers around them. That means the interaction and accessibility behaviour largely comes from the primitive layer, and your edits tend to sit on top of it.

## Sources

- [huntabyte/shadcn-svelte on GitHub](https://github.com/huntabyte/shadcn-svelte)
- [License: MIT](https://github.com/huntabyte/shadcn-svelte/blob/main/LICENSE)
- [Project website](https://shadcn-svelte.com)
- [README](https://github.com/huntabyte/shadcn-svelte/blob/main/README.md)
- [Releases](https://github.com/huntabyte/shadcn-svelte/releases)

---

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