Shadcn/ui upgrade to Tailwindcss v.4 #2996
Replies: 26 comments 31 replies
-
Jack recorded/noticed some problems migrating shadcn-ui to Tailwind v4 |
Beta Was this translation helpful? Give feedback.
-
It might be time to revisit this since tailwind just dropped a public beta. |
Beta Was this translation helpful? Give feedback.
-
shadcn/ui works with Tailwindcss v4. Here is an example TW4 globals.css file: @import "tailwindcss";
@variant dark (&:is(.dark *));
@plugin "tailwindcss-animate";
@theme {
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
--color-card: hsl(var(--card));
--color-card-foreground: hsl(var(--card-foreground));
--color-popover: hsl(var(--popover));
--color-popover-foreground: hsl(var(--popover-foreground));
--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--primary-foreground));
--color-secondary: hsl(var(--secondary));
--color-secondary-foreground: hsl(var(--secondary-foreground));
--color-muted: hsl(var(--muted));
--color-muted-foreground: hsl(var(--muted-foreground));
--color-accent: hsl(var(--accent));
--color-accent-foreground: hsl(var(--accent-foreground));
--color-destructive: hsl(var(--destructive));
--color-destructive-foreground: hsl(var(--destructive-foreground));
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-chart-1: hsl(var(--chart-1));
--color-chart-2: hsl(var(--chart-2));
--color-chart-3: hsl(var(--chart-3));
--color-chart-4: hsl(var(--chart-4));
--color-chart-5: hsl(var(--chart-5));
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem;
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--border-shadow: 255, 255, 255, 0.145;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
} I am not sure if this is the best way but I would love a very simple Nextjs, Tailwind and shadcn/ui setup on Next v15 and Tailwind v4. I have that working but it seems like there should be a "better way" - I wish shadcn would just fully adopt tailwind variables and not have special "shadcn" variables. Also not sure if this is the best dark mode approach - but it's how shadcn currently works. Cheers! |
Beta Was this translation helpful? Give feedback.
-
Here's one that's a little cleaner and shows various ways to define the colors: @import "tailwindcss";
@variant dark (&:where(.dark, .dark *));
@plugin "tailwindcss-animate";
@theme {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
@layer base {
:root {
--background: var(--color-neutral-50);
--foreground: var(--color-neutral-900);
--card: hsl(0 0% 100%);
--card-foreground: hsl(0 0% 3.9%);
--popover: hsl(0 0% 100%);
--popover-foreground: hsl(0 0% 3.9%);
--primary: hsl(0 0% 9%);
--primary-foreground: hsl(0 0% 98%);
--secondary: hsl(0 0% 96.1%);
--secondary-foreground: hsl(0 0% 9%);
--muted: hsl(0 0% 96.1%);
--muted-foreground: hsl(0 0% 45.1%);
--accent: hsl(0 0% 96.1%);
--accent-foreground: hsl(0 0% 9%);
--destructive: hsl(0 84.2% 60.2%);
--destructive-foreground: hsl(0 0% 98%);
--border: hsl(0 0% 89.8%);
--input: hsl(0 0% 89.8%);
--ring: hsl(0 0% 3.9%);
--chart-1: hsl(12 76% 61%);
--chart-2: hsl(173 58% 39%);
--chart-3: hsl(197 37% 24%);
--chart-4: hsl(43 74% 66%);
--chart-5: hsl(27 87% 67%);
--radius: 0.5rem;
}
.dark {
--background: var(--color-neutral-950);
--foreground: var(--color-neutral-100);
--card: hsl(0, 0%, 3.9%);
--card-foreground: hsl(0 0% 98%);
--popover: hsl(0 0% 3.9%);
--popover-foreground: hsl(0 0% 98%);
--primary: hsl(0 0% 98%);
--primary-foreground: hsl(0 0% 9%);
--secondary: hsl(0 0% 14.9%);
--secondary-foreground: hsl(0 0% 98%);
--muted: hsl(0 0% 14.9%);
--muted-foreground: hsl(0 0% 63.9%);
--accent: hsl(0 0% 14.9%);
--accent-foreground: hsl(0 0% 98%);
--destructive: hsl(0 62.8% 30.6%);
--destructive-foreground: hsl(0 0% 98%);
--border: hsl(0 0% 14.9%);
--input: hsl(0 0% 14.9%);
--ring: hsl(0 0% 83.1%);
--chart-1: hsl(220 70% 50%);
--chart-2: hsl(160 60% 45%);
--chart-3: hsl(30 80% 55%);
--chart-4: hsl(280 65% 60%);
--chart-5: hsl(340 75% 55%);
}
} |
Beta Was this translation helpful? Give feedback.
-
@dstroot I don't think that shadcn/ui works with Tailwindcss v4, most of the shadcn components are not displayed correctly when migrating to v4, and I had to update each component one by one to make them how they was before migration. I rolled back to v3 until official support ... |
Beta Was this translation helpful? Give feedback.
-
Can likely bin the hsl abstraction now thanks to simplified variable colours. @import "tailwindcss";
@plugin "tailwindcss-animate";
@variant dark (&:where(.dark, .dark *));
@theme {
--color-background: var(--color-white);
--color-foreground: var(--color-slate-900);
--color-card: var(--color-white);
--color-card-foreground: var(--color-slate-900);
--color-popover: var(--color-white);
--color-popover-foreground: var(--color-slate-900);
--color-primary: var(--color-slate-900);
--color-primary-foreground: var(--color-slate-50);
--color-secondary: var(--color-slate-100);
--color-secondary-foreground: var(--color-slate-900);
--color-muted: var(--color-slate-100);
--color-muted-foreground: var(--color-slate-500);
--color-accent: var(--color-slate-100);
--color-accent-foreground: var(--color-slate-900);
--color-destructive: var(--color-rose-500);
--color-destructive-foreground: var(--color-slate-50);
--color-border: var(--color-slate-200);
--color-input: var(--color-slate-200);
--color-ring: var(--color-slate-400);
--radius: 0.5rem;
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
@layer theme {
.dark {
--color-background: var(--color-zinc-950);
--color-foreground: var(--color-zinc-50);
--color-card: var(--color-zinc-950);
--color-card-foreground: var(--color-zinc-50);
--color-popover: var(--color-zinc-950);
--color-popover-foreground: var(--color-zinc-50);
--color-primary: var(--color-zinc-50);
--color-primary-foreground: var(--color-zinc-900);
--color-secondary: var(--color-zinc-800);
--color-secondary-foreground: var(--color-zinc-50);
--color-muted: var(--color-zinc-800);
--color-muted-foreground: var(--color-zinc-400);
--color-accent: var(--color-zinc-800);
--color-accent-foreground: var(--color-zinc-50);
--color-destructive: var(--color-rose-700);
--color-destructive-foreground: var(--color-zinc-50);
--color-border: var(--color-zinc-800);
--color-input: var(--color-zinc-800);
--color-ring: var(--color-zinc-300);
}
}
@layer base {
*,
::before,
::after {
border-color: var(--color-border);
}
} |
Beta Was this translation helpful? Give feedback.
-
I like the approach of @dstroot but dark mode wasn't working for me without using the https://play.tailwindcss.com/ErFtdWw2f5?file=css @import "tailwindcss";
@variant dark (&:where(.dark, .dark *));
@plugin "tailwindcss-animate";
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-destructive-foreground: var(--destructive-foreground);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-chart-1: var(--chart-1);
--color-chart-2: var(--chart-2);
--color-chart-3: var(--chart-3);
--color-chart-4: var(--chart-4);
--color-chart-5: var(--chart-5);
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
}
/* Default theme */
@layer base {
:root {
--background: var(--color-white);
--foreground: var(--color-slate-900);
--card: var(--color-white);
--card-foreground: var(--color-slate-900);
--popover: var(--color-white);
--popover-foreground: var(--color-slate-900);
--primary: var(--color-slate-900);
--primary-foreground: var(--color-slate-50);
--secondary: var(--color-slate-100);
--secondary-foreground: var(--color-slate-900);
--muted: var(--color-slate-100);
--muted-foreground: var(--color-slate-500);
--accent: var(--color-slate-100);
--accent-foreground: var(--color-slate-900);
--destructive: var(--color-rose-500);
--destructive-foreground: var(--color-slate-50);
--border: var(--color-slate-200);
--input: var(--color-slate-200);
--ring: var(--color-slate-400);
--chart-1: hsl(12 76% 61%);
--chart-2: hsl(173 58% 39%);
--chart-3: hsl(197 37% 24%);
--chart-4: hsl(43 74% 66%);
--chart-5: hsl(27 87% 67%);
--radius: 0.5rem;
}
.dark {
--background: var(--color-zinc-950);
--foreground: var(--color-zinc-50);
--card: var(--color-zinc-950);
--card-foreground: var(--color-zinc-50);
--popover: var(--color-zinc-950);
--popover-foreground: var(--color-zinc-50);
--primary: var(--color-zinc-50);
--primary-foreground: var(--color-zinc-900);
--secondary: var(--color-zinc-800);
--secondary-foreground: var(--color-zinc-50);
--muted: var(--color-zinc-800);
--muted-foreground: var(--color-zinc-400);
--accent: var(--color-zinc-800);
--accent-foreground: var(--color-zinc-50);
--destructive: var(--color-rose-700);
--destructive-foreground: var(--color-zinc-50);
--border: var(--color-zinc-800);
--input: var(--color-zinc-800);
--ring: var(--color-zinc-300);
--chart-1: hsl(220 70% 50%);
--chart-2: hsl(160 60% 45%);
--chart-3: hsl(30 80% 55%);
--chart-4: hsl(280 65% 60%);
--chart-5: hsl(340 75% 55%);
}
}
/* Theme variant */
@layer base {
[data-theme="example"] {
--background: var(--color-blue-50);
--foreground: var(--color-gray-900);
--card: var(--color-blue-100);
--card-foreground: var(--color-gray-800);
--popover: var(--color-blue-50);
--popover-foreground: var(--color-gray-800);
--primary: var(--color-blue-100);
--primary-foreground: var(--color-gray-900);
--secondary: var(--color-blue-400);
--secondary-foreground: var(--color-gray-800);
--muted: var(--color-emerald-100);
--muted-foreground: var(--color-gray-600);
--accent: var(--color-emerald-200);
--accent-foreground: var(--color-gray-800);
--destructive: var(--color-red-700);
--destructive-foreground: var(--color-gray-200);
--border: var(--color-blue-600);
--input: var(--color-blue-800);
--ring: var(--color-blue-100);
--radius: 0.3rem;
}
.dark [data-theme="example"],
.dark[data-theme="example"] {
--background: var(--color-gray-900);
--foreground: var(--color-gray-200);
--card: var(--color-gray-900);
--card-foreground: var(--color-gray-200);
--popover: var(--color-gray-950);
--popover-foreground: var(--color-gray-200);
--primary: var(--color-blue-500);
--primary-foreground: var(--color-blue-50);
--secondary: var(--color-blue-800);
--secondary-foreground: var(--color-blue-50);
--muted: var(--color-emerald-900);
--muted-foreground: var(--color-gray-500);
--accent: var(--color-emerald-900);
--accent-foreground: var(--color-gray-200);
--destructive: var(--color-red-700);
--destructive-foreground: var(--color-gray-200);
--border: var(--color-blue-800);
--input: var(--color-blue-800);
--ring:var(--color-blue-100);
--radius: 0.3rem;
}
} |
Beta Was this translation helpful? Give feedback.
-
Tailwind CSS v.4 has released so.... 👀 |
Beta Was this translation helpful? Give feedback.
-
Tailwind CSS v4 is out! |
Beta Was this translation helpful? Give feedback.
-
Atleast update the docs page to |
Beta Was this translation helpful? Give feedback.
-
Would love to see a detailed writeup on using Shadcn with Tailwind 4, what implications are, is it too soon for production, best practices and upgrade guide, etc. Hoping to have full out of the box support for React 19 and Tailwind 4 asap |
Beta Was this translation helpful? Give feedback.
-
Thanks to everyone who provided solutions in this thread. The current docs over dark mode / dark theme and provide an example that overrides the built-in @custom-variant dark (&:where(.dark, .dark *)); |
Beta Was this translation helpful? Give feedback.
-
To style a component you could use <span className="bg-white text-rose-600 dark:bg-black dark:text-rose-300">kgaeluiwfkn</span>
<span className="bg-background text-destructive">kgaeluiwfkn</span> In @import "tailwindcss";
// to use manual theme toggling. See https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually
@variant dark (&:where(.dark, .dark *));
// declaration-only, value is asigned later in :root or .dark
// `inline` to use the variable value instead of its reference, to avoid buggy behavior. See https://tailwindcss.com/docs/theme#referencing-other-variables
@theme inline {
--color-background: var(--background); // --background is assigned later
--color-foreground: var(--foreground);
}
@layer base {
// light values
:root {
--background: #f4f5f6; // assigned here
--destructive: var(--color-rose-600);
}
// dark values
.dark {
--background: hsl(225, 8%, 10%); // and also here
--destructive: oklch(72.06% 0.2214 26.17);
}
} The rest is migrating all your codebase from v3 to v4, just follow the migration guide. In short, the command |
Beta Was this translation helpful? Give feedback.
-
This is what worked for me - Environment - Steps to make the Shadcn CLI work -
In my globals.css I also have the ` @import "tailwindcss"; Now run My CLI response - `
Success! Project initialization completed. |
Beta Was this translation helpful? Give feedback.
-
somehow I did, you can check out my starter. |
Beta Was this translation helpful? Give feedback.
-
Can someone help me as I am unable to upgrade my old vite React with tailwind css v3 to tailwind css v4 by using the below command:
The terminal output screenshot: Similar error is being given to all of my projects while migrating from old version to newer tailwind css v4. Even though tailwind.config.js is in root folder in older version but still showing Could not load the configuration file. I'd appreciate it if anyone could provide some leads........ |
Beta Was this translation helpful? Give feedback.
-
Has there been any success with this? |
Beta Was this translation helpful? Give feedback.
-
In my case I used the manual installation of Shadcn and in my CSS file I placed this
and add the components in the normal way |
Beta Was this translation helpful? Give feedback.
-
Any update? |
Beta Was this translation helpful? Give feedback.
-
Seems shadcn is migrating to TW4 in another repo: https://github.com/shadcn/app-tailwind-v4 https://github.com/shadcn/app-tailwind-v4/blob/main/app/globals.css |
Beta Was this translation helpful? Give feedback.
-
Love how the most relied upon libraries are always the last to do anything about compatibility with other most relied upon libraries :D |
Beta Was this translation helpful? Give feedback.
-
Oh boi I ain't using tailwind v4 until shadcn upgrades into v4 lol |
Beta Was this translation helpful? Give feedback.
-
When approximately we expect the component update? Who knows? |
Beta Was this translation helpful? Give feedback.
-
How do you even disable the CSS? I got my own better desing system that I will put on shadcn components anyway. I can't install JS code because CSS that I don't want fails... Anyone got a solution for that? I tried to put "null" for css but then it won't work. I guess gonna have to manually create all folders - so much for CLI. |
Beta Was this translation helpful? Give feedback.
-
you can use the canary one |
Beta Was this translation helpful? Give feedback.
-
Will there be some type of service to migrate existing web apps to v4 once supported? |
Beta Was this translation helpful? Give feedback.
-
When will shadcn ui upgrade to tailwind css v.4? daisyUI has already done so...
Beta Was this translation helpful? Give feedback.
All reactions