Skip to content
On this page

VitePress Twoslash

Static code examples for VitePress using Shiki Twoslash — powered by the syntax engine of Visual Studio Code and the TypeScript compiler.

Overview

Try moving your cursor into the code block below:

ts
ts
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property]
}
 
type LockedAccount = {
readonly id: string
readonly name: string
}
 
type UnlockedAccount = CreateMutable<LockedAccount>
Try
ts
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property]
}
 
type LockedAccount = {
readonly id: string
readonly name: string
}
 
type UnlockedAccount = CreateMutable<LockedAccount>
Try

Pretty neat, right? To some extent, anything your editor can show you about code, Twoslash can show. For example, here is the real auto-complete for a VitePress config:

ts
ts
import { defineConfig } from 'vitepress'
 
export default defineConfig({
ti
    
})
Try
ts
import { defineConfig } from 'vitepress'
 
export default defineConfig({
ti
    
})
Try

The name Twoslash refers to specially formatted comments (e.g. // ^?) which can be used to set up your environment, like compiler flags or separate input files. It couldn't be easier to set up and start creating incredible code examples!

Install

Install vitepress-plugin-shiki-twoslash (requires vitepress@>=1.0.0-alpha.61).

bash
pnpm add vitepress-plugin-shiki-twoslash
pnpm add vitepress-plugin-shiki-twoslash
bash
npm i vitepress-plugin-shiki-twoslash
npm i vitepress-plugin-shiki-twoslash
bash
yarn add vitepress-plugin-shiki-twoslash
yarn add vitepress-plugin-shiki-twoslash

WARNING

Until shiki-twoslash uses the same version of shiki as VitePress, you must override the following packages' shiki versions for syntax highlighting to look the same.

json
{
  "pnpm": {
    "overrides": {
      "remark-shiki-twoslash>shiki": "^0.14.1",
      "shiki-twoslash>shiki": "^0.14.1"
    }
  }
}
{
  "pnpm": {
    "overrides": {
      "remark-shiki-twoslash>shiki": "^0.14.1",
      "shiki-twoslash>shiki": "^0.14.1"
    }
  }
}

Tracked in an upstream issue: https://github.com/shikijs/twoslash/issues/180

Configure

First, wrap your VitePress config file with the withTwoslash wrapper.

ts
ts
// .vitepress/config.[ext]
import { defineConfig } from 'vitepress'
import { withTwoslash } from 'vitepress-plugin-shiki-twoslash'
 
export default withTwoslash(
defineConfig({
// Your VitePress config
}),
)
Try
ts
// .vitepress/config.[ext]
import { defineConfig } from 'vitepress'
import { withTwoslash } from 'vitepress-plugin-shiki-twoslash'
 
export default withTwoslash(
defineConfig({
// Your VitePress config
}),
)
Try

Then, import vitepress-plugin-shiki-twoslash/styles.css into your theme.

ts
ts
// .vitepress/theme/index.ts
import defaultTheme from 'vitepress/theme'
import 'vitepress-plugin-shiki-twoslash/styles.css'
 
export default defaultTheme
Try
ts
// .vitepress/theme/index.ts
import defaultTheme from 'vitepress/theme'
import 'vitepress-plugin-shiki-twoslash/styles.css'
 
export default defaultTheme
Try

TIP

You can configure VitePress Twoslash using the twoslash property added to defineConfig.

Add Twoslash

Finally, add the twoslash attribute to markdown fenced code blocks.

md
```ts twoslash
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
  -readonly [Property in keyof Type]: Type[Property]
}

type LockedAccount = {
  readonly id: string
  readonly name: string
}

type UnlockedAccount = CreateMutable<LockedAccount>
//   ^?
```
```ts twoslash
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
  -readonly [Property in keyof Type]: Type[Property]
}

type LockedAccount = {
  readonly id: string
  readonly name: string
}

type UnlockedAccount = CreateMutable<LockedAccount>
//   ^?
```

And your code blocks will be twoslashified!

ts
ts
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property]
}
 
type LockedAccount = {
readonly id: string
readonly name: string
}
 
type UnlockedAccount = CreateMutable<LockedAccount>
type UnlockedAccount = { id: string; name: string; }
Try
ts
// Removes 'readonly' attributes from a type's properties
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property]
}
 
type LockedAccount = {
readonly id: string
readonly name: string
}
 
type UnlockedAccount = CreateMutable<LockedAccount>
type UnlockedAccount = { id: string; name: string; }
Try

Released under the MIT License.