SyntaxHighlightedCode¶
The primary public composable for rendering syntax-highlighted code blocks in Compose.
It shows plain monospace text immediately, then swaps to highlighted text when async highlighting completes. This keeps first paint fast and avoids visible flicker.
Full API in Dokka:
SyntaxHighlightedCodeHighlightThemeProviderrememberHighlightedCoderememberHighlightedCodeBothThemes
When to use it¶
- You want a ready-made code block UI with language badge and copy button.
- You want theme-aware code rendering with minimal setup.
- You prefer built-in loading behavior and error fallback over wiring a custom pipeline.
Key parameters¶
language- highlight.js language id ("kotlin","python","sql", etc).theme- pass explicitly, or rely onHighlightThemeProvider.style- controls code block visuals (CodeBlockStyle).showLineNumbers- enables line-number gutter.languageLabelandcopyButton- slots for header customization, ornullto hide.placeholder- custom loading content while highlighting is in progress.onHighlightCompleteandonError- observability hooks for metrics and diagnostics.
Recommended patterns¶
Use with HighlightThemeProvider (recommended)¶
import dev.hossain.highlight.ui.HighlightThemeProvider
import dev.hossain.highlight.ui.SyntaxHighlightedCode
import dev.hossain.highlight.ui.rememberTomorrowNightTheme
import dev.hossain.highlight.ui.rememberTomorrowTheme
HighlightThemeProvider(
lightHighlightTheme = rememberTomorrowTheme(),
darkHighlightTheme = rememberTomorrowNightTheme(),
) {
SyntaxHighlightedCode(
code = snippet,
language = "kotlin",
showLineNumbers = true,
)
}
With an explicit theme¶
import dev.hossain.highlight.ui.SyntaxHighlightedCode
import dev.hossain.highlight.ui.rememberTomorrowTheme
SyntaxHighlightedCode(
code = "SELECT * FROM users WHERE active = 1",
language = "sql",
theme = rememberTomorrowTheme(),
)
Hide header elements¶
import dev.hossain.highlight.ui.SyntaxHighlightedCode
SyntaxHighlightedCode(
code = snippet,
language = "json",
languageLabel = null, // hide language badge
copyButton = null, // hide copy button
)
Custom copy button¶
import dev.hossain.highlight.ui.SyntaxHighlightedCode
SyntaxHighlightedCode(
code = snippet,
language = "kotlin",
copyButton = { onClick ->
IconButton(onClick = onClick) {
Icon(Icons.Default.ContentCopy, contentDescription = "Copy")
}
},
)
Custom language label¶
import dev.hossain.highlight.ui.SyntaxHighlightedCode
SyntaxHighlightedCode(
code = snippet,
language = "kotlin",
languageLabel = {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(Icons.Default.Star, contentDescription = null, modifier = Modifier.size(12.dp))
Spacer(Modifier.width(4.dp))
Text("Kotlin", fontWeight = FontWeight.Bold, fontSize = 12.sp)
}
},
)
Timing callback¶
import dev.hossain.highlight.ui.SyntaxHighlightedCode
SyntaxHighlightedCode(
code = snippet,
language = "kotlin",
onHighlightComplete = { result ->
Log.d("Perf", "Highlighted in ${result.durationMs}ms, ${result.spanCount} spans")
},
)
Custom placeholder while loading¶
import dev.hossain.highlight.ui.SyntaxHighlightedCode
SyntaxHighlightedCode(
code = snippet,
language = "kotlin",
placeholder = { rawCode ->
Text(
text = rawCode,
color = Color.Gray.copy(alpha = 0.5f),
fontFamily = FontFamily.Monospace,
)
},
)
Why HighlightThemeProvider matters¶
HighlightThemeProvider creates one shared HighlightEngine (one hidden WebView) for its subtree.
If you render multiple code blocks on one screen, this avoids creating one WebView per block and
reduces warm-up cost and memory overhead.
Force a specific theme mode¶
import dev.hossain.highlight.ui.HighlightThemeProvider
import dev.hossain.highlight.ui.rememberTomorrowNightTheme
import dev.hossain.highlight.ui.rememberTomorrowTheme
HighlightThemeProvider(
darkTheme = userPrefersDark,
lightHighlightTheme = rememberTomorrowTheme(),
darkHighlightTheme = rememberTomorrowNightTheme(),
) { ... }
Lower-level Compose helpers¶
Use these when you want custom rendering but still want the library's highlight pipeline.
rememberHighlightedCode¶
Returns highlighted text as State<AnnotatedString?>. Render a plain-text fallback while null.
val highlighted by rememberHighlightedCode(code = snippet, language = "kotlin")
Text(text = highlighted ?: AnnotatedString(snippet))
Use onHighlightComplete for metrics and onError for typed failure handling.
val highlighted by rememberHighlightedCode(
code = snippet,
language = "kotlin",
onHighlightComplete = { result ->
metrics["highlightMs"] = result.durationMs
},
onError = { error ->
Log.d("Highlight", "Failed: ${error.message}")
},
)
rememberHighlightedCodeBothThemes¶
Highlights once, then returns both light and dark AnnotatedString variants so UI theme switching
can happen without extra highlight latency.
val themed by rememberHighlightedCodeBothThemes(
code = snippet,
language = "kotlin",
)
Text(
text = if (isDark) themed?.dark ?: AnnotatedString(snippet)
else themed?.light ?: AnnotatedString(snippet),
)
Inside HighlightThemeProvider, light and dark themes default from the provider. Outside a
provider, pass both themes explicitly.