This episode dissects the basic options of rehype-pretty-code: theme, keepBackground, defaultLang, grid, and bypassInlineCode. You will also understand the HTML output structure of figure, pre, and code along with the data attributes that become the anchors for CSS styling.

The hello world pipeline in episode 3 only used one option: theme. In fact, rehype-pretty-code provides many basic options that determine highlighting behavior and the shape of the output markup. Episode 4 dissects the five most fundamental options: theme, keepBackground, defaultLang, grid, and bypassInlineCode.
Besides understanding the meaning of each option, you also need to understand the HTML output structure produced. This <figure>, <pre>, and <code> markup with data attributes is what you'll be styling with CSS across all your content projects.
The theme option determines the color palette Shiki uses when tokenizing. Its value can be a built-in theme name string, a Shiki theme object, or an object containing several themes for light and dark modes.
.use(rehypePrettyCode, {
theme: "github-dark-default",
})The default value is github-dark-default. Because this theme is dark, make sure you also set a background in CSS so the code stays readable. In episode 15 we'll dig into the theme object for dual light and dark modes.
Shiki themes usually include a background color. The keepBackground option determines whether that background is copied into the HTML output or not.
.use(rehypePrettyCode, {
theme: "one-dark-pro",
keepBackground: false,
})Its default value is true, meaning the theme background is used. If you want to manage the background yourself through CSS, set keepBackground to false. This is useful when the page background is already decided and only the token colors are needed from the theme.
The defaultLang option determines the language used when a fenced code block doesn't include a language meta.
.use(rehypePrettyCode, {
defaultLang: "plaintext",
})Without defaultLang, code blocks without a language meta aren't highlighted and are left plain. Setting defaultLang to plaintext keeps the code intact without colors, while a value like ts provides highlighting even when the author forgets to mention the language.
The grid option adds grid characters behind each token to help with visual alignment when the code element is rendered as a CSS grid.
.use(rehypePrettyCode, {
grid: true,
})This feature is useful when you use CSS grid for code lines, for example in a layout with line numbers that must always stay aligned. Grid characters are usually hidden visually via CSS with a transparent color.
By default rehype-pretty-code doesn't touch inline code, i.e., text wrapped in a single pair of backticks. The bypassInlineCode option, which defaults to true, creates that behavior.
.use(rehypePrettyCode, {
bypassInlineCode: false,
})When set to false, inline code can be highlighted with syntax like `kode{:js}`. We'll practice the full feature in episode 9, because it affects many parts of documentation writing.
One of the biggest differences of rehype-pretty-code is the shape of the markup produced. A fenced code block:
const s = "halo";will be turned into a <figure> structure wrapping <pre> and <code>:
<figure data-rehype-pretty-code-figure>
<pre data-theme="github-dark-default">
<code data-language="ts">
<span>const</span>
<span>s</span>
</code>
</pre>
</figure>This structure gives you clear CSS "anchors". The <figure> element can be a container with border and radius, <pre> can be set for scrolling, and <code> for font and padding.
Every feature you request through a meta string is translated into data attributes. For example, highlighted lines produce data-highlighted-line, and line numbers produce data-line-numbers on the <code> element.
[data-rehype-pretty-code-figure] pre {
border-radius: 8px;
overflow-x: auto;
}CSS rules like [data-rehype-pretty-code-figure] pre don't need any extra class from you. Just rely on the attributes that are already generated, and the entire visual theme of the code block can be controlled from one place.
Key takeaways:
theme sets the color palette, defaulting to github-dark-default.keepBackground controls whether the theme background is copied.defaultLang becomes the fallback language for code blocks without meta.grid helps with visual alignment of code lines.bypassInlineCode controls whether inline code is also highlighted.<figure> with <pre> and <code> rich in data attributes.In episode 5 you'll learn to choose languages and themes properly: how to write the language meta on fenced code blocks, get to know the language list from @shikijs/langs, and choose a suitable built-in theme and manage its background yourself.