` component that can be used in `.mdx` and `.astro` files.
In contrast to static fenced code blocks, the `` component allows you to dynamically define a code block’s contents using props. This makes it possible to render code blocks from variables or data coming from external sources like files, databases or APIs.
## Basic usage
[Section titled “Basic usage”](#basic-usage)
To use the `` component, you must first import it into your file. The location and syntax of the import statement depend on the file type and integration you’re using:
### Usage in `.mdx` files
[Section titled “Usage in .mdx files”](#usage-in-mdx-files)
To get started, add an import statement to the content section of your `.mdx` file (the part below the frontmatter block). You can then use the component anywhere in the content.
* Astro
src/content/docs/example.mdx
```diff
---
title: My example page
---
+import { Code } from 'astro-expressive-code/components'
+
```
* Starlight
src/content/docs/example.mdx
```diff
---
title: My example page
---
+import { Code } from '@astrojs/starlight/components'
+
```
The code above generates the following on the page:
```js
console.log('Hello world!')
```
### Usage in `.astro` files
[Section titled “Usage in .astro files”](#usage-in-astro-files)
The `` component enables you to render code blocks in `.astro` files. This allows you to use all features of Expressive Code in your pages, and even creating custom components that wrap the `` component to provide additional functionality.
Using the component in `.astro` files works just like in `.mdx` files, except that you need to place the import statement inside the frontmatter block:
src/pages/index.astro
```diff
---
import MainLayout from '../layouts/MainLayout.astro'
+import { Code } from 'astro-expressive-code/components'
---
My example page
Here is some interesting code:
+
```
## Using props to define code blocks
[Section titled “Using props to define code blocks”](#using-props-to-define-code-blocks)
The true power of the `` component lies in its ability to render code blocks from variables or data coming from external sources like files, databases or APIs.
To do this, set the component’s props like `code`, `lang`, `title` etc. to variables instead of static values.
* Astro
src/content/docs/example.mdx
```diff
---
title: My example page
---
+import { Code } from 'astro-expressive-code/components'
export const exampleCode = `console.log('This could come from a file or CMS!');`
export const fileName = 'example.js'
export const highlights = ['file', 'CMS']
+
```
* Starlight
src/content/docs/example.mdx
```diff
---
title: My example page
---
+import { Code } from '@astrojs/starlight/components'
export const exampleCode = `console.log('This could come from a file or CMS!');`
export const fileName = 'example.js'
export const highlights = ['file', 'CMS']
+
```
The code above generates the following on the page:
example.js
```js
console.log('This could come from a file or CMS!');
```
## Importing code from files
[Section titled “Importing code from files”](#importing-code-from-files)
Use [Vite’s `?raw` import suffix](https://vitejs.dev/guide/assets#importing-asset-as-string) to import any code file as a string. You can then pass this imported string to the `` component to include it on your page.
This is especially useful when documenting a project, as your code examples will always be up-to-date with the actual code.
You can also use this feature to create reusable snippets and include them in multiple code blocks on your site.
* Astro
src/content/docs/example.mdx
```mdx
import { Code } from 'astro-expressive-code/components';
import importedCode from '/src/env.d.ts?raw';
```
* Starlight
src/content/docs/example.mdx
```mdx
import { Code } from '@astrojs/starlight/components';
import importedCode from '/src/env.d.ts?raw';
```
The code above generates the following on the page:
src/env.d.ts
```ts
/* eslint-disable @typescript-eslint/triple-slash-reference */
///
///
```
## Using an `ec.config.mjs` file
[Section titled “Using an ec.config.mjs file”](#using-an-ecconfigmjs-file)
The `` component is designed to automatically pick up the Expressive Code configuration options from your project’s Astro config file without requiring any additional setup.
Due to the way Astro works, the Expressive Code integration can only share its configuration with the component by serializing it to JSON. In some situations, this is not possible, e.g. when your configuration includes custom plugins or functions that are not serializable to JSON.
In these cases, you will receive the following error message when trying to use the `` component:
> *\[ERROR] Failed to render a `` component on page \[…]:*
>
> *Your Astro config file contains Expressive Code options that are not serializable to JSON. To use the `` component, please create a separate config file called `ec.config.mjs` in your project root, move your Expressive Code options object into the config file, and export it as the default export.*
As instructed by the error message, you can fix this issue by creating a separate `ec.config.mjs` file in your project root and moving your Expressive Code options object into the config file. Here is an example of how this file could look like if you’re using the [collapsible sections plugin](/plugins/collapsible-sections/):
* Astro
ec.config.mjs
```ts
import { defineEcConfig } from 'astro-expressive-code'
import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections'
export default defineEcConfig({
// Example: Using a custom plugin (which makes this `ec.config.mjs` file necessary)
plugins: [pluginCollapsibleSections()],
// ... any other options you want to configure
})
```
* Starlight
ec.config.mjs
```ts
import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections'
/** @type {import('@astrojs/starlight/expressive-code').StarlightExpressiveCodeOptions} */
export default {
// Example: Using a custom plugin (which makes this `ec.config.mjs` file necessary)
plugins: [pluginCollapsibleSections()],
// ... any other options you want to configure
}
```
## Available props
[Section titled “Available props”](#available-props)
You can find a list of all default props that can be used with the `` component below.
Note
Optional plugins can contribute additional props to the `` component. Please refer to the documentation of the respective plugin for more information.
### code
[Section titled “code”](#code)
Type: string
The plaintext contents of the code block. This property is required and must be set to a non-empty string.
### lang
[Section titled “lang”](#lang)
Type: string | undefined Default: undefined
The code block’s language.
Please use a valid [language identifier](/key-features/syntax-highlighting/#supported-languages) to ensure proper syntax highlighting.
### meta
[Section titled “meta”](#meta)
Type: string | undefined Default: undefined
An optional meta string. In markdown or MDX documents, this is the part of the code block’s opening fence that comes after the language name.
### locale
[Section titled “locale”](#locale)
Type: string | undefined Default: undefined
The code block’s locale (e.g. `en-US` or `de-DE`). This is used by plugins to display localized strings depending on the language of the containing page.
If no locale is defined here, most Expressive Code integrations will attempt to auto-detect the block locale using the configured [`getBlockLocale`](/reference/configuration/#getblocklocale) function, and finally fall back to the configured [`defaultLocale`](/reference/configuration/#defaultlocale).
### title
[Section titled “title”](#title)
Type: string | undefined Default: undefined
The code block’s title.
Depending on the frame type (code or terminal), this title is displayed by the [frames plugin](/key-features/frames/) either as an open file tab label or as a terminal window title.
### frame
[Section titled “frame”](#frame)
Type: `'auto' | 'code' | 'terminal' | 'none' | undefined` Default: `'auto'`
The code block’s [frame type](https://expressive-code.com/key-features/frames/#overriding-frame-types).
### mark / ins / del
[Section titled “mark / ins / del”](#mark--ins--del)
Type: [`MarkerDefinition`](/key-features/text-markers/#markerdefinition) | [`MarkerDefinition`](/key-features/text-markers/#markerdefinition)\[] Default: undefined
Defines the code block’s [text & line markers](/key-features/text-markers/).
You can either pass a single marker definition or an array of them.
### class
[Section titled “class”](#class)
Type: string | undefined Default: undefined
The CSS class name(s) to apply to the code block’s container element.
### wrap
[Section titled “wrap”](#wrap)
Type: `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.
### preserveIndent
[Section titled “preserveIndent”](#preserveindent)
Type: `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.
Note
This option only has an effect if `wrap` is `true`. It only affects how the code block is displayed and does not change the actual code. When copied to the clipboard, the code will still contain the original unwrapped lines.
### hangingIndent
[Section titled “hangingIndent”](#hangingindent)
Type: `number` Default: `0`
Defines the number of columns by which all wrapped lines are indented.
This option only has an effect if `wrap` is `true`.
If `preserveIndent` is `true`, this value is added to the indentation of the original line. If `preserveIndent` is `false`, this value is used as the indentation for all wrapped lines.
Note
This option only affects how the code block is displayed and does not change the actual code. When copied to the clipboard, the code will still contain the original unwrapped lines.
# Editor & Terminal Frames
Expressive Code supports rendering frames around your code blocks. By default, the type of frame (editor window or terminal window) is selected automatically based on the language identifier in your code block’s opening fence.
Frames can have optional titles, which are either taken from the code block’s meta string, or from a file name comment in the first lines of the code.
No installation required
These features are provided by `@expressive-code/plugin-frames`, which is installed & enabled by default in all framework integrations. You can start using it right away in your documents!
## Usage in markdown / MDX
[Section titled “Usage in markdown / MDX”](#usage-in-markdown--mdx)
### Code editor frames
[Section titled “Code editor frames”](#code-editor-frames)
To make code blocks look like an editor window similar to VS Code, you must provide a file name that can be displayed in the open file tab.
To do this, you can either set the `title` attribute in the opening code fence to a file name, or add a [file name comment](#file-name-comments) to the first lines of the code.
See the markdown code below for examples of both methods:
editor-example.md
````md
```js title="my-test-file.js"
console.log('Title attribute example')
```
```html
File name comment example
```
````
The rendered result looks like this:
my-test-file.js
```js
console.log('Title attribute example')
```
src/content/index.html
```html
File name comment example
```
### Terminal frames
[Section titled “Terminal frames”](#terminal-frames)
When encountering code blocks with a language identifier that is typically used for terminal sessions or shell scripts (`ansi`, `bash`, `bat`, `batch`, `cmd`, `console`, `powershell`, `ps`, `ps1`, `psd1`, `psm1`, `sh`, `shell`, `shellscript`, `shellsession`, `zsh`), Expressive Code performs additional checks to detect the frame type to use:
* If the code block contains a shell script file name in the `title` attribute of the opening code fence or a [file name comment](#file-name-comments), or if the code starts with a shebang (`#!`), it is considered to be a script file instead of a terminal session, and is rendered with a code editor frame if a file name was provided, or as a plain code block otherwise.
* In all other cases, the code block is considered to be a terminal session and rendered with a terminal frame.
In contrast to code editor frames, terminal frames do not require a title. The title bar will always be rendered, and you can optionally add a title using the `title` attribute:
````md
```bash
echo "This terminal frame has no title"
```
```powershell title="PowerShell terminal example"
Write-Output "This one has a title!"
```
````
The rendered result looks like this:
```bash
echo "This frame has no title"
```
PowerShell terminal example
```powershell
Write-Output "This one has a title!"
```
### File name comments
[Section titled “File name comments”](#file-name-comments)
If a code block does not have a `title` attribute, Expressive Code supports automatically extracting a title from a file name comment inside your code.
The following conditions must be met for a comment to be recognized as a file name comment:
* It must appear within the first 4 lines of the code block.
* Its line must start with `//`, ` 'const a = 1 + 2'
```
#### Constructors
[Section titled “Constructors”](#constructors-1)
##### new ExpressiveCodeBlock(options)
[Section titled “new ExpressiveCodeBlock(options)”](#new-expressivecodeblockoptions)
* `new ExpressiveCodeBlock(options): ExpressiveCodeBlock`
Note
You usually don’t need to create code blocks manually. Instead, you can pass `ExpressiveCodeBlockOptions` to the `render` method of the `ExpressiveCodeEngine` class, and the engine will create the code blocks for you.
Manually creating code blocks may still be useful in some cases, e.g. to allow integration authors to attach custom annotations to code blocks before passing them to the engine, or to attach custom data to a code block.
###### Arguments
[Section titled “Arguments”](#arguments-2)
| Parameter | Type |
| :-------- | :------------------------------------------------------------------------------ |
| `options` | [`ExpressiveCodeBlockOptions`](/reference/core-api/#expressivecodeblockoptions) |
#### Methods
[Section titled “Methods”](#methods-1)
##### deleteLine()
[Section titled “deleteLine()”](#deleteline)
* `deleteLine(index): void`
Deletes the line at the given index.
May throw an error if not allowed in the current [state](/reference/core-api/#state).
###### Arguments
[Section titled “Arguments”](#arguments-3)
| Parameter | Type |
| :-------- | :------- |
| `index` | `number` |
##### deleteLines()
[Section titled “deleteLines()”](#deletelines)
* `deleteLines(indices): void`
Deletes the lines at the given indices.
This function automatically sorts the indices in descending order before deleting the lines, so you do not need to worry about indices shifting after deleting a line.
May throw an error if not allowed in the current [state](/reference/core-api/#state).
###### Arguments
[Section titled “Arguments”](#arguments-4)
| Parameter | Type |
| :-------- | :---------- |
| `indices` | `number`\[] |
##### getLine()
[Section titled “getLine()”](#getline)
* `getLine(index): undefined | ExpressiveCodeLine`
Returns the line at the given index, or `undefined` if the index is out of range.
###### Arguments
[Section titled “Arguments”](#arguments-5)
| Parameter | Type |
| :-------- | :------- |
| `index` | `number` |
##### getLines()
[Section titled “getLines()”](#getlines)
* `getLines(startIndex?, endIndex?): readonly ExpressiveCodeLine[]`
Returns a readonly array of lines starting at the given index and ending before the given index (exclusive). The indices support the same syntax as JavaScript’s `Array.slice` method.
###### Arguments
[Section titled “Arguments”](#arguments-6)
| Parameter | Type |
| :------------ | :------- |
| `startIndex`? | `number` |
| `endIndex`? | `number` |
##### insertLine()
[Section titled “insertLine()”](#insertline)
* `insertLine(index, textLine): ExpressiveCodeLine`
Inserts a new line at the given index.
May throw an error if not allowed in the current [state](/reference/core-api/#state).
###### Arguments
[Section titled “Arguments”](#arguments-7)
| Parameter | Type |
| :--------- | :------- |
| `index` | `number` |
| `textLine` | `string` |
##### insertLines()
[Section titled “insertLines()”](#insertlines)
* `insertLines(index, textLines): ExpressiveCodeLine[]`
Inserts multiple new lines at the given index.
May throw an error if not allowed in the current [state](/reference/core-api/#state).
###### Arguments
[Section titled “Arguments”](#arguments-8)
| Parameter | Type |
| :---------- | :---------- |
| `index` | `number` |
| `textLines` | `string`\[] |
#### Accessors
[Section titled “Accessors”](#accessors)
##### code
[Section titled “code”](#code)
* `get code(): string`
Provides read-only access to the code block’s plaintext contents.
##### language
[Section titled “language”](#language)
* `get language(): string`
* `set language(value): void`
Allows getting and setting the code block’s language.
Setting this property may throw an error if not allowed in the current [state](/reference/core-api/#state).
###### Parameters
[Section titled “Parameters”](#parameters)
| Parameter | Type |
| :-------- | :------- |
| `value` | `string` |
##### locale
[Section titled “locale”](#locale)
* `get locale(): undefined | string`
Allows getting the code block’s locale (e.g. `en-US` or `de-DE`). It is used by plugins to display localized strings depending on the language of the containing page.
Integrations like `rehype-expressive-code` support multi-language sites by allowing you to provide custom logic to determine a block’s locale (e.g. based on its parent document).
If no locale is defined here, `ExpressiveCodeEngine` will render the code block using the `defaultLocale` provided in its configuration.
##### meta
[Section titled “meta”](#meta)
* `get meta(): string`
* `set meta(value): void`
Allows getting or setting the code block’s meta string. In markdown or MDX documents, this is the part of the code block’s opening fence that comes after the language name.
Setting this property may throw an error if not allowed in the current [state](/reference/core-api/#state).
###### Parameters
[Section titled “Parameters”](#parameters-1)
| Parameter | Type |
| :-------- | :------- |
| `value` | `string` |
##### metaOptions
[Section titled “metaOptions”](#metaoptions)
* `get metaOptions(): MetaOptions`
Provides read-only access to the parsed version of the block’s [meta](/reference/core-api/#meta) string.
##### parentDocument
[Section titled “parentDocument”](#parentdocument)
* `get parentDocument(): undefined | Object`
Provides read-only access to optional data about the parent document the code block is located in.
Integrations like `rehype-expressive-code` can provide this information based on the source document being processed. There may be cases where no document is available, e.g. when the code block was created dynamically.
##### props
[Section titled “props”](#props)
* `get props(): Partial`
Provides access to the code block’s props.
To allow users to set these props through the meta string, plugins can use the `preprocessMetadata` hook to read `metaOptions` and update their props accordingly.
Props can be modified until rendering starts and become read-only afterwards.
##### state
[Section titled “state”](#state)
* `get state(): undefined | ExpressiveCodeProcessingState`
Provides read-only access to the code block’s processing state.
The processing state controls which properties of the code block can be modified. The engine updates it automatically during rendering.
### ExpressiveCodeBlockOptions
[Section titled “ExpressiveCodeBlockOptions”](#expressivecodeblockoptions)
#### Properties
[Section titled “Properties”](#properties-1)
##### code
[Section titled “code”](#code-1)
Type: `string`
The plaintext contents of the code block.
##### language
[Section titled “language”](#language-1)
Type: `string`
The code block’s language.
Please use a valid [language identifier](https://expressive-code.com/key-features/syntax-highlighting/#supported-languages) to ensure proper syntax highlighting.
##### locale?
[Section titled “locale?”](#locale-1)
Type: `string`
The code block’s locale (e.g. `en-US` or `de-DE`). This is used by plugins to display localized strings depending on the language of the containing page.
If no locale is defined here, most Expressive Code integrations will attempt to auto-detect the block locale using the configured [`getBlockLocale`](https://expressive-code.com/reference/configuration/#getblocklocale) function, and finally fall back to the configured [`defaultLocale`](https://expressive-code.com/reference/configuration/#defaultlocale).
##### meta?
[Section titled “meta?”](#meta-1)
Type: `string`
An optional meta string. In markdown or MDX documents, this is the part of the code block’s opening fence that comes after the language name.
##### parentDocument?
[Section titled “parentDocument?”](#parentdocument-1)
Type: `Object`
Optional data about the parent document the code block is located in.
Integrations like `rehype-expressive-code` can provide this information based on the source document being processed. There may be cases where no document is available, e.g. when the code block was created dynamically.
###### Object properties
[Section titled “Object properties”](#object-properties)
* documentRoot
Type: `unknown`
A reference to the object representing the parsed source document. This reference will stay the same for all code blocks in the same document.
For example, if you are using `rehype-expressive-code` to render code blocks in a Markdown file, this would be the `hast` node representing the file’s root node.
* positionInDocument
Type: `Object`
Data about the position of the code block in the parent document.
* positionInDocument.groupIndex
Type: `number`
* positionInDocument.totalGroups
Type: `number`
* sourceFilePath
Type: `string`
The full path to the source file containing the code block.
##### props?
[Section titled “props?”](#props-1)
Type: Partial<[ExpressiveCodeBlockProps](/reference/configuration/#expressivecodeblockprops)>
Optional props that can be used to influence the rendering of this code block.
Plugins can add their own props to this type. To allow users to set these props through the meta string, plugins can use the `preprocessMetadata` hook to read `metaOptions` and update the `props` object accordingly.
### ExpressiveCodeLine
[Section titled “ExpressiveCodeLine”](#expressivecodeline)
#### Constructors
[Section titled “Constructors”](#constructors-2)
##### new ExpressiveCodeLine(text)
[Section titled “new ExpressiveCodeLine(text)”](#new-expressivecodelinetext)
* `new ExpressiveCodeLine(text): ExpressiveCodeLine`
###### Arguments
[Section titled “Arguments”](#arguments-9)
| Parameter | Type |
| :-------- | :------- |
| `text` | `string` |
#### Methods
[Section titled “Methods”](#methods-2)
##### addAnnotation()
[Section titled “addAnnotation()”](#addannotation)
* `addAnnotation(annotation): void`
###### Arguments
[Section titled “Arguments”](#arguments-10)
| Parameter | Type |
| :----------- | :-------------------------------------------------------------------------- |
| `annotation` | [`ExpressiveCodeAnnotation`](/reference/core-api/#expressivecodeannotation) |
##### deleteAnnotation()
[Section titled “deleteAnnotation()”](#deleteannotation)
* `deleteAnnotation(annotation): void`
###### Arguments
[Section titled “Arguments”](#arguments-11)
| Parameter | Type |
| :----------- | :-------------------------------------------------------------------------- |
| `annotation` | [`ExpressiveCodeAnnotation`](/reference/core-api/#expressivecodeannotation) |
##### editText()
[Section titled “editText()”](#edittext)
* `editText(columnStart, columnEnd, newText): string`
###### Arguments
[Section titled “Arguments”](#arguments-12)
| Parameter | Type |
| :------------ | :---------------------- |
| `columnStart` | `undefined` \| `number` |
| `columnEnd` | `undefined` \| `number` |
| `newText` | `string` |
##### getAnnotations()
[Section titled “getAnnotations()”](#getannotations)
* `getAnnotations(): readonly ExpressiveCodeAnnotation[]`
#### Accessors
[Section titled “Accessors”](#accessors-1)
##### parent
[Section titled “parent”](#parent)
* `get parent(): undefined | ExpressiveCodeBlock`
* `set parent(value): void`
###### Parameters
[Section titled “Parameters”](#parameters-2)
| Parameter | Type |
| :-------- | :------------------------------------------------------------------------------- |
| `value` | `undefined` \| [`ExpressiveCodeBlock`](/reference/core-api/#expressivecodeblock) |
##### text
[Section titled “text”](#text)
* `get text(): string`
### MetaOptions
[Section titled “MetaOptions”](#metaoptions-1)
#### Constructors
[Section titled “Constructors”](#constructors-3)
##### new MetaOptions(input)
[Section titled “new MetaOptions(input)”](#new-metaoptionsinput)
* `new MetaOptions(input): MetaOptions`
###### Arguments
[Section titled “Arguments”](#arguments-13)
| Parameter | Type |
| :-------- | :------- |
| `input` | `string` |
#### Methods
[Section titled “Methods”](#methods-3)
##### getBoolean()
[Section titled “getBoolean()”](#getboolean)
* `getBoolean(key): undefined | boolean`
Returns the last boolean value with the given key (case-insensitive).
###### Arguments
[Section titled “Arguments”](#arguments-14)
| Parameter | Type |
| :-------- | :------- |
| `key` | `string` |
##### getInteger()
[Section titled “getInteger()”](#getinteger)
* `getInteger(key): undefined | number`
Returns the last integer value with the given key (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-15)
| Parameter | Type |
| :-------- | :------- |
| `key` | `string` |
##### getIntegers()
[Section titled “getIntegers()”](#getintegers)
* `getIntegers(keyOrKeys?): number[]`
Returns an array of all integer values with the given keys (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-16)
| Parameter | Type |
| :----------- | :---------------------- |
| `keyOrKeys`? | `string` \| `string`\[] |
##### getRange()
[Section titled “getRange()”](#getrange)
* `getRange(key): undefined | string`
Returns the last range value (`{value}`) with the given key (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-17)
| Parameter | Type |
| :-------- | :------- |
| `key` | `string` |
##### getRanges()
[Section titled “getRanges()”](#getranges)
* `getRanges(keyOrKeys?): string[]`
Returns an array of all range values (`{value}`) with the given keys (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-18)
| Parameter | Type |
| :----------- | :---------------------- |
| `keyOrKeys`? | `string` \| `string`\[] |
##### getRegExp()
[Section titled “getRegExp()”](#getregexp)
* `getRegExp(key): undefined | RegExp`
Returns the last RegExp value (`/value/`) with the given key (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-19)
| Parameter | Type |
| :-------- | :------- |
| `key` | `string` |
##### getRegExps()
[Section titled “getRegExps()”](#getregexps)
* `getRegExps(keyOrKeys?): RegExp[]`
Returns an array of all RegExp values (`/value/`) with the given keys (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-20)
| Parameter | Type |
| :----------- | :---------------------- |
| `keyOrKeys`? | `string` \| `string`\[] |
##### getString()
[Section titled “getString()”](#getstring)
* `getString(key): undefined | string`
Returns the last string value with the given key (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-21)
| Parameter | Type |
| :-------- | :------- |
| `key` | `string` |
##### getStrings()
[Section titled “getStrings()”](#getstrings)
* `getStrings(keyOrKeys?): string[]`
Returns an array of all string values with the given keys (case-insensitive), or without a key by passing an empty string.
###### Arguments
[Section titled “Arguments”](#arguments-22)
| Parameter | Type |
| :----------- | :---------------------- |
| `keyOrKeys`? | `string` \| `string`\[] |
##### list()
[Section titled “list()”](#list)
* `list(keyOrKeys?, kind?): ReturnType`
Returns a list of meta options, optionally filtered by their key and/or MetaOptionKind.
###### Type parameters
[Section titled “Type parameters”](#type-parameters)
| Parameter | Value |
| :------------------------------------------------------------------------------ | :---------- |
| `K` extends `undefined` \| `"string"` \| `"boolean"` \| `"range"` \| `"regexp"` | `undefined` |
###### Arguments
[Section titled “Arguments”](#arguments-23)
| Parameter | Type | Description |
| :----------- | :---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `keyOrKeys`? | `string` \| `string`\[] | Allows to filter the options by key. An empty string will return options without a key. A non-empty string will return options with a matching key (case-insensitive). An array of strings will return options with any of the matching keys. If omitted, no key-based filtering will be applied. |
| `kind`? | `K` | Allows to filter the options by MetaOptionKind. If omitted, no kind-based filtering will be applied. |
##### value()
[Section titled “value()”](#value)
* `value(key, kind?): undefined | OptionType[“value”]`
###### Type parameters
[Section titled “Type parameters”](#type-parameters-1)
| Parameter | Value |
| :------------------------------------------------------------------------------ | :---------- |
| `K` extends `undefined` \| `"string"` \| `"boolean"` \| `"range"` \| `"regexp"` | `undefined` |
###### Arguments
[Section titled “Arguments”](#arguments-24)
| Parameter | Type |
| :-------- | :------- |
| `key` | `string` |
| `kind`? | `K` |
#### Accessors
[Section titled “Accessors”](#accessors-2)
##### errors
[Section titled “errors”](#errors)
* `get errors(): undefined | string[]`
A list of error messages that occurred when parsing the meta string, or `undefined` if no errors occurred.
## Themes
[Section titled “Themes”](#themes)
### ExpressiveCodeTheme
[Section titled “ExpressiveCodeTheme”](#expressivecodetheme)
#### Constructors
[Section titled “Constructors”](#constructors-4)
##### new ExpressiveCodeTheme(theme)
[Section titled “new ExpressiveCodeTheme(theme)”](#new-expressivecodethemetheme)
* `new ExpressiveCodeTheme(theme): ExpressiveCodeTheme`
Loads the given theme for use with Expressive Code. Supports both Shiki and VS Code themes.
You can also pass an existing `ExpressiveCodeTheme` instance to create a copy of it.
Note: To save on bundle size, this constructor does not support loading themes bundled with Shiki by name (e.g. `dracula`). Instead, import Shiki’s `loadTheme` function yourself, use it to load its bundled theme (e.g. `themes/dracula.json`), and pass the result to this constructor.
###### Arguments
[Section titled “Arguments”](#arguments-25)
| Parameter | Type |
| :-------- | :------------------------- |
| `theme` | `ExpressiveCodeThemeInput` |
#### Methods
[Section titled “Methods”](#methods-4)
##### applyHueAndChromaAdjustments()
[Section titled “applyHueAndChromaAdjustments()”](#applyhueandchromaadjustments)
* `applyHueAndChromaAdjustments(adjustments): ExpressiveCodeTheme`
Applies chromatic adjustments to entire groups of theme colors while keeping their relative lightness and alpha components intact. This can be used to quickly create theme variants that fit the color scheme of any website or brand.
Adjustments can either be defined as hue and chroma values in the OKLCH color space (range 0–360 for hue, 0–0.4 for chroma), or these values can be extracted from hex color strings (e.g. `#3b82f6`).
You can target predefined groups of theme colors (e.g. `backgrounds`, `accents`) and/or use the `custom` property to define your own groups of theme colors to be adjusted. Each custom group must contain a `themeColorKeys` property with an array of VS Code theme color keys (e.g. `['panel.background', 'panel.border']`) and a `targetHueAndChroma` property that accepts the same adjustment target values as `backgrounds` and `accents`. Custom groups will be applied in the order they are defined.
Returns the same `ExpressiveCodeTheme` instance to allow chaining.
###### Arguments
[Section titled “Arguments”](#arguments-26)
| Parameter | Type |
| :------------------------- | :---------------------------------------------------------------------------------- |
| `adjustments` | `Object` |
| `adjustments.accents`? | `string` \| [`ChromaticRecolorTarget`](/reference/core-api/#chromaticrecolortarget) |
| `adjustments.backgrounds`? | `string` \| [`ChromaticRecolorTarget`](/reference/core-api/#chromaticrecolortarget) |
| `adjustments.custom`? | `Object`\[] |
##### ensureMinSyntaxHighlightingColorContrast()
[Section titled “ensureMinSyntaxHighlightingColorContrast()”](#ensureminsyntaxhighlightingcolorcontrast)
* `ensureMinSyntaxHighlightingColorContrast(minContrast, backgroundColor?): ExpressiveCodeTheme`
Processes the theme’s syntax highlighting colors to ensure a minimum contrast ratio between foreground and background colors.
The default value of 5.5 ensures optimal accessibility with a contrast ratio of 5.5:1.
You can optionally pass a custom background color to use for the contrast checks. By default, the theme’s background color will be used.
Returns the same `ExpressiveCodeTheme` instance to allow chaining.
###### Arguments
[Section titled “Arguments”](#arguments-27)
| Parameter | Type | Default value |
| :----------------- | :------- | :------------ |
| `minContrast` | `number` | `5.5` |
| `backgroundColor`? | `string` | `undefined` |
##### fromJSONString()
[Section titled “fromJSONString()”](#fromjsonstring)
* `static fromJSONString(json): ExpressiveCodeTheme`
Attempts to parse the given JSON string as a theme.
As some themes follow the JSONC format and may contain comments and trailing commas, this method will attempt to strip them before parsing the result.
###### Arguments
[Section titled “Arguments”](#arguments-28)
| Parameter | Type |
| :-------- | :------- |
| `json` | `string` |
#### Properties
[Section titled “Properties”](#properties-2)
##### bg
[Section titled “bg”](#bg)
Type: `string`
##### colors
[Section titled “colors”](#colors)
Type: `Object` (mapping VS Code workbench color keys to values)
##### fg
[Section titled “fg”](#fg)
Type: `string`
##### name
[Section titled “name”](#name)
Type: `string`
##### semanticHighlighting
[Section titled “semanticHighlighting”](#semantichighlighting)
Type: `boolean`
##### settings
[Section titled “settings”](#settings)
Type: [`ThemeSetting`](/reference/core-api/#themesetting)\[]
##### styleOverrides
[Section titled “styleOverrides”](#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 [Overriding Styles](/reference/style-overrides) for a list of all available settings.
##### type
[Section titled “type”](#type)
Type: `"dark"` | `"light"`
## Annotations
[Section titled “Annotations”](#annotations)
In Expressive Code, annotations are used by plugins to attach semantic information to lines or inline ranges of code. They are used to represent things like syntax highlighting, text markers, comments, errors, warnings, and other semantic information.
Annotations must provide a `render` function that transforms its contained AST nodes, e.g. by wrapping them in HTML tags. This function is called by the engine when it’s time to render the line the annotation has been attached to.
### ExpressiveCodeAnnotation
[Section titled “ExpressiveCodeAnnotation”](#expressivecodeannotation)
An abstract class representing a single annotation attached to a code line.
You can develop your own annotations by extending this class and providing implementations for its abstract methods. See the implementation of the [InlineStyleAnnotation](/reference/core-api/#inlinestyleannotation) class for an example.
You can also define your annotations as plain objects, as long as they have the same properties as this class. This allows you to use annotations in a more functional way, without the need to extend a class.
#### Constructors
[Section titled “Constructors”](#constructors-5)
Note
As an abstract class, `ExpressiveCodeAnnotation` cannot be instantiated directly. You should create a subclass that extends `ExpressiveCodeAnnotation` instead.
#### Methods
[Section titled “Methods”](#methods-5)
##### `abstract` render()
[Section titled “abstract render()”](#abstract-render)
* `abstract render(options): Parents[]`
Renders the annotation by transforming the provided nodes.
This function will be called with an array of AST nodes to transform, and is expected to return an array containing the same number of nodes.
For example, you could use the `hastscript` library to wrap the received nodes in HTML elements.
###### Arguments
[Section titled “Arguments”](#arguments-29)
| Parameter | Type |
| :-------- | :------------------------------------------------------------------------ |
| `options` | [`AnnotationRenderOptions`](/reference/core-api/#annotationrenderoptions) |
#### Properties
[Section titled “Properties”](#properties-3)
All annotation base options are available on the instance as read-only properties. See [`AnnotationBaseOptions`](#annotationbaseoptions) for the entire list.
### InlineStyleAnnotation
[Section titled “InlineStyleAnnotation”](#inlinestyleannotation)
A theme-dependent inline style annotation that allows changing colors, font styles and decorations of the targeted code. This annotation is used by the syntax highlighting plugin to apply colors and styles to syntax tokens, and you can use it in your own plugins as well.
You can add as many inline style annotations to a line as you want, even targeting the same code with multiple fully or partially overlapping annotation ranges. During rendering, these annotations will be automatically optimized to avoid creating unnecessary HTML elements.
Note
If you want to publish your own plugin using the `InlineStyleAnnotation` class, import it from the `@expressive-code/core` package installed as a **peer dependency** of your plugin package. This ensures that your plugin does not cause a version conflict if the user has a different version of Expressive Code installed on their site.
#### Usage example
[Section titled “Usage example”](#usage-example-1)
In the following example, we create a plugin that makes the first word of each code block red in the first theme. We do this by adding an `InlineStyleAnnotation` to the first line of each code block.
plugins/plugin-first-word-red.js
```js
// @ts-check
import { definePlugin, InlineStyleAnnotation } from '@expressive-code/core'
export function pluginFirstWordRed() {
return definePlugin({
name: 'Make first word red',
hooks: {
postprocessAnalyzedCode: (context) => {
// Only apply this to code blocks with the `first-word-red` meta
if (!context.codeBlock.meta.includes('first-word-red')) return
// Get the first line of the code block
const firstLine = context.codeBlock.getLine(0)
if (!firstLine) return
// Find the end of the first word
const firstWordEnd = firstLine.text.match(/(?<=\w)\W/)?.index ?? -1
if (firstWordEnd <= 0) return
// Add an annotation that makes the first word red
firstLine.addAnnotation(
new InlineStyleAnnotation({
inlineRange: {
columnStart: 0,
columnEnd: firstWordEnd,
},
color: '#ff0000',
// Only apply the red color to the first configured theme
styleVariantIndex: 0,
})
)
},
},
})
}
```
After adding this plugin to your configuration, you can use it like this:
````plaintext
```js first-word-red
consule.log('Hello world!')
```
````
The rendered code block will now have a red text color applied to the first word, but only in the dark theme (the first theme in the configuration):
```js
consule.log('Hello world!')
```
#### Constructors
[Section titled “Constructors”](#constructors-6)
##### new InlineStyleAnnotation(options)
[Section titled “new InlineStyleAnnotation(options)”](#new-inlinestyleannotationoptions)
* `new InlineStyleAnnotation(options): InlineStyleAnnotation`
###### Arguments
[Section titled “Arguments”](#arguments-30)
| Parameter | Type |
| :-------- | :---------------------------------------------------------------------------------- |
| `options` | [`InlineStyleAnnotationOptions`](/reference/core-api/#inlinestyleannotationoptions) |
#### Methods
[Section titled “Methods”](#methods-6)
##### render()
[Section titled “render()”](#render-1)
* `render(options): Parents[]`
Renders the annotation by transforming the provided nodes.
This function will be called with an array of AST nodes to transform, and is expected to return an array containing the same number of nodes.
For example, you could use the `hastscript` library to wrap the received nodes in HTML elements.
###### Arguments
[Section titled “Arguments”](#arguments-31)
| Parameter | Type |
| :-------- | :------------------------------------------------------------------------ |
| `options` | [`AnnotationRenderOptions`](/reference/core-api/#annotationrenderoptions) |
#### Properties
[Section titled “Properties”](#properties-4)
All config options that can be passed to the constructor are also available on the instance as read-only properties.
See [`InlineStyleAnnotationOptions`](#inlinestyleannotationoptions) for the entire list.
## Asset functions
[Section titled “Asset functions”](#asset-functions)
### createInlineSvgUrl
[Section titled “createInlineSvgUrl”](#createinlinesvgurl)
* `createInlineSvgUrl(svgContents, options): string`
Creates an inline SVG image data URL from the given contents of an SVG file.
You can use it to embed SVG images directly into a plugin’s styles or HAST, or pass it to an existing `styleOverrides` icon setting.
The optional `options` argument allows further customization of the generated URL.
#### Arguments
[Section titled “Arguments”](#arguments-32)
| Parameter | Type |
| :------------ | :---------------------------------------------------------------------------- |
| `svgContents` | `string` \| `string`\[] |
| `options` | [`CreateInlineSvgUrlOptions`](/reference/core-api/#createinlinesvgurloptions) |
## Color analysis functions
[Section titled “Color analysis functions”](#color-analysis-functions)
### getColorContrast
[Section titled “getColorContrast”](#getcolorcontrast)
* `getColorContrast(color1, color2): number`
#### Arguments
[Section titled “Arguments”](#arguments-33)
| Parameter | Type |
| :-------- | :------- |
| `color1` | `string` |
| `color2` | `string` |
### getColorContrastOnBackground
[Section titled “getColorContrastOnBackground”](#getcolorcontrastonbackground)
* `getColorContrastOnBackground(input, background): number`
#### Arguments
[Section titled “Arguments”](#arguments-34)
| Parameter | Type |
| :----------- | :------- |
| `input` | `string` |
| `background` | `string` |
### getFirstStaticColor
[Section titled “getFirstStaticColor”](#getfirststaticcolor)
* `getFirstStaticColor(…inputs): undefined | string`
Given any number of input colors, which may include CSS variables with optional fallbacks, returns the first static color.
Returns `undefined` if no parseable static color can be found.
#### Arguments
[Section titled “Arguments”](#arguments-35)
| Parameter | Type |
| :-------- | :--------------------------- |
| …`inputs` | (`undefined` \| `string`)\[] |
### getLuminance
[Section titled “getLuminance”](#getluminance)
* `getLuminance(input): number`
Returns the luminance of a color. Luminance values are between 0 and 1.
#### Arguments
[Section titled “Arguments”](#arguments-36)
| Parameter | Type |
| :-------- | :------- |
| `input` | `string` |
### getStaticBackgroundColor
[Section titled “getStaticBackgroundColor”](#getstaticbackgroundcolor)
* `getStaticBackgroundColor(styleVariant): string`
Determine a static background color based on the given style variant, trying to resolve fallback values of CSS variables if necessary.
This color is intended to be used for contrast calculations, not as an actual background color.
#### Arguments
[Section titled “Arguments”](#arguments-37)
| Parameter | Type |
| :------------- | :---------------------------------------------------- |
| `styleVariant` | [`StyleVariant`](/reference/plugin-api/#stylevariant) |
## Color manipulation functions
[Section titled “Color manipulation functions”](#color-manipulation-functions)
### changeAlphaToReachColorContrast
[Section titled “changeAlphaToReachColorContrast”](#changealphatoreachcolorcontrast)
* `changeAlphaToReachColorContrast(input, background, minContrast, maxContrast): string`
#### Arguments
[Section titled “Arguments”](#arguments-38)
| Parameter | Type | Default value |
| :------------ | :------- | :------------ |
| `input` | `string` | `undefined` |
| `background` | `string` | `undefined` |
| `minContrast` | `number` | `6` |
| `maxContrast` | `number` | `22` |
### changeLuminanceToReachColorContrast
[Section titled “changeLuminanceToReachColorContrast”](#changeluminancetoreachcolorcontrast)
* `changeLuminanceToReachColorContrast(input1, input2, minContrast): string`
#### Arguments
[Section titled “Arguments”](#arguments-39)
| Parameter | Type | Default value |
| :------------ | :------- | :------------ |
| `input1` | `string` | `undefined` |
| `input2` | `string` | `undefined` |
| `minContrast` | `number` | `6` |
### darken
[Section titled “darken”](#darken)
* `darken(input, amount): string`
Darkens a color by the given amount. Automatically limits the resulting lightness value to the range 0 to 1.
#### Arguments
[Section titled “Arguments”](#arguments-40)
| Parameter | Type |
| :-------- | :------- |
| `input` | `string` |
| `amount` | `number` |
### ensureColorContrastOnBackground
[Section titled “ensureColorContrastOnBackground”](#ensurecolorcontrastonbackground)
* `ensureColorContrastOnBackground(input, background, minContrast, maxContrast): string`
Modifies the luminance and/or the alpha value of a color to ensure its color contrast on the given background color is within the given range.
* If the contrast is too low, the luminance is either increased or decreased first, and then the alpha value is increased (if required).
* If the contrast is too high, only the alpha value is decreased.
If the target contrast cannot be reached, the function will try to get as close as possible.
#### Arguments
[Section titled “Arguments”](#arguments-41)
| Parameter | Type | Default value |
| :------------ | :------- | :------------ |
| `input` | `string` | `undefined` |
| `background` | `string` | `undefined` |
| `minContrast` | `number` | `5.5` |
| `maxContrast` | `number` | `22` |
### lighten
[Section titled “lighten”](#lighten)
* `lighten(input, amount): string`
Lightens a color by the given amount. Automatically limits the resulting lightness value to the range 0 to 1.
#### Arguments
[Section titled “Arguments”](#arguments-42)
| Parameter | Type |
| :-------- | :------- |
| `input` | `string` |
| `amount` | `number` |
### mix
[Section titled “mix”](#mix)
* `mix(input, mixinInput, amount): string`
Mixes the second color into the first color by the given amount. Amount should be between 0 and 1.
#### Arguments
[Section titled “Arguments”](#arguments-43)
| Parameter | Type |
| :----------- | :------- |
| `input` | `string` |
| `mixinInput` | `string` |
| `amount` | `number` |
### multiplyAlpha
[Section titled “multiplyAlpha”](#multiplyalpha)
* `multiplyAlpha(input, factor): string`
Multiplies the existing alpha value of a color with the given factor. Automatically limits the resulting alpha value to the range 0 to 1.
#### Arguments
[Section titled “Arguments”](#arguments-44)
| Parameter | Type |
| :-------- | :------- |
| `input` | `string` |
| `factor` | `number` |
### onBackground
[Section titled “onBackground”](#onbackground)
* `onBackground(input, background): string`
Computes how the first color would look on top of the second color.
#### Arguments
[Section titled “Arguments”](#arguments-45)
| Parameter | Type |
| :----------- | :------- |
| `input` | `string` |
| `background` | `string` |
### setAlpha
[Section titled “setAlpha”](#setalpha)
* `setAlpha(input, newAlpha): string`
Overrides the alpha value of a color with the given value. Values should be between 0 and 1.
#### Arguments
[Section titled “Arguments”](#arguments-46)
| Parameter | Type |
| :--------- | :------- |
| `input` | `string` |
| `newAlpha` | `number` |
### setLuminance
[Section titled “setLuminance”](#setluminance)
* `setLuminance(input, targetLuminance): string`
Mixes a color with white or black to achieve the desired luminance. Luminance values should be between 0 and 1.
#### Arguments
[Section titled “Arguments”](#arguments-47)
| Parameter | Type |
| :---------------- | :------- |
| `input` | `string` |
| `targetLuminance` | `number` |
## Referenced types
[Section titled “Referenced types”](#referenced-types)
### AnnotationBaseOptions
[Section titled “AnnotationBaseOptions”](#annotationbaseoptions)
Type: `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-1)
* inlineRange
Type: [`ExpressiveCodeInlineRange`](/reference/core-api/#expressivecodeinlinerange)
* renderPhase
Type: [`AnnotationRenderPhase`](/reference/core-api/#annotationrenderphase)
### AnnotationRenderOptions
[Section titled “AnnotationRenderOptions”](#annotationrenderoptions)
Type: [`ResolverContext`](/reference/plugin-api/#resolvercontext) & `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-2)
* line
Type: [`ExpressiveCodeLine`](/reference/core-api/#expressivecodeline)
* lineIndex
Type: `number`
* nodesToTransform
Type: `Parents`\[]
### AnnotationRenderPhase
[Section titled “AnnotationRenderPhase”](#annotationrenderphase)
Type: `"earliest"` | `"earlier"` | `"normal"` | `"later"` | `"latest"`
### ChromaticRecolorTarget
[Section titled “ChromaticRecolorTarget”](#chromaticrecolortarget)
Type: `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-3)
* chroma
Type: `number`
The target chroma (0 – 0.4).
If the input color’s lightness is very high, the resulting chroma may be lower than this value. This avoids results that appear too saturated in comparison to the input color.
* hue
Type: `number`
The target hue in degrees (0 – 360).
* chromaMeasuredAtLightness
Type: `number`
The lightness (0 – 1) that the target chroma was measured at.
If given, the chroma will be adjusted relative to this lightness before applying it to the input color.
### CreateInlineSvgUrlOptions
[Section titled “CreateInlineSvgUrlOptions”](#createinlinesvgurloptions)
Type: `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-4)
* keepSize
Type: `boolean`
Whether to keep the original size of the SVG image.
By default, any `width` and `height` attributes inside the SVG tag are removed.
### ExpressiveCodeInlineRange
[Section titled “ExpressiveCodeInlineRange”](#expressivecodeinlinerange)
Type: `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-5)
* columnEnd
Type: `number`
* columnStart
Type: `number`
### ExpressiveCodeProcessingState
[Section titled “ExpressiveCodeProcessingState”](#expressivecodeprocessingstate)
#### Properties
[Section titled “Properties”](#properties-5)
##### canEditAnnotations
[Section titled “canEditAnnotations”](#caneditannotations)
Type: `boolean`
##### canEditCode
[Section titled “canEditCode”](#caneditcode)
Type: `boolean`
##### canEditLanguage
[Section titled “canEditLanguage”](#caneditlanguage)
Type: `boolean`
##### canEditMetadata
[Section titled “canEditMetadata”](#caneditmetadata)
Type: `boolean`
### InlineStyleAnnotationOptions
[Section titled “InlineStyleAnnotationOptions”](#inlinestyleannotationoptions)
Type: [`AnnotationBaseOptions`](/reference/core-api/#annotationbaseoptions) & `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-6)
* bgColor
Type: `string`
The background color of the annotation. This is expected to be a hex color string, e.g. `#888`. Using CSS variables or other color formats is possible, but prevents automatic color contrast checks from working.
* bold
Type: `boolean`
Whether the annotation should be rendered in bold.
* color
Type: `string`
The color of the annotation. This is expected to be a hex color string, e.g. `#888`. Using CSS variables or other color formats is possible, but prevents automatic color contrast checks from working.
* italic
Type: `boolean`
Whether the annotation should be rendered in italics.
* strikethrough
Type: `boolean`
Whether the annotation should be rendered with a strikethrough.
* styleVariantIndex
Type: `number`
Inline styles can be theme-dependent, which allows plugins like syntax highlighters to style the same code differently depending on the theme.
To support this, the engine creates a style variant for each theme given in the configuration, and plugins can go through the engine’s `styleVariants` array to access all the themes.
When adding an inline style annotation to a range of code, you can optionally set this property to a `styleVariants` array index to indicate that this annotation only applies to a specific theme. If this property is not set, the annotation will apply to all themes.
* underline
Type: `boolean`
Whether the annotation should be rendered with an underline.
### RenderInput
[Section titled “RenderInput”](#renderinput)
Type: [`ExpressiveCodeBlockOptions`](/reference/core-api/#expressivecodeblockoptions) | [`ExpressiveCodeBlock`](/reference/core-api/#expressivecodeblock) | ([`ExpressiveCodeBlockOptions`](/reference/core-api/#expressivecodeblockoptions) | [`ExpressiveCodeBlock`](/reference/core-api/#expressivecodeblock))\[]
### RenderOptions
[Section titled “RenderOptions”](#renderoptions)
#### Properties
[Section titled “Properties”](#properties-6)
##### onInitGroup?
[Section titled “onInitGroup?”](#oninitgroup)
Type: (`groupContents`) => `void`
An optional handler function that can initialize plugin data for the code block group before processing starts.
Plugins can provide access to their data by exporting a const set to a `new AttachedPluginData(...)` instance (e.g. `myPluginData`).
You can then import the const and set `onInitGroup` to a function that calls `myPluginData.setFor(group, { ...data... })`.
###### Arguments
[Section titled “Arguments”](#arguments-48)
| Parameter | Type |
| :-------------- | :------------------------------------------------- |
| `groupContents` | readonly { `codeBlock`: `ExpressiveCodeBlock` }\[] |
### ThemeSetting
[Section titled “ThemeSetting”](#themesetting)
Type: `Object`
#### Object properties
[Section titled “Object properties”](#object-properties-7)
* settings
Type: `Object`
* settings.fontStyle
Type: `string`
* settings.foreground
Type: `string`
* name
Type: `string`
* scope
Type: `string`\[]
# Plugin API
## ExpressiveCodePlugin
[Section titled “ExpressiveCodePlugin”](#expressivecodeplugin)
An interface that defines an Expressive Code plugin. To add a custom plugin, you pass an object matching this interface into the `plugins` array property of the engine configuration.
### Properties
[Section titled “Properties”](#properties)
#### name
[Section titled “name”](#name)
Type: `string`
The display name of the plugin. This is the only required property. It is used by the engine to display messages concerning the plugin, e.g. when it encounters an error.
#### baseStyles?
[Section titled “baseStyles?”](#basestyles)
Type: `string` | [`BaseStylesResolverFn`](/reference/plugin-api/#basestylesresolverfn)
The CSS styles that should be added to every page containing code blocks.
All styles are scoped to Expressive Code by default, so they will not affect the rest of the page. SASS-like nesting is supported. If you want to add global styles, you can use the `@at-root` rule or target `:root`, `html` or `body` in your selectors.
The engine’s `getBaseStyles` function goes through all registered plugins and collects their base styles.
If you provide a function instead of a string, it is called with an object argument of type [ResolverContext](/reference/plugin-api/#resolvercontext), and is expected to return a string or a string promise.
The calling code must take care of actually adding the collected styles to the page. For example, it could create a site-wide CSS stylesheet from the base styles and insert a link to it, or it could insert the base styles into a `