Learn Shiki Rehype Pretty Code - Basic Options of rehype-pretty-code
Episode 4 of 23

Learn Shiki Rehype Pretty Code - Basic Options of rehype-pretty-code

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.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

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.

Reading the Basic Options

theme: Setting the Main Color Palette

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.

JSSet the theme
.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.

keepBackground: Controlling the Background from the Theme

Shiki themes usually include a background color. The keepBackground option determines whether that background is copied into the HTML output or not.

JSDisable the built-in background
.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.

Options for Code and Grid

defaultLang: Fallback Language

The defaultLang option determines the language used when a fenced code block doesn't include a language meta.

JSFallback language
.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.

grid: Adding Grid Characters

The grid option adds grid characters behind each token to help with visual alignment when the code element is rendered as a CSS grid.

JSEnable 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.

bypassInlineCode: Controlling Inline Code

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.

JSEnable inline highlighting
.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.

Understanding the HTML Output Structure

From a Plain pre to a Structured figure

One of the biggest differences of rehype-pretty-code is the shape of the markup produced. A fenced code block:

JSExample markdown input
const s = "halo";

will be turned into a <figure> structure wrapping <pre> and <code>:

JSSimplified output structure
<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.

Data Attributes as the Styling API

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.

Styling based on data attributes
[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.

Conclusion

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.
  • The standard output is a <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.

Learn Shiki Rehype Pretty Code - Basic Options of rehype-pretty-code | Learn Shiki Rehype Pretty Code