𝗗𝘆𝗻𝗮𝗺𝗶𝗰 𝗧𝗵𝗲𝗺𝗶𝗻𝗴 𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗖𝗦𝗦-𝗶𝗻-𝗝𝗦

I used to be a huge fan of styled-components. I loved the flexibility. Then I hit a wall.

One project needed to drop runtime weight. I decided to try CSS Modules and native CSS. The result surprised me. I deleted styled-components, Emotion, and goober from my projects. I lost nothing that I actually needed.

The biggest win was not just performance. It was removing the styling dependency. In one project, the CSS-in-JS runtime took up 30% of the client bundle.

Plain CSS has grown up. You no longer need heavy JS libraries for these tasks:

• Nesting: Use native CSS nesting. • Color shifts: Use color-mix(). • Specificity control: Use @layer. • Responsive components: Use container queries.

Here is how you build a theme using only one file and custom properties.

  1. Define tokens in a CSS file.

:root { --color-bg: #ffffff; --color-text: #1a1a1a; --color-accent: #3c7dc4; }

[data-theme="dark"] { --color-bg: #14161a; --color-text: #f5f5f0; --color-accent: #6aa6e8; }

  1. Use those variables in your components.

.button { background: var(--color-accent); color: var(--color-bg); }

  1. Switch themes by changing a single attribute.

function setTheme(theme) { document.documentElement.dataset.theme = theme; localStorage.setItem("theme", theme); }

Components do not need a ThemeProvider. They do not need to re-render. The browser handles the update through the cascade. This keeps most of your app in Server Components.

To avoid the "flash" of the wrong theme on page load, use a tiny inline script in your HTML head:

Stop using JS to generate styles at runtime. Use native CSS variables for your tokens. It results in less code and faster load times.

Source: https://dev.to/kirill_c_7b35589230/dynamic-theming-without-css-in-js-d7e