TailwindCSS v4
To install TailwindCSS v4, please refer to the updated installation and upgrade guides.
1.) New CSS-first configuration (without JavaScript)
Note: Starting from TailwindCSS v4, the CSS-first configuration is recommended. It continues to receive improvements. However, it is still possible to avoid it and use the legacy configuration instead. See below.
As Wongjn mentioned, starting from v4, tailwind.config.js
is deprecated, and instead, you can use a CSS-first configuration with many new CSS directives.
CSS-First Configuration: Customize and extend the framework directly in CSS instead of JavaScript.
Unfortunately, the next-themes documentation currently doesn't include v4-compatible suggestions, but the TailwindCSS v4 documentation provides a solution. By using the @custom-variant directive, you can configure dark mode to apply when the parent is [data-theme="dark"]:
/* CSS-first configuration from TailwindCSS v4.0.0 */
@import "tailwindcss";
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
function toggleDarkMode() {
const body = document.body;
if (body.getAttribute('data-theme') === 'dark') {
body.removeAttribute('data-theme');
} else {
body.setAttribute('data-theme', 'dark');
}
}
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
<style type="text/tailwindcss">
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
/* or can use data-mode instead of data-theme */
/* data-theme suggested by TailwindCSS v4 Docs */
/* data-mode suggested by Next Themes Docs */
</style>
<button
class="px-4 py-2 rounded-lg border
bg-white dark:bg-black
text-black dark:text-white
cursor-pointer
"
onclick="toggleDarkMode()"
>
Toggle mode
</button>
2.) Legacy JavaScript-based configuration (with tailwind.config.js
)
Note: In v4, the JavaScript-based configuration is still usable, although they are working on migrating all functionality to the CSS-first configuration. Most of the legacy JavaScript-based configuration options can be found in the v3 documentation, as this option is primarily kept open for those transitioning from v3.
If you don't like this, you can still use the legacy JavaScript-based configuration in v4 with the @config
directive:
Using a JavaScript config file
JavaScript config files are still supported for backward compatibility, but they are no longer detected automatically in v4.
If you still need to use a JavaScript config file, you can load it explicitly using the @config directive:
@config "../../tailwind.config.js";
The configuration setting has changed by default. However, you have the option to declare the location of your tailwind.config.js
file using a relative path in your default CSS file so you can use it again.
// tailwind.config.js - from TailwindCSS v3.4.1 or v4.0.0
module.exports = {
// data-mode is used as an example, next-themes supports using any data attribute
darkMode: ['selector', '[data-mode="dark"]']
…
}