Configuring Expressive Code
Expressive Code comes with default settings that should work out of the box for most sites. However, you can customize the configuration to match your needs by providing an options object to Expressive Code.
How to define your configuration
There are two ways to configure Expressive Code:
- You can pass your options to the initialization function of the integration you are using
- In Astro or Starlight projects, you can also create a file named
ec.config.mjs
in your project’s root directory and export your configuration object from there
If both methods are used, both config sources are merged on a per-option basis, with the options from the ec.config.mjs
file taking precedence.
For the following object options, a deep merge of all nested properties is performed, allowing you to perform granular overrides:
Also, the following array options are concatenated instead of being replaced:
Passing options directly
The default method to configure Expressive Code is to pass your options to the initialization function of the integration you are using:
Using an ec.config.mjs
file
In projects based on Astro or Starlight, you also have the option to create a file named ec.config.mjs
in your project’s root directory and export your configuration object as the default export from there:
Core options
The following options are supported by the core package and all integrations:
cascadeLayer
undefined
Allows to specify a CSS cascade layer name that should be used for all generated CSS.
If you are using cascade layers on your site to control the order in which CSS rules are applied, set this option to a non-empty string, and Expressive Code will wrap all of its generated CSS styles in a @layer
rule with the given name.
customizeTheme
This optional function is called once per theme during engine initialization with the loaded theme as its only argument.
It allows customizing the loaded theme and can be used for various purposes:
- You can change a theme’s
name
property to influence the CSS needed to select it (e.g., when using the default settings forthemeCssRoot
andthemeCssSelector
, settingtheme.name = 'dark'
will allow theme selection using<html data-theme="dark">
). - You can create color variations of themes by using
theme.applyHueAndChromaAdjustments()
.
You can optionally return an ExpressiveCodeTheme
instance from this function to replace the theme provided in the configuration. This allows you to create a copy of the theme and modify it without affecting the original instance.
Parameters
- theme:
ExpressiveCodeTheme
defaultLocale
'en-US'
The locale that should be used for text content.
defaultProps
An optional set of default props for all code blocks in your project.
For example, setting this to { wrap: true }
enables word wrapping on all code blocks by default, saving you from having to manually set this option on every single code block.
Object properties
overridesByLang
ExpressiveCodeBlockProps
>> Allows to override the default props based on a code block’s syntax highlighting language.
Use the language IDs as keys and an object containing the props as values. The keys also support specifying multiple language IDs separated by commas to apply the same props to multiple languages.
Example
logger
Allows to customize how Expressive Code logs messages. The default implementation logs all messages to the console and prepends them with the label expressive-code
like this:
Available logger options
- label:
string
The label to use as a prefix for all log messages. Defaults to'expressive-code'
. - debug:
(message: string) => void
A function to log a debug message. - info:
(message: string) => void
A function that logs an info message. - warn:
(message: string) => void
A function that logs a warning message. - error:
(message: string) => void
A function that logs an error message.
minSyntaxHighlightingColorContrast
5.5
Determines if Expressive Code should process the syntax highlighting colors of all themes to ensure an accessible minimum contrast ratio between foreground and background colors.
The default of 5.5
ensures a contrast ratio of at least 5.5:1. You can change the desired contrast ratio by providing another value, or turn the feature off by setting this option to 0
.
plugins
An optional array of plugins that should be used when rendering code blocks.
To add a plugin, import its initialization function and call it inside this array.
If the plugin has any configuration options, you can pass them to the initialization function as an object containing your desired property values.
If any nested arrays are found inside the plugins
array, they will be flattened before processing.
styleOverrides
An optional set of style overrides that can be used to customize the appearance of the rendered code blocks without having to write custom CSS.
See the Style Overrides page for more details.
theme
themeCssRoot
':root'
Allows to customize the base selector used to scope theme-dependent CSS styles.
The default selector ':root'
ensures that all required CSS variables are globally available.
themeCssSelector
(theme) => `[data-theme='${theme.name}']`
Allows to customize the selectors used to manually switch between multiple themes.
These selectors are useful if you want to allow your users to choose a theme instead of relying solely on the media query generated by useDarkModeMediaQuery
.
You can add a theme selector either to your <html>
element (which is targeted by the themeCssRoot
default value of :root
), and/or any individual code block wrapper.
For example, when using the default settings, selecting the theme github-light
for the entire page would look like this:
If your site’s theme switcher requires a different approach, you can customize the selectors using this option. For example, if you want to use class names instead of a data attribute, you could set this option to a function that returns .theme-${theme.name}
instead.
If you want to prevent the generation of theme-specific CSS rules altogether, you can set this to false
or return it from the function.
themes
The color themes that should be available for your code blocks.
CSS variables will be generated for all themes, allowing to select the theme to display using CSS. If you specify one dark and one light theme, a prefers-color-scheme
media query will also be generated by default. You can customize this to match your site’s needs through the useDarkModeMediaQuery
and themeCssSelector
options.
Defaults to the github-dark
and github-light
themes.
useDarkModeMediaQuery
Determines if CSS code is generated that uses a prefers-color-scheme
media query to automatically switch between light and dark themes based on the user’s system preferences.
Defaults to true
if your themes
option is set to one dark and one light theme (which is the default), and false
otherwise.
useStyleReset
true
Determines if code blocks should be protected against influence from site-wide styles.
Defaults to true
, which causes Expressive Code to use the declaration all: revert
to revert all CSS properties to the values they would have had without any site-wide styles. This ensures the most predictable results out of the box.
You can set this to false
if you want your site-wide styles to influence the code blocks.
useThemedScrollbars
true
Whether the themes are allowed to style the scrollbars.
If set to false
, scrollbars will be rendered using the browser’s default style.
Note that you can override the individual scrollbar colors defined by the theme using the styleOverrides
option.
useThemedSelectionColors
false
Whether the themes are allowed to style selected text.
By default, Expressive Code renders selected text in code blocks using the browser’s default style to maximize accessibility. If you want your selections to be more colorful, you can set this option to true
to allow using theme selection colors instead.
Note that you can override the individual selection colors defined by the theme using the styleOverrides
option.
Options of expressive-code
The expressive-code
package bundles the core package with all default plugin packages. To allow controlling the plugins, it also supports the following options in addition to the ones above:
frames
The Frames plugin adds an editor or terminal frame around code blocks, including an optional title displayed as a tab or window caption.
This plugin is enabled by default. Set this to false
to disable it. You can also configure the plugin by setting this to an options object.
shiki
The Shiki plugin adds syntax highlighting to code blocks.
This plugin is enabled by default. Set this to false
to disable it. You can also configure the plugin by setting this to an options object.
textMarkers
true
The Text Markers plugin allows to highlight lines and inline ranges in code blocks in various styles (e.g. marked, inserted, deleted).
This plugin is enabled by default. Set this to false
to disable it.
Options of rehype-expressive-code
In addition to the options above, the rehype integration also supports the following options:
customCreateBlock
This optional function allows you to customize how ExpressiveCodeBlock
instances are created from code blocks found in the Markdown document.
The function is expected to return an ExpressiveCodeBlock
instance or a promise resolving to one.
Parameters
-
input: ExpressiveCodeBlockOptions
Block data for theExpressiveCodeBlock
constructor. -
file: VFileWithOutput<null>
AVFile
instance representing the Markdown document.
customCreateRenderer
undefined
This advanced option allows you to influence the rendering process by creating your own ExpressiveCode
instance or processing the base styles and JS modules added to every page.
The return value will be cached and used for all code blocks in the document.
Parameters
- options:
RehypeExpressiveCodeOptions
getBlockLocale
undefined
This optional function provides support for multi-language sites by allowing you to customize the locale used for a given code block.
If the function returns undefined
, the default locale provided in the Expressive Code configuration is used.
Parameters
-
input: ExpressiveCodeBlockOptions
Block data for theExpressiveCodeBlock
constructor. -
file: VFileWithOutput<null>
AVFile
instance representing the Markdown document.
tabWidth
2
The number of spaces that should be used to render tabs.
Any tabs found in code blocks in your markdown/MDX documents will be replaced with the specified number of spaces. This ensures that the code blocks are rendered consistently across browsers and platforms.
If you want to preserve tabs in your code blocks, set this option to 0.
themes
['github-dark', 'github-light']
The color themes that should be available for your code blocks.
CSS variables will be generated for all themes, allowing to select the theme to display using CSS. If you specify one dark and one light theme, a prefers-color-scheme
media query will also be generated by default. You can customize this to match your site’s needs through the useDarkModeMediaQuery
and themeCssSelector
options.
The following item types are supported in this array:
- any theme name bundled with Shiki (e.g.
dracula
) - any theme object compatible with VS Code or Shiki (e.g. imported from an NPM theme package)
- any ExpressiveCodeTheme instance (e.g. using
ExpressiveCodeTheme.fromJSONString(...)
to load a custom JSON/JSONC theme file yourself)
Options of astro-expressive-code
In addition to the options above, the Astro integration also supports the following options:
emitExternalStylesheet
true
Determines if the styles required to display code blocks should be emitted into a separate CSS file rather than being inlined into the rendered HTML of the first code block per page.
This is recommended for sites containing multiple pages with code blocks, as it will reduce the overall footprint of the site when navigating between pages.
The generated URL is located inside Astro’s assets directory and includes a content hash so it can be cached indefinitely by browsers. If you are using the default values for the Astro config options base
, build.assets
, build.assetsPrefix
, the resulting URL will be /_astro/ec.{hash}.css
.
Options of the Starlight integration
In addition to the options above, the Starlight integration provides two themes (starlight-dark
and starlight-light
) and options (useStarlightDarkModeSwitch
and useStarlightUiThemeColors
) that are specific to Starlight.
Please refer to the Starlight Configuration Reference for more details.
Referenced types
ExpressiveCodeBlockProps
Properties
preserveIndent
boolean
Default:
true
If true
, wrapped parts of long lines will be aligned with their line’s indentation level, making the wrapped code appear to start at the same column. This increases readability of the wrapped code and can be especially useful for languages where indentation is significant, e.g. Python.
If false
, wrapped parts of long lines will always start at column 1. This can be useful to reproduce terminal output.
wrap
boolean
Default:
false
If true
, word wrapping will be enabled for the code block, causing lines that exceed the available width to wrap to the next line. You can use the preserveIndent
option to control how wrapped lines are indented.
If false
, lines that exceed the available width will cause a horizontal scrollbar to appear.