Shiki Twoslash Renderer

A lightweight web component renderer that enhances TypeScript code blocks with interactive hover tooltips, type information, and error diagnostics.

Powered by Shiki syntax highlighting and TwoSlash type analysis.

Demo

Hover over the highlighted code elements to see TypeScript information:

interface Todo {
  titleTodo.title: string: string
}

const todoconst todo: Readonly<Todo>: Readonlytype Readonly<T> = { readonly [P in keyof T]: T[P]; }
Make all properties in T readonly
<Todo> = {
titletitle: string: 'Delete inactive users'.toUpperCaseString.toUpperCase(): string
Converts all the alphabetic characters in a string to uppercase.
(),
} todoconst todo: Readonly<Todo>.title = 'Hello'
Cannot assign to 'title' because it is a read-only property.

Installation

Install the required packages:

npm install shiki-twoslash-renderer @shikijs/twoslash shiki

Usage

Server-side

import { transformerTwoslashfunction transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformer
Factory function to create a Shiki transformer for twoslash integrations.
} from '@shikijs/twoslash'
import { codeToHtmlconst codeToHtml: (code: string, options: CodeToHastOptions<BundledLanguage, BundledTheme>) => Promise<string> } from 'shiki' import { createRendererfunction createRenderer(options?: RendererOptions): TwoslashRenderer } from 'shiki-twoslash-renderer' const htmlconst html: string = await codeToHtmlfunction codeToHtml(code: string, options: CodeToHastOptions<BundledLanguage, BundledTheme>): Promise<string>(`console.log()`, { langlang: "ts": 'ts', themeCodeOptionsSingleTheme<BundledTheme>.theme: ThemeRegistrationAny | StringLiteralUnion<BundledTheme, string>: 'vitesse-dark', transformersTransformerOptions.transformers?: ShikiTransformer[] | undefined
Transformers for the Shiki pipeline.
: [
transformerTwoslashfunction transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformer
Factory function to create a Shiki transformer for twoslash integrations.
({
rendererTransformerTwoslashOptions.renderer?: TwoslashRenderer | undefined
Custom renderers to decide how each info should be rendered
: createRendererfunction createRenderer(options?: RendererOptions): TwoslashRenderer(),
}), ], })

Client-side

Register the custom elements and import styles:

import 'shiki-twoslash-renderer/style.css'
import { registerfunction register(): void } from 'shiki-twoslash-renderer/elements'

registerfunction register(): void()

Examples

Type Inference

let countlet count: number = 42

const itemsconst items: string[] = ['apple', 'banana']

const doubledconst doubled: number[] = itemsconst items: string[].mapArray<string>.map<number>(callbackfn: (value: string, index: number, array: string[]) => number, thisArg?: any): number[]
Calls a defined callback function on each element of an array, and returns an array that contains the results.
@paramcallbackfn A function that accepts up to three arguments. The map method calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
((itemitem: string) => itemitem: string.lengthString.length: number
Returns the length of a String object.
)

Error Highlighting

interface Product {
  idProduct.id: number: number
  nameProduct.name: string: string
  priceProduct.price: number: number
}

const productconst product: Product: Product = {
  id: 'invalid',
Type 'string' is not assignable to type 'number'.
nameProduct.name: string: 'Laptop', // Missing 'price' property }

Custom Configuration

import { createRendererfunction createRenderer(options?: RendererOptions): TwoslashRenderer } from 'shiki-twoslash-renderer'
import { transformerTwoslashfunction transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformer
Factory function to create a Shiki transformer for twoslash integrations.
} from '@shikijs/twoslash'
const rendererconst renderer: TwoslashRenderer = createRendererfunction createRenderer(options?: RendererOptions): TwoslashRenderer({ // Custom options }) transformerTwoslashfunction transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformer
Factory function to create a Shiki transformer for twoslash integrations.
({
rendererTransformerTwoslashOptions.renderer?: TwoslashRenderer | undefined
Custom renderers to decide how each info should be rendered
,
})

API

createRenderer(options?)

Creates a Twoslash renderer with custom web components.

Parameters: options?: RendererOptions - Optional configuration extending RendererRichOptions from @shikijs/twoslash

Returns: TwoslashRenderer - A renderer function compatible with transformerTwoslash

register()

Registers the custom web components: twoslash-root, twoslash-trigger, and twoslash-content.

Call this once in your client-side code.