Rehype Pretty Code is a Rehype plugin powered by the Shiki syntax highlighter that provides beautiful code blocks for Markdown or MDX. It's fast since it avoids runtime syntax highlighting by executing at build-time, and works with new features like React Server Components.
Perfect syntax highlighting
Leverage the accuracy of VS Code's syntax highlighting engine and the popularity of its themes ecosystem — use any VS Code theme you want!
jsimport Document, { Html, Head, Main, NextScript } from "next/document"; // 🔥 Super granular and accurate highlighting export default class MyDocument extends Document { static async getInitialProps(ctx) { const initialProps = await Document.getInitialProps(ctx); return { ...initialProps }; } render() { return ( <Html> <Head /> <body className='bg-zinc-800 text-zinc-200'> <Main /> <NextScript /> </body> </Html> ); } }
Line numbers are supported
jsimport { useFloating } from "@floating-ui/react"; function MyComponent() { const { refs, floatingStyles } = useFloating(); return ( <> <div ref={refs.setReference} /> <div ref={refs.setFloating} style={floatingStyles} /> </> ); }
Word highlighting
jsimport { useFloating } from "@floating-ui/react"; function MyComponent() { const { refs, floatingStyles } = useFloating(); return ( <> <div ref={refs.setReference} /> <div ref={refs.setFloating} style={floatingStyles} /> </> ); }
Inline code highlighting
The result of [1, 2, 3].join('-')
is '1-2-3'
.
Context-aware inline code
For instance, if you had the following code block:
jsfunction getStringLength(str) { return str.length; }
When we refer to getStringLength
as a plain variable,
we can color it as a function. Same with function
, or
str
vs. str
, etc. This allows
you to semantically tie inline code with the nearest code block it's referring
to.
ANSI highlighting
ansivite v2.8.6 dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose ready in 125ms. 8:38:02 PM [vite] hmr update /src/App.jsx
Inline ANSI: > Local: http://localhost:3000/
Installation
Install via your terminal:
shellnpm install rehype-pretty-code shiki
Usage
jsimport { unified } from "unified"; import remarkParse from "remark-parse"; import remarkGfm from "remark-gfm"; import remarkRehype from "remark-rehype"; import rehypeStringify from "rehype-stringify"; import rehypePrettyCode from "rehype-pretty-code"; async function main() { const file = await unified() .use(remarkParse) .use(remarkGfm) .use(remarkRehype) .use(rehypePrettyCode, { // See Options section below. }) .use(rehypeStringify) .process("`const numbers = [1, 2, 3]{:js}`"); } main();
MDX
The following example shows how to use this package with Next.js.
jsconst rehypePrettyCode = require("rehype-pretty-code"); const fs = require("fs"); /** @type {import('rehype-pretty-code').Options} */ const options = { // See Options section below. }; const withMDX = require("@next/mdx")({ extension: /\.mdx?$/, options: { remarkPlugins: [], rehypePlugins: [[rehypePrettyCode, options]], }, });
Make sure you have disabled the
mdxRs
option for Next.js 13 / app dir, as it currently does not support Rehype plugins.
Options
To customize the theme and highlighting, options can be specified.
Code block styles
Code blocks are unstyled to give you full control. Code blocks however assume a grid style, so ensure the following style is present:
csspre > code { display: grid; }
This allows line highlighting to span the entire width of a horizontally-scrollable code block.
You can disable this setting if necessary:
jsconst options = { grid: false, };
Theme
The default theme is github-dark-dimmed
. Shiki has a bunch of
pre-packaged themes, which can
be specified as a plain string:
jsconst options = { theme: "one-dark-pro", };
But you can use your own theme as well by passing the theme JSON:
js// ESM const options = { theme: JSON.parse( readFileSync(new URL("./themes/theme.json", import.meta.url)) ), };
js// CJS const options = { theme: JSON.parse( fs.readFileSync(require.resolve("./themes/dark.json"), "utf-8") ), };