Learn Shiki Rehype Pretty Code - Production-Ready Configuration
Episode 21 of 23

Learn Shiki Rehype Pretty Code - Production-Ready Configuration

You will assemble a complete production configuration: transformers, dual themes, selected langs, complete CSS styling, and an SSG pipeline, then set up a CI/CD and maintenance strategy for controlled dependency upgrades.

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

Introduction

In the previous episodes you learned features separately. Now it's time to combine everything into one production-ready configuration: plugins, transformers, dual themes, selected langs, CSS styling, and a consistent build pipeline.

Episode 21 assembles the production-ready configuration: the final rehype-pretty-code config, complete CSS styling for all code block elements, the SSG build pipeline, plus CI/CD and maintenance practices to keep the system stable when dependencies are upgraded.

The Final Configuration

Combining All Options

The production configuration combines transformers, dual themes, and a selective langs list:

JSProduction configuration
import {
  transformerNotationDiff,
  transformerNotationHighlight,
} from "@shikijs/transformers";
 
const rehypePrettyCodeOptions = {
  theme: {
    dark: "github-dark-default",
    light: "github-light-default",
  },
  defaultLang: "plaintext",
  keepBackground: false,
  langs: ["ts", "tsx", "js", "css", "html", "json", "bash"],
  transformers: [
    transformerNotationDiff(),
    transformerNotationHighlight(),
  ],
};

The langs list is limited to the languages that actually appear in the content, the theme uses the dual themes from episode 15, and the transformers add diff and highlight notation. This configuration becomes the single source of truth for all pages.

Installing It in the Pipeline

Register the configuration on the pipeline used by all content:

JSProduction pipeline
unified()
  .use(remarkParse)
  .use(remarkRehype)
  .use(rehypePrettyCode, rehypePrettyCodeOptions)
  .use(rehypeSanitize)
  .use(rehypeStringify);

The plugin order follows the principle from episode 17: highlight before sanitization, sanitization before stringify. This pipeline is used once in the build config, not per page, so behavior stays consistent.

Complete CSS Styling

Preparing All the Elements

A production code block needs styling for the title, highlighted lines, diff, and background. The following example summarizes it in one set of rules:

Complete code block styling
[data-rehype-pretty-code-figure] {
  position: relative;
}
 
[data-rehype-pretty-code-figure] pre {
  background: #ffffff;
  border-radius: 8px;
  overflow-x: auto;
}
 
[data-rehype-pretty-code-figure] span {
  color: var(--shiki-light);
}
 
[data-rehype-pretty-code-figure] [data-highlighted-line] {
  background: rgba(255, 200, 0, 0.12);
}
 
@media (prefers-color-scheme: dark) {
  [data-rehype-pretty-code-figure] pre {
    background: #0d1117;
  }
 
  [data-rehype-pretty-code-figure] span {
    color: var(--shiki-dark);
  }
}

These rules handle the background for both modes, the token colors via CSS variables, and line highlighting. Add the data-added-line and data-removed-line styling from episode 8 to complete the diff.

Separating the Styling File

Keep the styling in a separate CSS file so it doesn't mix with component logic. In Next.js, just import that file in the layout or a global file. This separation makes swapping palettes easy without touching component code.

The SSG Build Pipeline

Guaranteeing Build Consistency

Make sure the build is deterministic: the same result for the same input. Every document goes through the same pipeline, and static assets are produced at build time. Before merging to production, run a full build:

Production build
bun run build

This command runs the content build then the Next.js build in sequence with bun run build. If the build fails, the CI pipeline fails too, so problems are caught before reaching users.

Output Snapshots as a Safety Net

Snapshotting the HTML output of a few key pages prevents unexpected visual changes. Save snapshots after the build and compare them on every change. If a snapshot changes, check whether it's an intended change. This catches subtle regressions that don't appear as errors.

CI/CD and Maintenance

Controlled Dependency Upgrades

Don't jump straight to the newest version without testing. Review the changelog first, then perform the upgrade on a separate branch and run the build and snapshots:

Controlled upgrade
bun add shiki@^4 rehype-pretty-code@^0.14

After upgrading, run all the tests and compare the snapshots. Constrain dependencies with a narrow range so accidental updates don't break the rendered output.

Monitoring Build and Bundle

Watch the build duration and bundle size on every release. A sharp increase indicates a new grammar or asset accidentally entering the bundle. Integrate a size warning into the CI pipeline so performance regressions are detected early.

Conclusion

Key takeaways:

  • The production configuration combines transformers, dual themes, and selective langs.
  • The pipeline is installed once in the build for consistent behavior.
  • Complete styling handles background, token colors, highlighting, and diff.
  • The SSG build is deterministic and validated in CI.
  • Output snapshots prevent unexpected visual regressions.
  • Dependency upgrades are done incrementally with testing and monitoring.

In episode 22 you'll close the series with the alternative ecosystem and a final reflection: comparing Shiki with highlight.js, Prism, and lowlight, plus a recap of the journey from episode 0 to 21 into a production-grade code block checklist.

Learn Shiki Rehype Pretty Code - Production-Ready Configuration | Learn Shiki Rehype Pretty Code