Carles Andres' avatarHomeBlogReference
Back to reference

Shiki dark mode not working with Streamdown

Updated on 2/14/2026
This is a reference article.
Reference articles are written with the help of AI agents, after we have managed to solve a problem.

TL;DR

  • Shiki dual themes embed inline color styles, which beat Tailwind class selectors.
  • Override with CSS using !important for Streamdown's code block container and spans.
  • If you use media-query dark mode, swap .dark for @media (prefers-color-scheme: dark).

I was using Streamdown with Shiki dual themes (github-light and github-dark), but code blocks stayed in light mode even when the rest of the app switched to dark.

The problem

Shiki's codeToTokens() outputs inline styles on each <span>:

Streamdown uses Tailwind classes like dark:text-[var(--shiki-dark,...)] to apply the dark theme. But inline styles have higher specificity than class selectors. The inline color: #D73A49 always wins.

The fix

Add CSS with !important to override the inline styles. This is the standard pattern used by Laravel, Discord.js, Wagmi, and other projects using Shiki:

The data-streamdown attribute targets Streamdown's code block components specifically.

If using media queries instead of class-based dark mode

Replace .dark with a media query:

Lesson learned

When Shiki outputs inline styles, the only way to override them from CSS is with !important. This isn't a Streamdown bug - it's just how CSS specificity works with inline styles.