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 {
title Todo.title: string : string
}
const todo const todo: Readonly<Todo> : Readonly type Readonly<T> = { readonly [P in keyof T]: T[P]; }Make all properties in T readonly <Todo> = {
title title: string : 'Delete inactive users'.toUpperCase String.toUpperCase(): stringConverts all the alphabetic characters in a string to uppercase. (),
}
todo const todo: Readonly<Todo> .title = 'Hello'Installation
Install the required packages:
npm install shiki-twoslash-renderer @shikijs/twoslash shikiUsage
Server-side
import { transformerTwoslash function transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformerFactory function to create a Shiki transformer for twoslash integrations. } from '@shikijs/twoslash'
import { codeToHtml const codeToHtml: (code: string, options: CodeToHastOptions<BundledLanguage, BundledTheme>) => Promise<string> } from 'shiki'
import { createRenderer function createRenderer(options?: RendererOptions): TwoslashRenderer } from 'shiki-twoslash-renderer'
const html const html: string = await codeToHtml function codeToHtml(code: string, options: CodeToHastOptions<BundledLanguage, BundledTheme>): Promise<string> (`console.log()`, {
lang lang: "ts" : 'ts',
theme CodeOptionsSingleTheme<BundledTheme>.theme: ThemeRegistrationAny | StringLiteralUnion<BundledTheme, string> : 'vitesse-dark',
transformers TransformerOptions.transformers?: ShikiTransformer[] | undefinedTransformers for the Shiki pipeline. : [
transformerTwoslash function transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformerFactory function to create a Shiki transformer for twoslash integrations. ({
renderer TransformerTwoslashOptions.renderer?: TwoslashRenderer | undefinedCustom renderers to decide how each info should be rendered : createRenderer function createRenderer(options?: RendererOptions): TwoslashRenderer (),
}),
],
})Client-side
Register the custom elements and import styles:
import 'shiki-twoslash-renderer/style.css'
import { register function register(): void } from 'shiki-twoslash-renderer/elements'
register function register(): void ()Examples
Type Inference
let count let count: number = 42
const items const items: string[] = ['apple', 'banana']
const doubled const doubled: number[] = items const items: string[] .map Array<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. ((item item: string ) => item item: string .length String.length: numberReturns the length of a String object. )Error Highlighting
interface Product {
id Product.id: number : number
name Product.name: string : string
price Product.price: number : number
}
const product const product: Product : Product = {
id : 'invalid', name Product.name: string : 'Laptop',
// Missing 'price' property
}Custom Configuration
import { createRenderer function createRenderer(options?: RendererOptions): TwoslashRenderer } from 'shiki-twoslash-renderer'
import { transformerTwoslash function transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformerFactory function to create a Shiki transformer for twoslash integrations. } from '@shikijs/twoslash'
const renderer const renderer: TwoslashRenderer = createRenderer function createRenderer(options?: RendererOptions): TwoslashRenderer ({
// Custom options
})
transformerTwoslash function transformerTwoslash(options?: TransformerTwoslashIndexOptions): ShikiTransformerFactory function to create a Shiki transformer for twoslash integrations. ({
renderer TransformerTwoslashOptions.renderer?: TwoslashRenderer | undefinedCustom 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.