Syntax Highlighting
Expressive Code’s default syntax highlighter is Shiki, which uses the same engine as VS Code to provide accurate syntax highlighting for over 100 languages.
Usage in markdown / MDX
Regular syntax highlighting
To get syntax highlighting for your code blocks, wrap them in code fences (using three or more backticks) and ensure that your opening code fences include a language identifier, e.g. js
for JavaScript:
```jsconsole.log('This code is syntax highlighted!')```
The rendered result looks like this:
console.log('This code is syntax highlighted!')
Rendering ANSI escape sequences
Expressive Code supports rendering a subset of ANSI escape sequences. This can be useful for displaying formatted terminal output in your documentation.
To enable this feature for a code block, set its language identifier in the opening code fence to ansi
. You can then use the following ANSI escape sequences:
```ansiANSI colors:- Regular: [31mRed[0m [32mGreen[0m [33mYellow[0m [34mBlue[0m [35mMagenta[0m [36mCyan[0m- Bold: [1;31mRed[0m [1;32mGreen[0m [1;33mYellow[0m [1;34mBlue[0m [1;35mMagenta[0m [1;36mCyan[0m- Dimmed: [2;31mRed[0m [2;32mGreen[0m [2;33mYellow[0m [2;34mBlue[0m [2;35mMagenta[0m [2;36mCyan[0m
256 colors (showing colors 160-177):[38;5;160m160 [38;5;161m161 [38;5;162m162 [38;5;163m163 [38;5;164m164 [38;5;165m165[0m[38;5;166m166 [38;5;167m167 [38;5;168m168 [38;5;169m169 [38;5;170m170 [38;5;171m171[0m[38;5;172m172 [38;5;173m173 [38;5;174m174 [38;5;175m175 [38;5;176m176 [38;5;177m177[0m
Full RGB colors:[38;2;34;139;34mForestGreen - RGB(34, 139, 34)[0m
Text formatting: [1mBold[0m [2mDimmed[0m [3mItalic[0m [4mUnderline[0m```
Result:
ANSI colors:- Regular: Red Green Yellow Blue Magenta Cyan- Bold: Red Green Yellow Blue Magenta Cyan- Dimmed: Red Green Yellow Blue Magenta Cyan
256 colors (showing colors 160-177):160 161 162 163 164 165166 167 168 169 170 171172 173 174 175 176 177
Full RGB colors:ForestGreen - RGB(34, 139, 34)
Text formatting: Bold Dimmed Italic Underline
Supported languages
Out of the box, over 100 languages are supported, including JavaScript, TypeScript, HTML, CSS, Astro, Markdown, MDX, JSON, YAML, and many more. You can find a list of all language identifiers on GitHub.
Differences to Shiki’s HTML output
If you’re migrating an existing site to Expressive Code that uses custom CSS to modify syntax-highlighted code, please note that the HTML output and classes generated by Expressive Code do not match the default output generated by Shiki.
Instead, the syntax tokens generated by Shiki are converted to Expressive Code’s own annotations (InlineStyleAnnotation
), which provide efficient multi-theme support and can be combined with other annotations.
If you need additional classes on some HTML elements, consider writing your own plugin to modify the output as needed.
Configuration
When using this plugin through a framework integration, you can configure it by passing options to the integration.
Here are configuration examples for common scenarios:
import { defineConfig } from 'astro/config'import astroExpressiveCode from 'astro-expressive-code'// Add this if you want to load a custom language grammar from a file:// import fs from 'node:fs'
export default defineConfig({ integrations: [ astroExpressiveCode({ // You can use any of the themes bundled with Shiki by name, // specify a path to JSON theme file, or pass an instance // of the `ExpressiveCodeTheme` class here: themes: ['dracula', 'solarized-light'], shiki: { // You can pass additional plugin options here, // e.g. to load custom language grammars: langs: [ // import('./some-exported-grammar.mjs'), // JSON.parse(fs.readFileSync('./some-json-grammar.json', 'utf-8')) ], }, }), ],})
import { defineConfig } from 'astro/config'import starlight from '@astrojs/starlight'// Add this if you want to load a custom language grammar from a file:// import fs from 'node:fs'
export default defineConfig({ integrations: [ starlight({ title: 'My Starlight site', expressiveCode: { // You can use any of the themes bundled with Shiki by name, // specify a path to JSON theme file, or pass an instance // of the `ExpressiveCodeTheme` class here: themes: ['dracula', 'solarized-light'], shiki: { // You can pass additional plugin options here, // e.g. to load custom language grammars: langs: [ // import('./some-exported-grammar.mjs'), // JSON.parse(fs.readFileSync('./some-json-grammar.json', 'utf-8')) ], }, }, }), ],})
import createMDX from '@next/mdx'import rehypeExpressiveCode from 'rehype-expressive-code'// Add this if you want to load a custom language grammar from a file:// import fs from 'node:fs'
/** @type {import('rehype-expressive-code').RehypeExpressiveCodeOptions} */const rehypeExpressiveCodeOptions = { // You can use any of the themes bundled with Shiki by name, // specify a path to JSON theme file, or pass an instance // of the `ExpressiveCodeTheme` class here: themes: ['dracula', 'solarized-light'], shiki: { // You can pass additional plugin options here, // e.g. to load custom language grammars: langs: [ // import('./some-exported-grammar.mjs'), // JSON.parse(fs.readFileSync('./some-json-grammar.json', 'utf-8')) ], },}
/** @type {import('next').NextConfig} */const nextConfig = { reactStrictMode: true, pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdx"],}
const withMDX = createMDX({ extension: /\.mdx?$/, options: { remarkPlugins: [], rehypePlugins: [ // The nested array structure is required to pass options // to a rehype plugin [rehypeExpressiveCode, rehypeExpressiveCodeOptions], ], },})
export default withMDX(nextConfig)
Available plugin options
You can pass the following options to the plugin:
langs
A list of additional languages that should be available for syntax highlighting.
You can pass any of the language input types supported by Shiki, e.g.:
import('./some-exported-grammar.mjs')
JSON.parse(fs.readFileSync('./some-json-grammar.json', 'utf-8'))
See the Shiki documentation for more information.
Using another syntax highlighter
If you want to use another syntax highlighter, you can set shiki: false
in the configuration to prevent the default highlighter from being loaded. You can then write a plugin for the new syntax highlighter and add it to the plugins
array.