Shiki dark mode not working with Streamdown
TL;DR
- Shiki dual themes embed inline
colorstyles, which beat Tailwind class selectors.- Override with CSS using
!importantfor Streamdown's code block container and spans.- If you use media-query dark mode, swap
.darkfor@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.