Use shadcn/ui or shadcn-vue or shadcn-svelte or SolidUI with UnoCSS.
- Based on fisand/unocss-preset-shadcn
- Theme can be easily customized
Follow the official guide to set up shadcn/ui, shadcn-vue, or shadcn-svelte, or SolidUI. Replace the step to set up Tailwind CSS with UnoCSS.
Install the Tailwind Browser Style Reset.
Then install unocss-preset-shadcn
and unocss-preset-animations
, and update your unocss.config.ts
:
ni @unocss/reset
ni -D unocss @unocss/preset-wind3 unocss-preset-animations unocss-preset-shadcn
// unocss.config.ts
import { presetWind } from "@unocss/preset-wind3";
import { defineConfig } from "unocss";
import presetAnimations from "unocss-preset-animations";
import { presetShadcn } from "unocss-preset-shadcn";
export default defineConfig({
presets: [
presetWind(),
presetAnimations(),
presetShadcn(
{
color: "red",
// With default setting for SolidUI, you need to set the darkSelector option.
darkSelector: '[data-kb-theme="dark"]',
},
{
// If you are using reka ui.
componentLibrary: "reka",
}
),
],
// By default, `.ts` and `.js` files are NOT extracted.
// If you want to extract them, use the following configuration.
// It's necessary to add the following configuration if you use shadcn-vue or shadcn-svelte.
content: {
pipeline: {
include: [
// the default
/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
// include js/ts files
"(components|src)/**/*.{js,ts}",
],
},
},
});
Important
Do not run npx shadcn-ui@latest init
or npx shadcn-vue@latest init
or npx shadcn-svelte@latest init
or npx solidui-cli@latest init
to initialize your project.
ni lucide-react class-variance-authority clsx tailwind-merge
ni lucide-vue-next radix-vue class-variance-authority clsx tailwind-merge
for shadcn-vue.ni lucide-svelte tailwind-variants clsx tailwind-merge
for shadcn-svelte.ni tailwindcss-animate class-variance-authority clsx tailwind-merge
for SolidUI.
- copy
utils.ts
into your project atsrc/lib
- create
components.json
orui.config.json
(for SolidUI) in your project root and modify as needed npx shadcn-ui@latest add button
npx shadcn-vue@latest add button
for shadcn-vue.npx shadcn-svelte@latest add button
for shadcn-svelte.npx solidui-cli@latest add button
for SolidUI.
Warning
You may need an empty tailwind.config.js
file in your project root to make cli commands happy.
If you encounter problems adjusting animation property, this may be because tailwind-animate has duplicate rules about animation and transition. You can refer to Migration Guide from Animations Preset for UnoCSS to solve this problem.
utils.ts
: this file usually under src/lib
folder.
import type { ClassValue } from "clsx";
import { clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
components.json
: this file should under your project root.
React + shadcn-ui
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"tailwind": {
"config": "tailwind.config.js",
"css": "styles/global.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"rsc": false,
"tsx": true,
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui"
}
}
Vue + shadcn-vue
{
"$schema": "https://shadcn-vue.com/schema.json",
"style": "new-york",
"typescript": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/assets/index.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"composables": "@/composables",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib"
},
"iconLibrary": "lucide"
}
Svelte + shadcn-svelte
{
"$schema": "https://shadcn-svelte.com/schema.json",
"style": "default",
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app.pcss",
"baseColor": "neutral"
},
"aliases": {
"components": "$lib/components",
"utils": "$lib/utils"
}
}
ui.config.json
: this file should under your project root. This file is for SolidUI.
{
"tsx": true,
"componentDir": "./src/components/ui",
"tailwind": {
"config": "tailwind.config.js",
"css": "src/App.css"
},
"aliases": {
"path": "~/*"
}
}
Preview the demo.
If you want to use a dynamic theme, you can pass an array of theme objects to presetShadcn
:
import { defineConfig, presetUno, UserConfig } from "unocss";
import presetAnimations from "unocss-preset-animations";
import { builtinColors, presetShadcn } from "unocss-preset-shadcn";
export default defineConfig({
presets: [
presetUno(),
presetAnimations(),
presetShadcn(builtinColors.map((c) => ({ color: c }))),
],
});
Add a theme sync script to your index.html. To dynamically change the theme, you can create a theme switch component.