You will get to know the big changes in Shiki 4.x and rehype- pretty-code 0.14.x: the highlighter API overhaul with the engine option, typed token metadata ThemedToken.type, splitting langs and themes into separate packages, and full ESM support.

The ecosystem keeps moving, and the end of 2025 marked a big change: Shiki 4.x overhauled the core API, while rehype-pretty-code 0.14.x adapted and added support for new features. Knowing what changed lets you migrate without stumbling.
Episode 20 summarizes the latest stable features: the highlighter API overhaul and the engine option, the ThemedToken.type token metadata, splitting langs, themes, and transformers into separate packages, plus improvements in rehype-pretty-code like the inline character highlighting fix and full ESM support.
Shiki 4.x was released in early 2026 with an architecture redesigned from 3.x. The main shiki package now uses a WebAssembly-based engine and exposes a more explicit API. Meanwhile, rehype-pretty-code 0.14.x added full support for Shiki 4 after previously supporting Shiki 1.x to 3.x.
Both now run with full ESM. You need "type": "module" in the package or an .mjs extension when using them in Node.js, and Next.js uses next.config.mjs for the MDX configuration.
Before migrating, confirm the version you use:
node -p "require('./node_modules/shiki/package.json').version"This command reads the exact version from the installed package file, more accurate than documentation claims. Compare it with the latest version in the registry using npm view shiki version.
In Shiki 4, creating a highlighter requires a clear engine. You choose the Oniguruma or JavaScript engine:
import { createHighlighter } from "shiki";
import { createOnigurumaEngine } from "@shikijs/engine-oniguruma";
const highlighter = await createHighlighter({
langs: ["typescript"],
themes: ["github-dark-default"],
engine: createOnigurumaEngine(),
});The engine option is now part of the API contract, not an internal detail. This gives library integrators full control while making testing with different engines easier.
Short APIs like codeToHtml and createHighlighterCore remain available, but all paths now share the same contract. Deprecated functions like getHighlighter are replaced by createHighlighter, and the singleton pattern is centralized in getSingletonHighlighter. This consistency makes migrating code between versions more predictable.
One of the important additions in Shiki 4 is the ThemedToken.type property on tokens. Besides content and color, each token now carries a semantic classification like keyword, string, or comment. This data opens the door to smarter transformations:
const result = await highlighter.codeToTokens(
"const x = 1;",
{ lang: "typescript", theme: "github-dark-default" },
);
for (const line of result.tokens) {
for (const token of line) {
if (token.type === "keyword") {
console.log(token.content);
}
}
}With token.type, you can filter tokens by their role, not their text. This is far more reliable than manually matching strings for needs like annotations or static analysis.
For tool builders, this metadata enables features that were previously difficult: marking all keywords with a special style, exporting tokens to other formats with complete semantics, or building tests that verify colors per category. Shiki transformers also leverage this metadata for more precise word highlighting.
Since v4, languages, themes, and transformers are no longer one monolithic bundle. You import per package:
npm i @shikijs/langs @shikijs/themes @shikijs/transformersEach package is responsible for one domain: @shikijs/langs for grammars, @shikijs/themes for color palettes, and @shikijs/transformers for token transformations. This split keeps bundles small and allows adding grammars without touching themes.
rehype-pretty-code configuration can now reference language and theme ids without extra imports because the bundle already carries the references. For full control, you import specific modules like @shikijs/themes/nord directly. You already practiced this pattern in episode 12.
rehype-pretty-code 0.14.x runs as a pure ESM package and delegates the highlighting engine to Shiki 4. Migration from 0.13 usually only requires a dependency update because core options like theme, keepBackground, and defaultLang haven't changed. Make sure your config files use ESM so imports run smoothly.
Version 0.14 fixes character highlighting on inline code. The old-version problem where inline character highlighting was inconsistent with blocks is now handled better. You can mark specific tokens inside a sentence with the same result as in a code block.
npm view rehype-pretty-code versionThis command makes sure you're on the latest 0.14 release before using that feature.
Key takeaways:
ThemedToken.type carries semantic metadata for each token.npm view before using new features.In episode 21 you'll assemble a production-ready configuration: combining the final configuration with transformers, dual themes, selected langs, complete CSS styling, an SSG pipeline, plus a CI/CD and maintenance strategy for controlled dependency upgrades.