{"owner":"shikijs","repo":"shiki","hasSkills":true,"totalSkillsCount":37,"totalTokensCount":83983,"categories":["project-spec","anthropic-skill","plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":["docs/api.md","docs/packages/astro.md","docs/packages/cli.md","docs/packages/codegen.md","docs/packages/colorized-brackets.md","docs/packages/magic-move.md","docs/packages/markdown-exit.md","docs/packages/markdown-it.md","docs/packages/monaco.md","docs/packages/next.md","docs/packages/nuxt.md","docs/packages/rehype.md","docs/packages/stream.md","docs/packages/transformers.md","docs/packages/twoslash.md","docs/packages/vitepress.md","docs/references/engine-js-compat.md","packages/cli/README.md","packages/codegen/README.md","packages/colorized-brackets/README.md","packages/core/README.md","packages/engine-javascript/README.md","packages/engine-oniguruma/README.md","packages/langs-precompiled/README.md","packages/langs/README.md","packages/magic-move/README.md","packages/markdown-exit/README.md","packages/markdown-it/README.md","packages/monaco/README.md","packages/rehype/README.md","packages/shiki/README.md","packages/stream/README.md","packages/themes/README.md","packages/transformers/README.md","packages/twoslash/README.md","packages/types/README.md","packages/vitepress-twoslash/README.md"],"skills":{"docs/api.md":"# API References\n\n## `codeToHast`\n\nYou can also get the intermediate `hast` to do custom rendering without serializing them into HTML with `codeToHast`. You can also further integrate the AST with the [unified](https://github.com/unifiedjs) ecosystem.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"aa0ea59b9742ed721640f4d1233696e3e09408080ce58a4fde6a5efd7f40382b\",\"data\":\"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=\"}\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord', 'min-light'],\n  langs: ['javascript'],\n})\n// ---cut---\nconst root = highlighter.codeToHast(\n  'const a = 1',\n  { lang: 'javascript', theme: 'nord' }\n)\n\nconsole.log(root)\n```\n\n<!-- eslint-skip -->\n\n```ts\n{\n  type: 'root',\n  children: [\n    {\n      type: 'element',\n      tagName: 'pre',\n      properties: {\n        class: 'shiki vitesse-light',\n        style: 'background-color:#ffffff;color:#393a34',\n        tabindex: '0'\n      },\n      children: [\n        {\n          type: 'element',\n          tagName: 'code',\n          properties: {},\n          children: [\n            {\n              type: 'element',\n              tagName: 'span',\n              properties: { class: 'line' },\n              children: [\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#AB5959' },\n                  children: [ { type: 'text', value: 'const' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#B07D48' },\n                  children: [ { type: 'text', value: ' a' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#999999' },\n                  children: [ { type: 'text', value: ' =' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#2F798A' },\n                  children: [ { type: 'text', value: ' 1' } ]\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}\n```\n","docs/packages/astro.md":"# Astro Integration\n\nYou don't need explicit integration in [Astro](https://astro.build/) as Astro already uses Shiki under the hood.\n\nLearn more about the configurations in the [Astro documentation](https://docs.astro.build/en/guides/syntax-highlighting/).\n","docs/packages/cli.md":"# @shikijs/cli\n\n<Badges name=\"@shikijs/cli\" />\n\nShiki in the command line.\n\n## Usage\n\nThe Shiki CLI works like `cat` command, but with syntax highlighting.\nIt also supports remote files.\n\n```bash\nnpx @shikijs/cli README.md\n```\n\n```bash\nnpx @shikijs/cli \\\n  'https://github.com/shikijs/shiki/blob/main/taze.config.ts?raw=true'\n```\n\n## Install\n\nYou can also install it globally. Command aliases `@shikijs/cli`, `shiki`, `skat` are registered.\n\n::: code-group\n\n```sh [npm]\nnpm i -g @shikijs/cli\n```\n\n```sh [yarn]\nyarn global add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add -g @shikijs/cli\n```\n\n```sh [bun]\nbun add -g @shikijs/cli\n```\n\n```sh [deno]\ndeno install -gREn skat npm:@shikijs/cli\n```\n\n:::\n\n```sh\nskat src/index.ts\n```\n\n## Options\n\n### `--theme`\n\nSpecify the theme to use. Defaults to `vitesse-dark`.\n\n```bash\nnpx @shikijs/cli README.md --theme=nord\n```\n\n### `--lang`\n\nLanguage is auto-inferred from the file extension. You can override it with `--lang`.\n\n```bash\nnpx @shikijs/cli src/index.js --lang=ts\n```\n\n### `--format`\n\nSpecify the output format. Defaults to `ansi`.\nSupported values: `ansi`, `html`.\n\n```bash\nnpx @shikijs/cli README.md --format=html\n```\n\n## Node.js API\n\nThe `@shikijs/cli` package also provides a Node.js API.\n\n::: code-group\n\n```sh [npm]\nnpm i @shikijs/cli\n```\n\n```sh [yarn]\nyarn add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add @shikijs/cli\n```\n\n```sh [bun]\nbun add @shikijs/cli\n```\n\n```sh [deno]\ndeno add npm:@shikijs/cli\n```\n\n:::\n\n### `codeToANSI`\n\nThe asynchronous `codeToANSI` function allows you to convert code to ANSI escape codes for terminal output.\nThis is useful for rendering syntax-highlighted code in the terminal.\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord')\n\nconsole.log(highlighted)\n```\n\n`codeToANSI` takes three required parameters:\n\n1. `code: string`\n2. `lang: BundledLanguage`\n3. `theme: BundledTheme`\n\nand one optional parameter:\n\n4. `options?: CodeToANSIOptions`\n\nThe color level of the emitted escape codes is explicit instead of being inferred from the environment, and defaults to `3` (truecolor). Use `options.colorLevel` to target a different level — pass the level reported by `ansis` to follow the current terminal, or `0` to get plain text:\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\nimport ansis from 'ansis'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord', {\n  colorLevel: ansis.level,\n})\n```\n","docs/packages/codegen.md":"# shiki-codegen\n\n<Badges name=\"shiki-codegen\" />\n\nCodegen for Shiki to create optimized bundles dedicated for your usage.\n\n## Usage\n\n### CLI\n\n```bash\nnpx shiki-codegen \\\n  --langs typescript,javascript,vue \\\n  --themes light-plus,dark-plus \\\n  --engine javascript \\\n  ./shiki.bundle.ts\n```\n\nFile `shiki.bundle.ts` will be created with the code that you can use in your project.\n\nThen you can use it in your project:\n\n```ts\nimport { codeToHtml } from './shiki.bundle'\n\nconst html = await codeToHtml(code, { lang: 'typescript', theme: 'light-plus' })\n```\n\n### Programmatic\n\nYou can also use `shiki-codegen` programmatically, and write the generated code to a file:\n\n```ts\nimport { codegen } from 'shiki-codegen'\n\nconst { code } = await codegen({\n  langs: ['typescript', 'javascript', 'vue'],\n  themes: ['light-plus', 'dark-plus'],\n  engine: 'javascript',\n  typescript: true\n})\n\n// Write the code to a file\n```\n","docs/packages/colorized-brackets.md":"---\noutline: deep\n---\n\n# @shikijs/colorized-brackets\n\n<Badges name=\"@shikijs/colorized-brackets\" />\n\nVSCode-style colorized brackets transformer for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/colorized-brackets\n```\n\n```sh [yarn]\nyarn add -D @shikijs/colorized-brackets\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/colorized-brackets\n```\n\n```sh [bun]\nbun add -D @shikijs/colorized-brackets\n```\n\n```sh [deno]\ndeno add npm:@shikijs/colorized-brackets\n```\n\n:::\n\n## Usage\n\nAdd to your Shiki transformers:\n\n```ts colorize-brackets\nimport { transformerColorizedBrackets } from '@shikijs/colorized-brackets'\nimport { codeToHtml } from 'shiki'\n\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: 'dark-plus',\n  transformers: [transformerColorizedBrackets()],\n})\n```\n\n### Colors\n\nBrackets are automatically colored according to your Shiki theme (or themes if using [dual themes](https://shiki.style/guide/dual-themes)), with support for all of Shiki's built-in themes. However, you can customize colors if you've added custom themes to Shiki, or if you want to override the colors of a built-in theme:\n\n```ts colorize-brackets\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: myCustomTheme,\n  transformers: [transformerColorizedBrackets({\n    themes: {\n      'my-custom-theme': ['goldenrod', 'blueviolet', 'dodgerblue', 'crimson'],\n    },\n  })],\n})\n```\n\nThe final color is the mismatched bracket color. The other colors are for each \"level\" of bracket pair. Any valid CSS color can be used.\n\nIf no bracket colors are found for a theme, it falls back to the default `dark-plus` theme.\n\n### Brackets\n\nYou can customize the bracket pairs:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  bracketPairs: [{ opener: '{', closer: '}' }],\n})\n```\n\nThe above would only colorize `{}` curly brackets. The default config colorizes `[]` square brackets, `{}` curly brackets, `()` parentheses, and `<>` angle brackets (only in TS type annotations).\n\nFor advanced usage, you can specify which TextMate scopes a bracket pair is allowed or denied in, using `scopesAllowList` and `scopesDenyList`. For example, the default config for `<>` angle brackets is:\n\n```ts colorize-brackets\nconst bracketPair = {\n  opener: '<',\n  closer: '>',\n  scopesAllowList: [\n    'punctuation.definition.typeparameters.begin.ts',\n    'punctuation.definition.typeparameters.end.ts',\n  ],\n}\n```\n\n### Language-specific Overrides\n\nAll settings can be overridden for specific languages using the `langs` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  langs: { ts: myCustomTypescriptConfig },\n})\n```\n\n### Explicit Trigger\n\nIf you do not want colorized brackets for all code blocks, you can enable the `explicitTrigger` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  explicitTrigger: true,\n})\n```\n\nThen, only code blocks with the `colorize-brackets` [meta string](/guide/transformers#meta) will have bracket colorizing enabled.\n\n````md\n```ts\n// no bracket colorizing\n```\n\n```ts colorize-brackets\n// brackets will be colorized\n```\n````\n","docs/packages/magic-move.md":"---\noutline: deep\n---\n\n# @shikijs/magic-move\n\n<Badges name=\"@shikijs/magic-move\" />\n\nSmoothly animated code blocks with Shiki. Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n`@shikijs/magic-move` is a low-level library: at its core is a framework-agnostic [diff/animation machine](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/core.ts) and [renderer](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/renderer.ts), with thin wrappers for Vue, React, Solid, Svelte, and a Web Component.\n\nEach framework wrapper provides three components:\n\n- **`ShikiMagicMove`** — the main component; wraps a code block and animates whenever `code` changes\n- **`ShikiMagicMovePrecompiled`** — animations for compiled tokens, without the Shiki dependency at runtime\n- **`ShikiMagicMoveRenderer`** — the low-level renderer component\n\n`ShikiMagicMove` needs a Shiki highlighter instance plus the bundled stylesheet (`@shikijs/magic-move/style.css`). Whenever `code` changes, the component animates the diff.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/magic-move shiki\n```\n\n```sh [yarn]\nyarn add -D @shikijs/magic-move shiki\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/magic-move shiki\n```\n\n```sh [bun]\nbun add -D @shikijs/magic-move shiki\n```\n\n```sh [deno]\ndeno add npm:@shikijs/magic-move npm:shiki\n```\n\n:::\n\n## Usage\n\n### Vue\n\nImport `@shikijs/magic-move/vue` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```vue\n<script setup>\nimport { ShikiMagicMove } from '@shikijs/magic-move/vue'\nimport { createHighlighter } from 'shiki'\nimport { ref } from 'vue'\n\nimport '@shikijs/magic-move/style.css'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst code = ref(`const hello = 'world'`)\n\nfunction animate() {\n  code.value = `let hi = 'hello'`\n}\n</script>\n\n<template>\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    :options=\"{ duration: 800, stagger: 0.3, lineNumbers: true }\"\n  />\n  <button @click=\"animate\">\n    Animate\n  </button>\n</template>\n```\n\n### React\n\nImport `@shikijs/magic-move/react` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport type { HighlighterCore } from 'shiki'\nimport { ShikiMagicMove } from '@shikijs/magic-move/react'\nimport { useEffect, useState } from 'react'\nimport { createHighlighter } from 'shiki'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = useState(`const hello = 'world'`)\n  const [highlighter, setHighlighter] = useState<HighlighterCore>()\n\n  useEffect(() => {\n    async function initializeHighlighter() {\n      const h = await createHighlighter({\n        themes: ['nord'],\n        langs: ['javascript', 'typescript'],\n      })\n      setHighlighter(h)\n    }\n    initializeHighlighter()\n  }, [])\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      {highlighter && (\n        <>\n          <ShikiMagicMove\n            lang=\"ts\"\n            theme=\"nord\"\n            highlighter={highlighter}\n            code={code}\n            options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n          />\n          <button onClick={animate}>Animate</button>\n        </>\n      )}\n    </div>\n  )\n}\n```\n\n### Solid\n\nImport `@shikijs/magic-move/solid` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport { ShikiMagicMove } from '@shikijs/magic-move/solid'\nimport { bundledLanguages, bundledThemes, createHighlighter } from 'shiki'\nimport { createResource, createSignal, Show } from 'solid-js'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = createSignal(`const hello = 'world'`)\n\n  const [highlighter] = createResource(async () => {\n    return await createHighlighter({\n      themes: Object.keys(bundledThemes),\n      langs: Object.keys(bundledLanguages),\n    })\n  })\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      <Show when={highlighter()}>\n        {h => (\n          <>\n            <ShikiMagicMove\n              lang=\"ts\"\n              theme=\"nord\"\n              highlighter={h()}\n              code={code()}\n              options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n            />\n            <button onClick={animate}>Animate</button>\n          </>\n        )}\n      </Show>\n    </div>\n  )\n}\n```\n\n### Svelte\n\nImport `@shikijs/magic-move/svelte` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```svelte\n<script lang=\"ts\">\n  import { ShikiMagicMove } from '@shikijs/magic-move/svelte'\n  import { createHighlighter } from 'shiki'\n\n  import '@shikijs/magic-move/style.css'\n\n  const highlighter = createHighlighter({\n    themes: ['nord'],\n    langs: ['javascript', 'typescript'],\n  })\n\n  let code = $state(`const hello = 'world'`)\n\n  function animate() {\n    code = `let hi = 'hello'`\n  }\n</script>\n\n{#await highlighter then highlighter}\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    {highlighter}\n    {code}\n    options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n  />\n  <button onclick={animate}>Animate</button>\n{/await}\n```\n\n## `ShikiMagicMovePrecompiled`\n\n`ShikiMagicMovePrecompiled` is a lighter variant of `ShikiMagicMove` that doesn't need Shiki at runtime — useful when you want to ship pre-tokenized step data (e.g. produced at build time) and animate between steps in the browser.\n\n```vue\n<script setup>\nimport { ShikiMagicMovePrecompiled } from '@shikijs/magic-move/vue'\nimport { ref } from 'vue'\n\nconst step = ref(1)\nconst compiledSteps = [/* Compiled token steps */]\n</script>\n\n<template>\n  <ShikiMagicMovePrecompiled\n    :steps=\"compiledSteps\"\n    :step=\"step\"\n  />\n  <button @click=\"step++\">\n    Next\n  </button>\n</template>\n```\n\nTo produce the compiled tokens, run this somewhere with access to Shiki (build script, server, etc.) and serialize the result:\n\n```ts\nimport { codeToKeyedTokens, createMagicMoveMachine } from '@shikijs/magic-move/core'\nimport { createHighlighter } from 'shiki'\n\nconst shiki = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst codeSteps = [\n  `const hello = 'world'`,\n  `let hi = 'hello'`,\n]\n\nconst machine = createMagicMoveMachine(\n  code => codeToKeyedTokens(shiki, code, {\n    lang: 'ts',\n    theme: 'nord',\n  }),\n  {\n    // options\n  },\n)\n\nconst compiledSteps = codeSteps.map(code => machine.commit(code).current)\n\n// Pass `compiledSteps` to the precompiled component.\n// Since these are plain serialisable objects, you can stringify them at build time\n// and rehydrate them in the browser without needing Shiki.\n```\n\n## How it works\n\nFor a deep dive into the algorithm behind the animations, see Anthony's article [**The Magic In Shiki Magic Move**](https://antfu.me/posts/shiki-magic-move).\n","docs/packages/markdown-exit.md":"# @shikijs/markdown-exit\n\n<Badges name=\"@shikijs/markdown-exit\" />\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for Shiki.\n\n`markdown-exit` is a modern TypeScript rewrite of `markdown-it` with native async rendering support — no extra library needed for async highlighting.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-exit\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-exit\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-exit\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-exit\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-exit\n```\n\n:::\n\n## Usage\n\nThe default export uses Shiki's [shorthands](/guide/shorthands) for on-demand loading of themes and languages. Since highlighting is async, use `md.renderAsync()` to render:\n\n````ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n\nconst html = await md.renderAsync(md_string)\n```\n\n## Custom `codeToHtml`\n\nIf you have a custom `codeToHtml` function (e.g., from a fine-grained shorthand bundle), use `fromAsyncCodeToHtml`:\n\n````ts\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\nconst md = createMarkdownExit()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-exit/core` and pass your own highlighter:\n\n```ts\nimport { fromHighlighter } from '@shikijs/markdown-exit/core'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = createMarkdownExit()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n","docs/packages/markdown-it.md":"# @shikijs/markdown-it\n\n<Badges name=\"@shikijs/markdown-it\" />\n\n[markdown-it](https://markdown-it.github.io/) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-it\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-it\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-it\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-it\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-it\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"959709c97c288ea5ed5a231f28e5eebf48f1676e9c76559e68208cb76e2b6711\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n```\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"7251d42df549db899085560c6ca05a99dc9f338642b7849507ef0ead24fa6dba\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n```\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-it/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4cce3b72c2224ceff07c637806719480ab0b5bcdb0fafc8ad599ec8c8ad5d255\",\"data\":\"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\"}\n// @noErrors: true\nimport { fromHighlighter } from '@shikijs/markdown-it/core'\nimport MarkdownIt from 'markdown-it'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = MarkdownIt()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n\n## With Shorthands\n\nShiki's [shorthands](/guide/shorthands) provides on-demand loading of themes and languages, but also makes the highlighting process asynchronous. Unfortunately, `markdown-it` itself [does NOT support async highlighting](https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#i-need-async-rule-how-to-do-it) out of the box.\n\nTo workaround this, you can use [`markdown-it-async`](https://github.com/antfu/markdown-it-async) by [Anthony Fu](https://github.com/antfu). Where Shiki also provides an integration with it, you can import `fromAsyncCodeToHtml` from `@shikijs/markdown-it/async`.\n\n````ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4d4fcf8100ee107a1813af12192e944bfcf04449a77daa41fca68ea887412763\",\"data\":\"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\"}\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async'\nimport MarkdownItAsync from 'markdown-it-async'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\n// Initialize MarkdownIt instance with markdown-it-async\nconst md = MarkdownItAsync()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    // Pass the codeToHtml function\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformer Caveats\n\n`markdown-it` defaults to enforcing `<pre><code>` as the outermost wrappers of code block html. If you use a custom Shiki [transformer](/guide/transformers), this behavior may be undesirable. For example, if the transformer produces\n\n```html\n<div class=\"fenced-code-block\">\n  <pre>\n    <code>\n      …\n    </code>\n  </pre>\n</div>\n```\n\nthe result after `markdown-it` processing will be\n\n```html\n<pre>\n  <code>\n    <div class=\"fenced-code-block\">\n      <pre>\n        <code>\n          …\n        </code>\n      </pre>\n    </div>\n  </code>\n</pre>\n```\n\nWork around this by adding [olets/markdown-it-wrapperless-fence-rule](https://github.com/olets/markdown-it-wrapperless-fence-rule) to your `markdown-it` configuration, or by writing your own `markdown-it` fence rule (see [markdown-it#269](https://github.com/markdown-it/markdown-it/issues/269)).\n","docs/packages/monaco.md":"# Monaco Editor Integration\n\nShiki uses the same TextMate grammar and themes as VS Code, so it can be used to highlight Monaco Editor. Shiki provides an official integration for Monaco Editor. You can also use [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration.\n\n## @shikijs/monaco\n\n<Badges name=\"@shikijs/monaco\" />\n\nUse Shiki to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\nMonaco's built-in highlighter does not use the full TextMate grammar, which in some cases is not accurate enough. This package allows you to use Shiki's syntax highlighting engine to highlight Monaco, with shared grammars and themes from Shiki.\n\nHeavily inspired by [`monaco-editor-textmate`](https://github.com/zikaari/monaco-editor-textmate).\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/monaco\n```\n\n```sh [yarn]\nyarn add -D @shikijs/monaco\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/monaco\n```\n\n```sh [bun]\nbun add -D @shikijs/monaco\n```\n\n```sh [deno]\ndeno add npm:@shikijs/monaco\n```\n\n:::\n\n### Usage\n\n```ts\nimport { shikiToMonaco } from '@shikijs/monaco'\nimport * as monaco from 'monaco-editor-core'\nimport { createHighlighter } from 'shiki'\n\n// Create the highlighter, it can be reused\nconst highlighter = await createHighlighter({\n  themes: [\n    'vitesse-dark',\n    'vitesse-light',\n  ],\n  langs: [\n    'javascript',\n    'typescript',\n    'vue'\n  ],\n})\n\n// Register the languageIds first. Only registered languages will be highlighted.\nmonaco.languages.register({ id: 'vue' })\nmonaco.languages.register({ id: 'typescript' })\nmonaco.languages.register({ id: 'javascript' })\n\n// Register the themes from Shiki, and provide syntax highlighting for Monaco. // [!code highlight:2]\nshikiToMonaco(highlighter, monaco)\n\n// Create the editor\nconst editor = monaco.editor.create(document.getElementById('container'), {\n  value: 'const a = 1',\n  language: 'javascript',\n  theme: 'vitesse-dark',\n})\n\n// ...As you use the editor normally\n```\n\n## modern-monaco\n\n<Badges name=\"modern-monaco\" />\n\nWe highly recommend using [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration. It provides a more convenient API for building Monaco Editor.\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D modern-monaco\n```\n\n```sh [yarn]\nyarn add -D modern-monaco\n```\n\n```sh [pnpm]\npnpm add -D modern-monaco\n```\n\n```sh [bun]\nbun add -D modern-monaco\n```\n\n```sh [deno]\ndeno add npm:modern-monaco\n```\n\n:::\n\nOr import it from [esm.sh](https://esm.sh) CDN in the browser without a build step:\n\n```js\nimport * as monaco from 'https://esm.sh/modern-monaco'\n```\n\n### Usage\n\n```html\n<!-- index.html -->\n<monaco-editor theme=\"vitesse-dark\"></monaco-editor>\n<script src=\"app.js\" type=\"module\"></script>\n```\n\n```js\n// app.js\nimport { lazy, Workspace } from 'modern-monaco'\n\n// create a workspace with initial files\nconst workspace = new Workspace({\n  initialFiles: {\n    'index.html': `<html><body>...</body></html>`,\n    'main.js': `console.log('Hello, world!')`,\n  },\n  entryFile: 'index.html',\n})\n\n// initialize the editor lazily\nawait lazy({ workspace })\n\n// write a file and open it in the editor\nworkspace.fs.writeFile('util.js', 'export function add(a, b) { return a + b; }')\nworkspace.openTextDocument('util.js')\n```\n\nMore usage please see the [modern-monaco](https://github.com/esm-dev/modern-monaco) repository.\n","docs/packages/next.md":"# Next.js\n\nShiki does not provide an official integration for [Next.js](https://nextjs.org), but it is rather straightforward to use Shiki in Next.js applications.\n\n::: info\nUsing Shiki on Edge Runtime might cause unintended problems, Shiki relies on lazy imports to load languages and themes.\n\nServerless Runtime is recommended.\n:::\n\n## React Server Component\n\nSince Server Components are server-only, you can use the bundled highlighter without worrying the bundle size.\n\n```tsx\nimport type { BundledLanguage } from 'shiki'\nimport { codeToHtml } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHtml(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return <div dangerouslySetInnerHTML={{ __html: out }} />\n}\n```\n\n### Custom Components\n\nYou can also call `codeToHast` to get the HTML abstract syntax tree, and render it using [`hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime). With this method, you can render your own `pre` and `code` components.\n\n```tsx\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHast(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n    components: {\n      // your custom `pre` element\n      pre: props => <pre data-custom-codeblock {...props} />\n    },\n  }) as JSX.Element\n}\n```\n\n## React Client Component\n\nFor client components, they are pre-rendered on server and hydrated/rendered on client.\nWe can start by creating a client `CodeBlock` component.\n\nCreate a `shared.ts` for highlighter:\n\n```ts\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki/bundle/web'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki/bundle/web'\n\nexport async function highlight(code: string, lang: BundledLanguage) {\n  const out = await codeToHast(code, {\n    lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n  }) as JSX.Element\n}\n```\n\nIn your `codeblock.tsx`:\n\n```tsx\n'use client'\nimport { JSX, useLayoutEffect, useState } from 'react'\nimport { highlight } from './shared'\n\nexport function CodeBlock({ initial }: { initial?: JSX.Element }) {\n  const [nodes, setNodes] = useState(initial)\n\n  useLayoutEffect(() => {\n    void highlight('console.log(\"Rendered on client\")', 'ts').then(setNodes)\n  }, [])\n\n  return nodes ?? <p>Loading...</p>\n}\n```\n\nThe `initial` prop can be passed from a server component to pre-render the code block on server.\n\nIn your `page.tsx`:\n\n```tsx\nimport { CodeBlock } from './codeblock'\nimport { highlight } from './shared'\n\nexport default async function Page() {\n  // `initial` is optional.\n  return (\n    <main>\n      <CodeBlock initial={await highlight('console.log(\"Rendered on server\")', 'ts')} />\n    </main>\n  )\n}\n```\n\n::: info\nThe above example uses the `shiki/bundle/web` bundle. You can change it to [Fine-grained Bundle](/guide/bundles#fine-grained-bundle) to fully control the bundled languages/themes.\n:::\n\n### Performance\n\nShiki lazy loads the requested languages and themes, the Next.js bundler can handle lazy imports automatically.\nImporting `shiki` or its web bundle is efficient enough for most Next.js applications, Fine-grained Bundle won't significantly impact the bundle size.\n\nIn addition, you can use the `createHighlighter` API to preload specific languages and themes.\nPlease refer to [Highlighter Usage](/guide/install#highlighter-usage) for further details.\n\n### Highlighter Instance\n\nIf you define a highlighter (without `await`) as a global variable, you can reference it directly from server and client components.\n\n```ts\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript'],\n})\n\n// Inside an async server component, or client side `useEffect`\nconst html = (await highlighter).codeToHtml('const a = 1', {\n  lang: 'javascript',\n  theme: 'nord'\n})\n```\n","docs/packages/nuxt.md":"# Nuxt\n\n[Nuxt](https://nuxt.com) is a general-purpose meta-framework that gives you full control over your application. You can install Shiki along with integrations like ([markdown-it](/packages/markdown-it), [rehype](/packages/rehype)) or import manually as you needed.\n\nOn top of that, Nuxt also provide some module integrations for Shiki allowing you use it easier:\n\n- [`nuxt-shiki`](https://github.com/pi0/nuxt-shiki) - Shiki integration for client and server sides, with component usage.\n- [`@nuxt/content`](https://github.com/nuxt/content) - Nuxt Content has Shiki built-in for markdown files. [You can enable it with the `highlight` option](https://content.nuxt.com/docs/getting-started/configuration#highlight).\n  - [`@nuxtjs/mdc`](https://github.com/nuxt-modules/mdc) - The underlying module of `@nuxt/content` that provides Markdown Component (MDC) syntax as well as Shiki for syntax highlighting.\n\n## TwoSlash Integration\n\n- [`nuxt-content-twoslash`](https://github.com/antfu/nuxt-content-twoslash) - A Nuxt module that adds Twoslash support to Nuxt Content. Twoslash information are evaluated at build time.\n","docs/packages/rehype.md":"---\noutline: deep\n---\n\n# @shikijs/rehype\n\n<Badges name=\"@shikijs/rehype\" />\n\n[rehype](https://github.com/rehypejs/rehype) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/rehype\n```\n\n```sh [yarn]\nyarn add -D @shikijs/rehype\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/rehype\n```\n\n```sh [bun]\nbun add -D @shikijs/rehype\n```\n\n```sh [deno]\ndeno add npm:@shikijs/rehype\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"f652dc1d308709739c1be11a9172b77ef0b59d02c30ad9b2f5dc7195fad4cd45\",\"data\":\"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=\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThe default export of `@shikijs/rehype` uses a shared instance of `shiki` from `getSingletonHighlighter`, which will persist across processes. If you want full control over the highlighter lifecycle, use [Fine-grained Bundle `@shikijs/rehype/core`](#fine-grained-bundle) instead.\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import `rehypeShikiFromHighlighter` from `@shikijs/rehype/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"141199456275121b3ddecb36bbeedc3ec800ba9c5d4c78ec0a3f651e44ac22ee\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjHzYYAZXzsA1uwBipCAFsAEuwDm+DkZqlGyoyfxnEvfVcM2yAcRhgy7EQB5mYDBS8fhgAfIEQWOKScHYASrLySqrsAMIQMgDykRJgPHYAKqR+cPzp2mTesRAQaIFVNSEAOmDs2ljpaNIJOElqmjoOxk5mlCBwaMykDIgA7FSs7gZo+EgATABsVBOkBjDTIDJyPcp9WnpO1iPz7B5IAAxUIviTzGJkSDMAvhTo8niEJHIWzo+xYHC4fBE0U6h0SaFINwM7H4GDsAAVWIIkWBvMhGFkorleAAfXhgQSsVgk3jCWD8G4wKDcAD8AF06tVarxxgiwAYmi02h0ukdFPDEciMKMoBARAhECAMVibrw0BAglAoNzBFh2lMBOluZ42OwAF6IoJwez5ACyABkAHSjCYGeXIZDUZQIKi8XhYLQieBwdJO9kerAvbSjNJgekGQRFQm8RgRQlsbihigemRoBO5Ua+gByNWUfND7LG22m6wAnPNFsskABGACsW0mu32sJ64r5ktGHFuiCbj2eRTe5Fm31+OH+xHewPoTBNEN4UNyMJg2kmKjRkzgMHRmOxuMY8WYMrArAw3gJOTgIWp5Mp1NpMHpHiZbMCPMRHIazStHqm7bqQu77rgVAynKeAAIKatqurCqUpB+vuFr8GcvCgSoMoAO5gE67aukg7qeuw3ogL6/qykGIYgGGIARkUUZUDGcYJswSYptkkjppm2Z7HmlFFiWiLllQ4yTNMTZNpsIALHyjbDiO1AdnseAyDhe6kAeA4Mmso4vBOHzTtQfwKgCC7UCCy7gjwAjCGIORdDh8SiowNGBnAwakOiAZ0aQ4S8bkzJxDAF6SNet4hQ+T4UlSpJvh+jLcAURS5Ch2gAEIIlAuzJgA1KsvDzqQrAQBePCAUK+paTu7l/FBsryiA+R5thO74VINxqta9oOs0zQAMSjaNvDFjQcBDWAY1jbwCiGGAXEJjAM0AFS8MiQR+gFPmGhRvBIiQYAUM0vqkMIVrLDAybdjAfBYMeNxWoIB5apIW2dHh7DLDtzzjKqMgwGdUiqvg7i8FAFEiJMUDXRDXRwBSnSMOtABGeUFdo0AwOt3DNJtJZkD9B6gxdQmkESzC8ADnTwjAIPneDt1PcqRJvYyQT8GYvAAAb1WBjU4HzQQyCK8h+s9RJo9oggTDQ2G4/jM2PoAvBuAJI7vDretk14+tiDNI+ACSaCAJgEVqWMYGA0leqgwNe4NcbwGAQIIvB4X49PqhGPk7XzXmBXzg1gCNc3Df1dozbEzB4ZHW1WswRDMOwrDMOjCxbVI2hQFwnRcPzNjaKwouQLAidgFqsNSOjt1brXmpcyqdPNAXB7aBREyV3D/NFHhpe43AIc2hAgNs9iVpLekt0C7HA/l7w6Py6qeHqpAEwZ7dkjwFDkhm2ghuh2Am0C90MAALS/n2KKi2wwa0wXfilSF/NsBVeEACJ+LsWhvboaDF1FnhZQTwPap1YMzN2aAsDLxutIWOkcQ6+nyF6BOqpsBeDfjbaGcAoScV2FqAu68uboxtnA1MLllrlEXsvQ6nMhBUmRMzV27soRtAWDQR28I3r53loQXShNe5n3Pn3UW1cH6V0znAvuvB66MlgFqXQto7Tcl7K6ReNtmJwAtDdbQzNerqikt3UgWo6ZkkHsmPmDstzuDQHzQIfMaD0HsbItAIhuAAG5mbLEOodGmEMk5kK4CoS0X0ySM3hjtBhVIlH2jQrpMg5MaGdF+mg8hV4baezIYYnUwFbbcPGFzdcNAwBoBmuHCO6hOTEOmkfG0wRn6EitMjJCUwuYQ3FjINOis+qlBqDUkOVT+k1B3pMW669uQ4BEMidgJCbZpG0DjMA9SwKg2AV4fAHtbqlEpBAOOpCobvmYCjEOKCYA2zGYhYCczeAuF+roQQ6NQb3z6WgGpa4n611kctTeWoVQ4W6mAv6p8cLnwMPwbQwcZpnMafefmrziHZVeCoO06cHa30rvC6pIzUW1xLoclKZIVpFCpGnPkghmC7GaMsZ2dAnopyJAikZcA1kgM2YdZQjcpAoW5MMLmnNdLJO5IQAiqp1RcG0eMdgJBVQwCeJACqBgMAhwAOoQykCw1CEYCqHQmSqAAonyDgcB8CgxYdhHhBKGRA2KN0rmydMTwBDs0JFIgQkyH4GQdw3kaQHl4LBWIxtYJBDQOKJeU1QbhpZkaZyn0054q+geVg/BfWjNphFaGfInYpMtuwLlQLNl+GaHzOApBz5RQwGItOPlTmGJFWEvq2jTD8oPLpUGdJrXQ34J6mQpSQ1hvljvFUfMmU0FxQ7NEWgcBTFmXAKFR8Km8BSBVdGtdeQGBmkMt5zKs7wmgIIH1NMaKb20KDAuqTBwqCtKO26sNKTXXVDeq1LQmmlSkHA7Vt1li/yMPzPNfNW6hoROGneuwPCJi5phHQqbULFNsayjZSMUaTykB/DINo1wrrXeJGaaGMMiCw54LNh0fExBmnzCjRcIE4iwFtKAABeWgIRvAAHosACm8LghEkQQhsDIGgRgtA+AsZY/zWgA844erIA+6NeH+ZYGGuJ2RCxyilNY1x9gPHi0UZmvqlTtirQHJuuwVCxsP5i1utuWAQRk6p3TpnA5mM9mtqtJ9OBfMfqVz2aLCA6MABWcrajNHWaAvxMaEy/RtgiOAKgQ4AFVtFZqPR69gtBuQQFYCQBGh1j0qedcs6eWcspcRcp9etfVniSNvYR9dQRMUfpS2lw6dK04Mj+Ufda+raDMHYYedNF5ERWkYHJgjvnsN8m4JtYd91L5+F+maGA86w5zV4HFsAKhICirLvAGaa2Nt7KkNtxO4sjsFp2pgHA2aE5gH3lnQufgoALF0j51CAcJUoJ/fgedMK6THNYJ0WuzwiASFQjy4Q+2tsWIoofQRwDIZwO2w/RO/MHWCEW8zFgmKZTwBu50IHM9c4TAdPgQsPXFsOMJ8wYnk6Ij8dnS4w0fNKfE5SMoVgUBe32OZgeW6drSDcCSSIGQXFbr+LzvzJxdjzGwEEcTUgpMmZgyFxFRWNM+beGhkQEIotrGqdRiFzZeD2eL1vZVghZ2mdcSpyTsnfMBfMx+n9X6Vonipw55DbcupINYRzuLir4uC54QdtR5oKDDqA6TiDj5NdTffxub7RLBg6v83B5tsAugHtPeDs6SlboPRlQqheSgz5WCMQL5VKAxeEpl8BIXyvFAS+MWYj16U8BxDLSTDT7yvlSqwckBxRMLkeJplYBmBiWYmKRlGBQ6IvA1WQ2S7RfaqFPZWmOu4UG64B8lc+sPnI/Fx+CVzFTSihRihZQkpWaSzYWxtgUg2FYw5Vjth2BpBUgsVDC0ggpAyiAADMRk44IwU4Pw5ks4lkZUzotkCoYInADkQgogSYyuIugwlwZAaQMge+0QdgqBfKpAGBMAd40Q3g/Ad8MAIQaUvANOHcB43guBza+B08AoQEwoyBNA9BzgjBMg0oLUeAKQwuquC0Jw7Aa4hWVsaBqEL0XcgYgQjumykAvAZK8YlKO8houiO8S8VWUAqqXA2gdWWoEUoCShFKBUD2LM1CcsgMXydeXM245IWCREakJEKAHoPOowNg0CiAImJqyQDo4wGACwLG8YeaMALGmhj28Aw0KUYKRQbW584RCwDEFYUkUwzYNYAAHPWEpI/qsKpNsJ2HgGwTABwWYAQfpEOAACyAGvDAE1hmQXa4AQGAhQFLgwErjwFORIECGEEtDxiXTbiGrYgwBYGhR2B2gV4qq6FEFEikgl6UHUEUQwCVAwC7C0CDEMjMG1SdBFEZC9EJiCADF9i3CSRVhrAVF1j37ZFrB5HqT7A7F7H9HMDrHHE/5Dh35PDGS1H1EWQECQGLigjtGQjQi2wzKMj+RL6+TeDJRtaBDQmfiwmVzvgwm2wdrwkolImfibF5LCCgn14gDQStT8Eq6i7hJxyBzL6OEuh54gB0A9ZPTf7IKoK0m9bCrOa0x7I7QeBkl7Q97iJfJFFaiMBQZ6Ego7h276GKE3AqCMjeLqg6zjCZo6yMAVF8BmHyloAyjyxKkqn5a+gUZ8x+a1K+gsH6jknXpYQADk22iAZpFp+iWxohogXECgDMPWAglp64sMaAl8rp2gdpYMJpnQwAH+nw7p0GFpH+/pzMZpfhGpNwDoWAmmwxzMvonpzpvpQpnRQ+S8/AfAwAKZvou0EJsZmpaADoeECINAjALp66jAH+jAGYZpCgGAogjAOZ3AHZBZnwBMYMPZepFGh+BwlM+YPoE0MAcc60wgUGpo7gm0ZphojAAcPJ6QduupvAYeVo85khLu/ehgq0WofUq8YE0acAZOoSzudW3kaopASCc+6q0a5cgY3cfaW5aCW+e5Mg7W0aQgx+t0qS2OVo68zMzA3agW0afgV5JKRZ3e9ErIyRpx/+TYABlxSwj+cwakr++wOJ9IjI5RjR6FHxQB7wiAdRoBDRc4zR/xhRwJ4heBOBFweBZRJx1+/+FRd+ikqFzYNxmF/wDFDBeFSAFxhFNRxF6w3x4BvxlFNkrRIAsBq4RRJR6B08IxMQ9gfFnBBB0xcAJBZBFB4JNBSxilXB5BNUeSCl6lpR08PBMECoRJIuO0vQIhUI4stFDBWcRiMhZ2ChxhKhrmqE6hhmtICw2hzQkxcAehZhhhmyPlph9WEMFhlq1hFethfgFKlIyqOezhZEbhVAHhWAXhLGPhagsZARoRwRsAYRQVkR0RBgsRn48RVVSRzFqR/+6w7FD+1xL+BRCo5ljgDBTFrxjRQlY4Ilk4Gw4ljRkl1kkuTANE06mAfARlmlsUOlrAB4IQDoAVYU658VMAxsYAMCaAyArIr4iJKUeJBJeAZy1CVC8A4Q/lu1XQSIPIO+UgvmAWYgMmSVF4/KWAUGpSjhKR0wf+NYqkHFyk8k+Rb+noNilEg4jRTYDwIAwlJkiAqwE1FF010Bslc1/GGAi1FlSlmQK1pBa15BDoShcA21qK5KKh+1h1x1p1qJuFzUNlIANNyhBUt1LKveih38Jht0Mgz18Ir1pU/mgWX1vOyVWoOo/1ZZowQNSAbFz+KFykd+UN+wlNAlw4yFKNwB6NZFPxVkQI0loIuNUw+NalfVGl08Wlq161DoiwDIdgsEnsv09mSx8Qqxzx5B1lhJPC0GXtXWtGTtHggNCFLYdwFx4Nj+kNtxeAod3+8NzY8ketxFBtM4k1xtLRAJ9kkI3RuxH5BxTxRxwxM+oxvA4xF4YV2gWl8UlI8xZwixyx3tpdWJrBBdDxxdPtCtEdTY6FMdnVGF3VyNndRdhxQx2tck1RqNiNGNTRWNMl64gMfcdgwQvdLFLYMwA9HV/+XV0NfcU9w1nxol89U1JtM1Co69zV0wLY6R0du9KtGteA/AcNv+TYx9RFk4TY6RZ92dVFV9/gG9LVLYNYKtg9iAmRw9B9Ga6gqcSd79n9o11xf9fxpt1FG4Ag8DdgAAanA4kTfUgOsLkVkZxYgFUdA/sPSAQ4NWsEjWnZOGJYbRJf/eg20XnSCThVAA2eCTBaQFCWdciXCYyAiczVAKIxiSI+iede3fqNhbMhdbwbZd0ZyeOdBYFJSbnqRB6MyfSQWDtc1t1iySamyfWjTFyeo8vtHibmuN0YKcKUIjhOKWYZejKWDH1OqYqetMqaqZip41AtqRmDNP2QaUaVtA6WaWGXoVabjDaTyf6caQ6WmWgDWRFHoQ4xackz6cLn6faXksGVuDuKGRk5GcE5Y0PAqfGYmTgIwAWck6kz1pmYgdmYILmbwPmWDIWeUyWVAuWZWcMTWYiHWYU2BA2QmTyc2a2e2Z2Z07wN2czH2fzAOYxDmMJPo4WGo5ObGFoDOcfOUwuUuRCSuUE0fIyTlsuduY6QPlzIeekCEnAqedQuemgBXFeSGMzPPu+ojI+e4LnC+Rc2+buX0U3F89svLKtGEgBeYmUmDCBZ6mIOBaIG3lBVuZforYgOsH/hQxA+hc/QqPIyzbQ2jfQyNbPaRZnZjRfdjYwOUMsNAHwF3oFAI2IxI+day0I4I2icI1ABtZzLiOyKouuv+GgCEJ5NLEeOzPyz+GosK2ELwA6Aq83rS9JnYIzaSMgOjNUAsH4KyI3Uc/w/UFyNy+y1y5y1I9y4+IwMVKVLXhXjwH7XwUCxCw1vq2KqmjtOPDcIEDTMap0BACmm9B7bwKjndbzcwM0P6PAHsPlsbCmi63w2gmwMLlADbG9BaEetLIEA1jAMDm7JudLM0O+X0aLYdB8XyCQlwFzG5ojOXQjM7JcgniCyHPtaVDdCvukPDFm4jJ6z1IBTUBqAojtAeOuAea0DAPlo+DrHrDrHYHzJzGIn4BMvyW/FW1IOtNObOfs7pCHI+CkG/NGq+fSLpN7LY8Sao3HFOTs5DKi5ldSbozQ4yV6hZp1P4B7MwBgDJgnlLOzDJsHJzA2fOmc1aPe7dOvhXDa2QMDuOTDmDPqYaXk8KMAAS1AMU5ach1GWDMhw2QWSJlQdLGdrW4fF0w6P+z27BIEMALQHYNwiDC7NR5dDAPM7M7h3uD5DoojI86zPh5SgythGQLsDubGB+aLYwH1HzJR/R2joEKiAIGQYEKaJJ4x3bkR4WSRweGK+zOR+0zJ6TWTLwAp0DGjkx10yx9LGRrM2p8McgD29lIED2ykLqzh6JvkKvN+xPF27dMO5IFqHIbCtgQWZZ4wNZ9LB/IEMF+zPqhR58HBYs76CxzIAeN9L9Jsj2xXFqIl+3q6Cp76IF8AKl6qz2+oGFz2y4FF3BT+HsJl6pXl6PPNpIHYLp4x8Z4WbhwoJV4Nm+teNl/K/+8ABl4NnYDV9ooSA12QZ8M1/qYOTQOwiLqMMALBKQEUDeKngdiEKGcgDpGTmYHAPRsdayFN1uPSjQHN8WNZqSFfEnklGayh7wMgPTfLPRty/t4xNN0d9/sgBkPLIdfRvd2gM9xPuXkXg3tXgD7a0D43qD2QHXlXpSE3lPlQCG6tqeZvMG2wGjgJJPixKMEq3sNJlQZGLj22h7PeRm+zGguvlII/L6kGyGxj6syftGAmL2p0De+V1fi1esBUTvVcXvZQ3gJzNrSQ8jaS8AX/qg1JZfbJYCY6SvSM+BAkhKyeHiOeJeNFFpY+LMQlEzZI1+AKxd7K6ZcKB/jpHpKza1PBOl7kshIaFohhD7l1Adpo1lR6KRvo6zxPkq9GE64PrvuXQfis8OSJBNGJGWE1ez9WC2GDbvbJPvV2HLybwg0OELww6ZMw1nWg5LzS3sIQEyFQRc5UJyCa+a9d0X+I9I21ry7QcdcK7Kxp9iIrzcFK7wIa7K4EAqwmQT9t6qydeq5qxlhFGALq7w0yy3834X2PzUKX6X5a9a4D/DNwA67Zd71+t2wC31JzB65mztL66VAG8j5nCGzzYaOGwdQl9GzNLGwewC34qwMm6m4npv+zB57tDmxIG9G5zcIW97yWy7mbhW+9G+mjS1srsDbCVE22aAts5cHsDtjzQ/T4ddU/bC8IOxphed6sY7CdtrF1gjIZ2KeA8AuzABLtb0K7D6Guw3Z7MtyQ8I2Eun3bxtAoWDY9m6yKLntbYZArdk7zvZGM9Go5M5OLEuR2FMk77T9hKg/5EgxOgXbgIBwMbAdOBmcMDsnjKhQc8IMHEJvBwDIOkkOLQLhqh3DLocymWHWLrwFM5k9fOhHALqR2lhacJOhnWjjJxo7Nc4uomVjg/weZnke2QQAwLx3KCv5BO2+biGJysE0dpOo3MmvJ0U6fBlOZg9TmRwo46c5O+nMIQYKMETxuugXcLtiFs4iCHOiQ5zq51S7P9UBPnZLn51yApD/2aQm4KF1u49tIu7TaLo52Y6OCz+SXP6KlwlL9c+Q5nYjr13y5VDpYRXXoezFK61DyuRoUNAN3abtBhuOQYIQeHG7ZCFo7XDoZ11RCRDhifXRYVlwmG1cRusnMmnMOZiTcXuh3O1HNwW5LcBGEOMAGt1u6bdlWukXbnBQO4zdjuVAYAKd1ujnc1E2vc6ut1+6Pdru/3F3scNm5UAPuX3B7r90BEgA5+MPUvJD3KgV5YRNeKHoiOB6w8Pe8PEAIjwSw080e47Qcp7yoA49tu+PFiITx5pw5KeIg8ntKgXzI5A2KPWnoOXp4jkQAKQJnrYjYFh90W6wdYNzzIbIU8WIAAXtcCT4q0U+/+cXovVzpwE+ACBWNFIA/xf5PIFzYfsvmChNJtqKvCtDFCaQa8yQWvK7mI0oJn5MoZQXKHmgKhWsSoc/aqIKDyRKiz4i/NqB1ABQHZd06oWJI6HKQrY9YtSZbPNEWgGAO8q0DaFtBTSL4E2h0CnkkkuiiDEYwzUUI9DM6poSBYSXzmLkBgMxFcvoG6FIBwSwwTECMQWvABRjJgMYWMSzMrB7JEw22CuWMYH3+h+5gYSSOAT+1THcxeYopIWGfFvidIz4IgobOtDlgKwqxsAFWEfHVhawp22Ag2FQNNgWxaYFwVNnbGlJcJngnQc1J7D7R9Qv2auLcktlmjhxI40cBBF6MTa2Z40mcf5LnEBgFw+YVGeeKMkxR8k642gBuIO2bh5xW4zSLcJ3Aew9xZ4/caXE6maAjwx4KYqeOLCAlPjAq9MVzuvCDbbwrQl4feDBxPgzYLukoW+GtXVAAx5BL8PmG/D2Rfxy2v8OAP/EATE9EMP0SkJAnBH0xEYMiL0beQ3JpIMEd6R2AWLdhFBzcRCEZFqCMw1sX4t1IVHQgPAMJwxzCN2KIV6ycIyEl0O8XwnSC1IMJwiURNY0qwRFo0MiORI3EUTKJBWHXA5LbyzS6J9EpSQxF3FzgmIkcnQU7IuV1y2IXEjiEEC4j2DuIvE7jVBGFgCREAgkMWc8vZIiTI5ok8cLRIkmZhRpUkJGGthkjfbZIrkwoYQAUhoBVxJAJSGFgGPGhboakM0epK+2AEtJrkpiJ9l0nsq9JsUU0QZFVNGQnZ+2cAKZLiQ0RLodASyFZCoAQygIg8BoXZPsmwRHITkoeCGBcnFjFSOgNyO5GgAeRPJmgLyWqS7k+R1wfkwVO7G6NFS+duxKgMFBCkPEwpgBI6Wqa6hRRop8UZhQ6cMjHSnTRYzNIlMfjYB81aaVKUpBuNkS0B6UL0A0JdLurBY2UaCTlLAG5SGgm0zgGWi5iFQmNRUfUCVJ3FpGyp5UGWCAEqlVT3lNUaEHVH2xSRSBBixqU1M0HNSWFOgt0kWrkDtRahD++WY6V0B7Teod4G/ANEGn7TAZB0LKZoFGgeaBYXI8aB2Imgdh7800ASTNEnhpQ5olx+aDMUfBLRloK0VaCVLWlZJxxUkjaPlGDOkztpJGUMZEDTL7RcQB0U0O7BdO3RXS8UNOeavTnyyLpl0Y2IjBuiPi5Sd0vULQFAAPRppcsW4M9JPE6CXpr0tUj5PejdZPpUSdXIkNW1ZgqFwYn2P9FAAAwd49ZoGdwGQBFxagHGAqR0plK6mbIEuyGO7CNhqw4Yj4uc62bVlinQ5yMlGABNRm8C0Y80jGZjGxg4waYeMfGKYIJmEyiY+YSmTbNTLx59Q4EcmAOIph1z6Y1MhVIXJphFbaYY5zQPTDYlKSGYyEEMEzLwDMzPsrMouS8UG0cxaA8I4M0OfzE8z4QfM4tMQBnMTbhZKyUWCiLFmaAJZ02L/ekGlmDCZYd4pGIsienywjxxYNwYrEmDKwcl/cVWTDEXPTZxVWYjWNBC1gZQgtCYXWOkgsDsCCyOuw2dDEAtXQ2zJsBszCXNnEAzlDxi6PbGnhAn+iwABC90adkuSnYMx6CS7CLOuy3Zh0Wkp7HOl5pvYfIH2N2EYG+zfNBp/2E3EDijxg51shC07KXI6zE94ciMRHPhLVwhsY5voTHFqAAq44H4MqS3EThtzlAXJzOfAKbLpzwAGcr2bRazjdyc4kkPOPmmYHtxK4VGmYzoK5OcQgTZcdYxYoLhsX8wNc0qbXMplnn64/pRuQSbHnLaFDgU2i0nJoqsW+hfOF5V3Ozl7SdQvcycn3LeJPZmJA8weaFKggjy5tYMS0tcH/0EmaIYZSWKQHOyEUHYM8VWUgNnmIjUkYRaIuEfnjB714IejSlEeDxB7hhMR5cdvKLUZZWNDQRbTiNxD96j4MehI6EbFDvIL4t2b7NfLSNOhf8hOxbYZSFH94T4WRp+DKCUDKBosEKfIqPjzybBP1467+OXl/kF7iiRexFL4Gn0pY50mAtLHPgy3z6j9Xl4/Y1uX0xKWdcQrlTgvRWtpmA3A4GLwL4H8Det/AcrQjs3zPiOVlqTSAVm8oaB18bgDfHEMgF+W2AraQwBgkCs8A+Bgg4K0IBqPvDhRRQsK22rFARXj9DWcrdvsSJVa3c++2rQftSHRWE0/IWKiQrioRD4qwVdWIlcUNUpf5yVxNeFXqz4YF9J+E/LkKPw+UWsioNoppfazN6OsllzrVfq63X5+pSe2Ib1pKUBj+tqejIvEUf1Qgn9I2iXGNnGw1VRjE4t/DNPfzvk9tn+kbXNu/x7aLLfBLkUtvksXiVs0x5CSZbQtAE+RwBYASAW22gFFiXV8AzGQOy5goC5U3nVUOgNViYDp2BsXAYtmjyEC/Zq0z6OuyvbkCLmlAq4dQJfC0CrGR7LMeqCYHmM1Gl7CALsy5E1LtGNJGQQyR2pPs+BDSLJEIL9itCxB/7CQaxKZIdqjotI8DgoNmRKCymcHMJoGXabIdtB0TXQac04YKNsODQvDsYKKGmCLO5gzThRyo7WCgh1g+wYYMcFFLhZHHVwdxw8H/J+OO8QZT7ykCid1Q4nE9YELo67C9OBnOwREIPVRCLBMQmYbR3/UMcL1SQl6KUPU7lCwAGQ+zvUJM45CfYZnfIUmsxQmDYosGqzj20qHwaahwAOofMMnRRtmhKXFMWYXaFZdVhjAPLmZwK59Diu0sIYcRpGE0bqukw4OWBv2Hbq2uYwpYRWlw30bONg3bjTsMa58aQmTwt7qcMW7vsLhaea4Rt077SYHhUI17icNeHvDqQF3b4W1l+EHUHuT3WTdppABgjoEEI4zX90HJ1KWl0IppUiPhHQ96lcPLHgjzxFI9cRjqMZZiPpWCpbh5I2QiT2pHRj5loSGmAyIP54i6egfRnot05Gs94KLFdYOkSgYQNBRJy4UabyJarBdaVyycGL1uUL0qWMlOSh0WaafR7ojlfoOcABVkALA7K/5dis4LcqQVBK/lZCpw3QqyVwhOFfeBNFbKsoFQRFRPPtFG8YVwhOrUZWAbVgwGpDZSBsFj6aQptyQGbeysF4FaT6k4G5RS1K33KeqNFZrZysYpWVCGswVYEjQgYx8+elkTbaKMaL5aZ6ovFsFKLK1m0p0eNPgGkFgBaUbQKMTTAsGurwBvA2UKqlABB0bUAq6IaSJwFYDLFnKUATjDKy7XlAvancV9bBFfakhBmfIO0L9ETmsA1sOQMHRDpB3St10IQanc6ODSe5d+ohCqKhG5pusAqpyVBMRJ3kuwZJjaJqSiAtT/YgdK/WGgaAeqgcE5EGdKbAHyz6kXmzQDFWQAdBQhYA+QCAJRNYCMBldtHDpr6CUJ2ALShpC0q2N2rVcCylwfXcDimgHhz4lwI3QWRskqALdhO0NefAd126wYnwZoEx31IzQVU4CI6BLpFwwd9SVGZoJxgjBSB/CCwejI0GRqIy/Iw0WSE2A8TnxL4whV3TuEQBRFu0XiEACEC13qYI9AoSbq2pcJjBGY7hUNFgBiAiYkQywR5Erp0CFVhChpZvckGGiXAHdrutKufACrciEK29eSBAzjo8UFQfex7WsHeKFala72w7TjS+0W0+A5u3gLHst1BgL4lwWPXNo+ALbVaj+dWtlsuCC9U60+jFrPoAbz7aci+qGJnpX1Yjnd1uh3Vvou3pFVg4DXehQyFEO7BeBFU/Uw323n059WfOlrnz6WQkxtNfT5cXzEaV8li1faVZTsRCise2qKpvqPwu60rFWam3SN31ZVMqB+Q/PPvq0lUyrqVZBqVRgYVUQcERVUBfiqqX5qrxYlanvFqpJLOrt+ncBndFtuiH97qQQCNk0KtVX9XWN/O/r6idVb9s2bq/NuzE9XCckwPquPIJP9WADA1r6YNeLEbbtZm2b1SNUeU7YHtY10LeNYQhjTJrxA5QDATOJoA4C52eAnNf22XaUhV22sMgXORLU7ty1VIZg4aGrUns61pJFgUWpbVOEOBcCztTwNFzix+BCU/tTIYnhus/26nEdczDYkgcJ1WWeQYCEUHKClmoTBDvqA0G4kV1vAC0muuZj6CnOO67EARxw10boh7TL9QxzPV2DSN16k8nerJ48dH13gq5vIaHz+CmjUnH9Y11CHnrANXQ4DUeu05gaxjrRqo0qGSF0b4NiG6WFkKqMuc0NP7DDSO1qNNIRN8GgjdULK7IaWujQ8jWdlaHUaNhnQ1Tt0MY0DDsQ/Q+DWxrqEVdBNmwobjxt/VNd5hAmqrssJE3rCPjXG7YdMJ+PSa8jZmkESAHm4KbluZSgiCpqC3bcNN0Jl4bCd02fDasRonXkZu+6majhzw97p9ys1oAfuNmqEfZo6WOa2lzSmk9SfRGdKPNWIrzTiONW+aCR/m7A1aBRNqzxFVItweFpOiRajVMWzkwH2Pysj2RiW/5vq12UsV0id9RbY/iy2j6ctifRon/hJY7akAxWgA6w0z7S9l6m4MlWoklCoG8QddTXi+FxPnUWQVKig2olkamm4Q66fsPQcVD4doZCEcafqB5Stp4dZodNlaBYm3s21rvUcu72ZMt42I3/FZSPjHySm1mo5SaKWAMAKmWq6RYhiqZvwrbTlZp90yiG1ramXt1y8/Ww1kqPL6WRBiVRAYQMNmMD4zCEpMxEBCl4G21BZBGHEAo87TbWSgng3gbOiwD0aCnlg0zgFwX1LhnwzeRmjY7ZEi3A6AjG3k9QIxcAFsk8C0CQB3+JM7ZaQG0DHZb0y/EKpOPTWzjZ2TZDc6LEwiMwZyxYmZdtAmRJsHVrhotetCsNYCbDmaw5t3lbOixp0WUe8xFMCBxjwV6Xc0/zqwAAwnU4ZsveMuoa3R8Gt0EYumA8TULME6VfmBdxez8xBzCwPmGhYaSI9XggYSIAmtqQdzRYw6CxnheGJCZs8yZhnlQGGlgKISkGeBvlhhQRSy+u5kbWXzMJsJEyq0xHn4g3ko8uIxaBCw6FkXJhzFxCE5lQOsP6w7AyHdC5xJtiCX4G88o0AiBNDmg+QdgHGOMCoGaWmFXQKU1hbUSiwUwr2OLL1HSJnD32q5KgQoB0BHm2g8DInsjFAQFx0kR5xg1zDkJUDkAp8UUCIkMJ2JWQyAGbMLjEACsWRrbDpKj0dRDYVQr82GHpxP6PhzwCLbMScxNgpoWEZscWGmySyyShLZAK7EotuyBm9LtHOlGBS7TayYWj4LObwoplGwqBqup6p3EqsiAA6ehNqy8zuz5BEgY8yIN6wQi6IxUVA4AAAAFL0Wu1qR5YWDxBkY/2epFgE+D5Zor6kiK6yAQVV6a9QRZLg3rYQsZ7oremKxFf72KnX9uZlSPmaYgTMNzJZ1SBKP1NgF0+EvbGiafgRKD+V2+yBjWGxa701TI9Q+hPsQplnv6b2isFrrwCLqat02s4EZSialG5rRVdgFdbPgsZnKMAf0kjZhUQWbYJTYRFhJRCE2HSxvCCOjYjJy9z4EUqmw6LOUDiyboKe6MzcQ6nsUC7KggnMzptY28b08Lm4UZ5s0BC6fRbuqXQFsZMhbidFjJIHHrMAMOi64ABuq5glGyjmghRhhz+sK7UI9GIIG7W2LdElqylHXeYXgCqsCygZRgBaUxst64ALGAKixjX0u7bdizdkMzEpo23Zmdth21jdb2U0WMfmJOFwHGtoALSES3gN7bBiJ07A9xZWz7UYANleA9GR8AHaFur4/SMzJjospXoIIjbscFOJ0FfoOhk2SF+2w6BYw3BDqDoHONHYLtl34G6d426XY1vcNFmgXGmwkm7v/tHRSY5mD3bW2nABg7KwIAbYo5VHGc6ha88f15RGphd5QAsjDvaYFlddwwJ3Vbo33DB3dXTX0A7u3vr6M9YEfe4WU90e7+76nGrSTe7uXnWyfcNuV9AtJ2r74kw7RCj13E8luQG5/AFubzbXhRgtLZgEgFAAgh3A2iSQHgBeYgBxuQAA\"}\n// @noErrors: true\nimport rehypeShikiFromHighlighter from '@shikijs/rehype/core'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nimport { unified } from 'unified'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst raw = await fs.readFile('./input.md')\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShikiFromHighlighter, highlighter, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .processSync(raw) // it's also possible to process synchronously\n```\n\n## Features\n\n### Inline Code\n\nYou can also highlight inline codes with the `inline` option.\n\n| Option                  | Example          | Description                                                 |\n| ----------------------- | ---------------- | ----------------------------------------------------------- |\n| `false`                 | -                | Disable inline code highlighting (default)                  |\n| `'tailing-curly-colon'` | `let a = 1{:js}` | Highlight with a `{:language}` marker inside the code block |\n\nEnable `inline` on the Rehype plugin:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"549ef2ad84b55c413cb40bcedc19dcf805008cf25a703dd1f3614dff89dbdd93\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    inline: 'tailing-curly-colon', // or other options\n    // ...\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThen you can use inline code in markdown:\n\n```md\nThis code `console.log(\"Hello World\"){:js}` will be highlighted.\n```\n\n## Postprocess Transformers\n\n::: info\nThe `postprocess` transformer hook is only invoked when producing HTML strings (i.e., when using `codeToHtml`). Since `@shikijs/rehype` operates on HAST (Hypertext Abstract Syntax Tree) rather than HTML strings, postprocess transformers will not be executed.\n:::\n\nThis design is intentional: running `postprocess` hooks in rehype would require converting HAST → HTML → running postprocess → parsing back to HAST, which changes the semantics and could surprise users expecting HAST-only transformers.\n\n### Workaround for HTML-based Postprocessing\n\nIf you need to run HTML-based postprocessing with rehype, you can apply a `root` transformer that:\n\n1. Converts the HAST fragment to HTML using `hast-util-to-html`\n2. Runs your HTML transformers\n3. Converts back to HAST using `hast-util-from-html`\n\nExample:\n\n```ts\nimport { fromHtml } from 'hast-util-from-html'\nimport { toHtml } from 'hast-util-to-html'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    },\n    transformers: [\n      {\n        name: 'custom-html-postprocessor',\n        root(node) {\n          // Convert HAST to HTML\n          const html = toHtml(node)\n\n          // Apply your HTML transformations\n          const processedHtml = myCustomPostprocess(html)\n\n          // Parse back to HAST\n          const newNode = fromHtml(processedHtml, { fragment: true })\n\n          // Replace the node\n          return newNode\n        }\n      }\n    ]\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n","docs/packages/stream.md":"---\noutline: deep\n---\n\n# @shikijs/stream\n\n<Badges name=\"@shikijs/stream\" />\n\nStreaming colorization for Shiki. Useful for highlighting text streams like LLM outputs, where code arrives incrementally and you want each chunk highlighted as it lands without re-tokenizing the whole document.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/stream\n```\n\n```sh [yarn]\nyarn add -D @shikijs/stream\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/stream\n```\n\n```sh [bun]\nbun add -D @shikijs/stream\n```\n\n```sh [deno]\ndeno add npm:@shikijs/stream\n```\n\n:::\n\n## Usage\n\nCreate a transform stream with `CodeToTokenTransformStream` and `.pipeThrough` your text stream:\n\n```ts\nimport { CodeToTokenTransformStream } from '@shikijs/stream'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\n\n// Initialize the Shiki highlighter somewhere in your app\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\n// The ReadableStream<string> you want to highlight\nconst textStream = getTextStreamFromSomewhere()\n\n// Pipe the text stream through the token stream\nconst tokensStream = textStream\n  .pipeThrough(new CodeToTokenTransformStream({\n    highlighter,\n    lang: 'javascript',\n    theme: 'nord',\n    allowRecalls: true, // see explanation below\n  }))\n```\n\n### `allowRecalls`\n\nDue to the fact that highlighting may change based on the context of the code, themed tokens can be re-evaluated as the stream progresses. Because streams are one-directional, `@shikijs/stream` emits a special **recall** token that tells the receiver to discard the last N tokens that changed.\n\nBy default, `CodeToTokenTransformStream` only emits **stable** tokens — no recalls. The trade-off is coarser granularity, usually one line at a time.\n\nFor stream consumers that can handle recalls (e.g. the bundled Vue, React, Solid, and Svelte components), set `allowRecalls: true` to get finer-grained tokens.\n\nTypically recalls should be handled like:\n\n```ts\nimport type { RecallToken } from '@shikijs/stream'\nimport type { ThemedToken } from 'shiki'\n\nconst receivedTokens: ThemedToken[] = []\n\ntokensStream.pipeTo(new WritableStream<ThemedToken | RecallToken>({\n  async write(token) {\n    if ('recall' in token) {\n      // discard the last `token.recall` tokens\n      receivedTokens.length -= token.recall\n    }\n    else {\n      receivedTokens.push(token)\n    }\n  },\n}))\n```\n\n## Consume the Token Stream\n\n### Manually\n\n```ts\ntokensStream.pipeTo(new WritableStream({\n  async write(token) {\n    console.log(token)\n  },\n}))\n```\n\nOr in Node.js:\n\n```ts\nfor await (const token of tokensStream) {\n  console.log(token)\n}\n```\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/vue'\n\n// get the token stream\n</script>\n\n<template>\n  <ShikiStreamRenderer :stream=\"tokensStream\" />\n</template>\n```\n\n### React\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/react'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Solid\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/solid'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Svelte\n\n```svelte\n<script lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/svelte'\n\n// get the token stream\n</script>\n\n<ShikiStreamRenderer stream={tokensStream} />\n```\n\n## Cached Renderer\n\n`@shikijs/stream` also ships a simplified renderer for the common case of an incrementally-updated code string (rather than a token stream).\n\n::: warning Experimental\nThis API is experimental and may change.\n:::\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiCachedRenderer } from '@shikijs/stream/vue'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\nimport { onMounted, ref } from 'vue'\n\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\nconst code = ref('') // code should only be updated incrementally\n\n// for demo purposes\nonMounted(() => {\n  setInterval(() => {\n    code.value += '\\nconsole.log(\"Hello, world!\");'\n  }, 1000)\n})\n</script>\n\n<template>\n  <ShikiCachedRenderer\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    lang=\"js\"\n    theme=\"vitesse-light\"\n  />\n</template>\n```\n","docs/packages/transformers.md":"---\noutline: deep\n---\n\n# @shikijs/transformers\n\n<Badges name=\"@shikijs/transformers\" />\n\nCommon transformers for Shiki, inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/transformers\n```\n\n```sh [yarn]\nyarn add -D @shikijs/transformers\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/transformers\n```\n\n```sh [bun]\nbun add -D @shikijs/transformers\n```\n\n```sh [deno]\ndeno add npm:@shikijs/transformers\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"8efec5d385627b3d23e03e4c9bdf13f9a3c80178f3105cfb878cd54cef1eacb9\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZAHIQ0zcZIAi7fv0YQsO+QH5EvACqz5iles3aJYfYYDyp1zysBlfHYAa3ZbOQUlVVIAHTB2ZSwlNGk7CMdSDS0zd35KECgIEQREEABVOBheAANkAEIRaEqAaiaAXSreOShquobYXgBaAfbpCF5lZlIgzqhYbq7eUhhlYhhujjB4ADo8uC1SBkQAZgAWKlYYMABzNHwkACYjqn2rmEPqVIcozJc9A1zzuxNg8qCJ8JNmGIyA8AL4UdDYXAlQgkcjPOjvFgcLh8BryZJ9GDWCAACTQylYVkYhKse1IQKuFF4JjMcCsAGFGsSSVw0F5WQAeABCwigFygABk5FdBMxXkyRWAxWtrPhljAAHx8AC8Gt4AAVSBBlOwKgK6QyNbF4okDrxCdzyaxdvtDgBGN0ABnOlxud0QXuek1e7wdpKdeQ2SIAbKDwbIoeREPc4QicHgUdD0fQ8Hi9vbGlZoiA8xALltWBArowAORq1iVmvcYsuybuk5nEAXa63JCdl5vXONSNApEATjjEMTSGjqeoiIzqzR1AxQ/xvHwTtpMgZrYOSDdAA5vV3fb3EP3g4PkRHAcCAyewVOaEnZ/D5+nkUu8jQcyUsZwPAFrAjoUtSha8Ba1xMiyPgclypK8vyPjCqK4pStcsryrwirKlAqrqlqViGsapowOaO7XFacQJEkwFEuGFJ7u6Y5PKePb+oG1BXqGCFkkxd5IlxT4Ji+B5jnOmCfgQ37Zrx640rwxaluWlbVnWMANhATYtlQextg8nqdt2fp9kGpAhkOsAjvewnxpCYnHJ6kkLl+qI/qu/5YEaOAHBgfCsNKRbUHAukgPp+7Jm6xlnv6l4WdeXbSjZQlupOonQsmLnSZmy6/pi3kmGQmB8JysDIZIcB+AyFwEaoqFKuKdWalstzqlYzUAEowFcpoyL8YAAIJgBgvAAD68H4lFXBK7AvmwpRxJIDV4c1TJQVcGrMQ89yHj6HFIAArOZlklG1qgpQe9zpQ5mUpu+UlIjJ7lyUwhW+SVNifJEZAVfIrXfekcCWJNgQhGE9g/aQyCtONvCijA/CjlAeQFEUeAQ2kURwAISjSGqoPBOwvBYOwOBRjsemug8JzHexpkBtd3EJe8/WQ0Dl0BmxIm3Um91pk9uUeX+IAATiKThF8ThZK4OTGN4lUg5jUsZM42T/H9viE+DgNRNatF2mzWPSwNOSo4UxRlBUPT1I0vAtCMCw1Lb/RDCMaBjBMUwzHMnRKosyyrOso5wJT4XU8m0Z0yZ56PCdiVGyrPzq4YnPRTd04XjCrSgsOJQAPT57wvR24EVz4Bw5doIgh2tPrtrJMAsS8BL7PfGrsv/BQze8IXvBbAPsQwgIRrKLwNYAAJwGD7AAFZwPnidQ3ANb13RTdSPRoGsN3YDD/wo/j9PROr2AsR5gSdvatUKkwBWVa1vWjbcFU5+Vckm4Urw1/MAA7swc0t6MVYOBWATIN4t0CtcKwNY0Ar13i3c6MAYGQFIFAGsCDW7G1IGyYuPdEG6xNinIw3AmR9xLv0MuFd2BVzrpvFufcB5bB7jnIe3A8iqC0EgUAGJLhwFcHgOBIAYQwiAA===\"}\n// [!code highlight:5]\nimport {\n  transformerNotationDiff,\n  // ...\n} from '@shikijs/transformers'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff(), // [!code highlight]\n    // ...\n  ],\n})\n```\n\n## Unstyled\n\nTransformers only applies classes and does not come with styles; you can provide your own CSS rules to style them properly.\n\n## Matching Algorithm\n\nWe found that the algorithm for matching comments in v1 is sometime conterintuitive, where we are trying to fix it in a progressive way. Since v1.29.0, we introduced a new `matchAlgorithm` option to most of the transformer for you to toggle between different matching algorithms. Right now, the default is `v1` which is the old algorithm, and `v3` is the new algorithm. When Shiki v3 is landed, the default will be `v3`.\n\n```ts\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff({\n      matchAlgorithm: 'v3', // [!code hl]\n    }),\n  ],\n})\n```\n\n### `matchAlgorithm: 'v1'`\n\nThe matching algorithm mostly affects the single-line comment matching, in `v1`, it will count the comment line as the first line, while in `v3`, it will count start from the comment line:\n\n```ts\n// [\\!code highlight:3]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n### `matchAlgorithm: 'v3'`\n\nIn `v3`, the matching algorithm will start counting from the line below the comment:\n\n```ts\n// [\\!code highlight:2]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n## Transformers\n\n### `transformerNotationDiff`\n\nUse `[!code ++]` and `[!code --]` to mark added and removed lines.\n\n````md\n```ts\nconsole.log('hewwo') // [\\!code --]\nconsole.log('hello') // [\\!code ++]\nconsole.log('goodbye')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('hewwo') // [!code --]\nconsole.log('hello') // [!code ++]\nconsole.log('goodbye')\n```\n\n- `// [!code ++]` outputs: `<span class=\"line diff add\">`\n- `// [!code --]` outputs: `<span class=\"line diff remove\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-diff\">`\n\n::: details HTML Output\n\n```html\n<!-- Output (stripped of `style` attributes for clarity) -->\n<pre class=\"shiki has-diff\"> <!-- Notice `has-diff` -->\n  <code>\n    <span class=\"line\"></span>\n    <span class=\"line\"><span>function</span><span>()</span><span></span><span>{</span></span>\n    <span class=\"line diff remove\">  <!-- Notice `diff` and `remove` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hewwo</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line diff add\">  <!-- Notice `diff` and `add` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hello</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line\"><span></span><span>}</span></span>\n    <span class=\"line\"><span></span></span>\n  </code>\n</pre>\n```\n\n:::\n\n---\n\n### `transformerNotationHighlight`\n\nUse `[!code highlight]` to highlight a line.\n\n````md\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [\\!code highlight]\nconsole.log('Not highlighted')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [!code highlight]\nconsole.log('Not highlighted')\n```\n\n- `// [!code highlight]` outputs: `<span class=\"line highlighted\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nYou can also highlight multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [\\!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n````\n\nRenders:\n\n```ts\n// [!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n---\n\n### `transformerNotationWordHighlight`\n\nUse `[!code word:Hello]` to highlight the word `Hello` in any subsequent code.\n\n````md\n```ts\n// [\\!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\n// [!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\nYou can also specify the number of lines to highlight words on, e.g. `[!code word:Hello:1]` will only highlight occurrences of `Hello` on the next line.\n\n````md\n```ts\n// [\\!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders:\n\n```ts\n// [!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\n---\n\n### `transformerNotationFocus`\n\nUse `[!code focus]` to focus a line.\n\n````md\n```ts\nconsole.log('Not focused');\nconsole.log('Focused') // [\\!code focus]\nconsole.log('Not focused');\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not focused')\nconsole.log('Focused') // [!code focus]\nconsole.log('Not focused')\n```\n\n- Outputs: `<span class=\"line focused\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-focused\">`\n\nYou can also focus multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n````\n\nRenders:\n\n```ts\n// [!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n\n---\n\n### `transformerNotationErrorLevel`\n\nUse `[!code error]`, `[!code warning]`, and `[!code info]` to mark a line with an error, warning, or info levels.\n\n````md\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [\\!code error]\nconsole.warn('Warning') // [\\!code warning]\nconsole.log('Info') // [\\!code info]\n```\n````\n\n- Outputs: `<span class=\"line highlighted error\">` for errors\n- Outputs: `<span class=\"line highlighted warning\">` for warnings\n- Outputs: `<span class=\"line highlighted info\">` for info\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nWith some additional CSS rules, you can make it look like this:\n\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [!code error]\nconsole.warn('Warning') // [!code warning]\nconsole.log('Info') // [!code info]\n```\n\n---\n\n### `transformerRenderWhitespace`\n\nRender whitespaces (tabs and spaces) as individual spans, with classes `tab` and `space`.\n\nOptions:\n\n- `position`: `'all' | 'boundary' | 'trailing' | 'leading'`. Default `'all'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#AB5959;--shiki-dark:#CB7676;\">function</span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">block</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">{</span></span>\n<span class=\"line\"><span class=\"space\"> </span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">space</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span></span>\n<span class=\"line\"><span class=\"tab\">&#9;</span><span class=\"tab\">&#9;</span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">tab</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span style=\"--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;\"> </span></span>\n<span class=\"line\"><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .tab,\npre.shiki .space {\n  position: relative;\n}\n\npre.shiki .tab::before {\n  content: '⇥';\n  position: absolute;\n  opacity: 0.3;\n}\n\npre.shiki .space::before {\n  content: '·';\n  position: absolute;\n  opacity: 0.3;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderIndentGuides`\n\nRender indentations as individual spans, with class `indent`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CB7676\">function</span><span style=\"color:#80A665\"> func</span><span style=\"color:#666666\">()</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">1</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\" style=\"--indent-offset: 0ch;\"></span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#4D9375\">for</span><span style=\"color:#666666\"> (</span><span style=\"color:#CB7676\">const </span><span style=\"color:#BD976A\">i</span><span style=\"color:#CB7676\"> of</span><span style=\"color:#666666\"> [])</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">2</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#666666\">}</span></span>\n<span class=\"line\"><span style=\"color:#666666\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .indent {\n  display: inline-block;\n  position: relative;\n  left: var(--indent-offset);\n}\n\npre.shiki .indent:empty {\n  height: 1lh;\n  vertical-align: bottom;\n}\n\npre.shiki .indent::before {\n  content: '';\n  position: absolute;\n  opacity: 0.15;\n  width: 1px;\n  height: 100%;\n  background-color: currentColor;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderLineNumber`\n\nRender line numbers as individual spans, with class `line-number`.\n\n```ts\nimport { transformerRenderLineNumber } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  transformers: [\n    transformerRenderLineNumber(),\n  ],\n})\n```\n\nOptions:\n\n- `start`: Start number. Default `1`.\n- `classLineNumber`: Class for line number. Default `'line-number'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n```css\npre.shiki .line-number {\n  user-select: none;\n  opacity: 0.5;\n  margin-right: 1em;\n}\n```\n\n---\n\n### `transformerMetaHighlight`\n\nHighlight lines based on the [meta string](/guide/transformers#meta) provided on the code snippet.\n\n````md\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n````\n\nRenders (with custom CSS rules):\n\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n\n- Outputs: `<span class=\"line highlighted\">` for included lines.\n\n### `transformerMetaWordHighlight`\n\nHighlight words based on the meta string provided on the code snippet.\n\n````md\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg)\nconsole.log(msg) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\n---\n\n### `transformerCompactLineOptions`\n\nSupport for `shiki`'s `lineOptions` that is removed in `shiki`.\n\n---\n\n### `transformerRemoveLineBreak`\n\nRemove line breaks between `<span class=\"line\">`. Useful when you set `display: block` to `.line` in CSS.\n\n---\n\n### `transformerRemoveNotationEscape`\n\nTransform `// [\\!code ...]` to `// [!code ...]`.\nAvoid rendering the escaped notation syntax as it is.\n\n---\n\n### `transformerStyleToClass`\n\nConvert Shiki's inline styles to unique classes.\n\nClass names are generated based on the hash value of the style object with the prefix/suffix you provide. You can put this transformer in multiple highlights passes and then get the CSS at the end to reuse the exact same styles. As Shiki doesn't handle CSS, it's on your integration to decide how to extract and apply/bundle the CSS.\n\nFor example:\n\n```ts\nimport { transformerStyleToClass } from '@shikijs/transformers'\nimport { codeToHtml } from 'shiki'\n\nconst toClass = transformerStyleToClass({ // [!code highlight:3]\n  classPrefix: '__shiki_',\n})\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  themes: {\n    dark: 'vitesse-dark',\n    light: 'vitesse-light',\n  },\n  defaultColor: false,\n  transformers: [toClass], // [!code highlight]\n})\n\n// The transformer instance exposes some methods to get the CSS\nconst css = toClass.getCSS() // [!code highlight]\n\n// use `html` and `css` in your app\n```\n\nHTML output:\n\n```html\n<pre class=\"shiki shiki-themes vitesse-dark vitesse-light __shiki_9knfln\" tabindex=\"0\"><code><span class=\"line\">\n  <span class=\"__shiki_14cn0u\">console</span>\n  <span class=\"__shiki_ps5uht\">.</span>\n  <span class=\"__shiki_1zrdwt\">log</span>\n  <span class=\"__shiki_ps5uht\">(</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_1g4r39\">hello</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_ps5uht\">)</span>\n</span></code></pre>\n```\n\nCSS output:\n\n```css\n.__shiki_14cn0u {\n  --shiki-dark: #bd976a;\n  --shiki-light: #b07d48;\n}\n.__shiki_ps5uht {\n  --shiki-dark: #666666;\n  --shiki-light: #999999;\n}\n.__shiki_1zrdwt {\n  --shiki-dark: #80a665;\n  --shiki-light: #59873a;\n}\n.__shiki_236mh3 {\n  --shiki-dark: #c98a7d77;\n  --shiki-light: #b5695977;\n}\n.__shiki_1g4r39 {\n  --shiki-dark: #c98a7d;\n  --shiki-light: #b56959;\n}\n.__shiki_9knfln {\n  --shiki-dark: #dbd7caee;\n  --shiki-light: #393a34;\n  --shiki-dark-bg: #121212;\n  --shiki-light-bg: #ffffff;\n}\n```\n\n### `transformerRemoveComments`\n\nRemove comments from the code. It works by checking the internal grammar token metadata to determine if the token is a comment.\n\nThis transformer requires `includeExplanation: true` to work.\n\n```ts\nimport { transformerRemoveComments } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  includeExplanation: true, // [!code highlight]\n  transformers: [\n    transformerRemoveComments(), // [!code highlight]\n  ],\n})\n```\n\nOptions:\n\n- `removeEmptyLines`: Remove lines that become empty after removing comments. Default `true`.\n\nFor example:\n\n````md\n```js\n// This is a comment\nconst x = 1 // Inline comment\n/* Block comment */\nconst y = 2\n\n// Another comment\n```\n````\n\nWill renders:\n\n```js\nconst x = 1\nconst y = 2\n```\n","docs/packages/twoslash.md":"---\noutline: deep\n---\n\n# @shikijs/twoslash\n\n<Badges name=\"@shikijs/twoslash\" />\n\nA Shiki transformer for [Twoslash](https://github.com/twoslashes/twoslash), provide inline type hover inside code blocks.\n\n[TwoSlash Notation Reference](https://twoslash.netlify.app/refs/notations).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm install -D @shikijs/twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/twoslash\n```\n\n:::\n\nThis package is **a transformer addon** to Shiki. This means that for every integration that supports passing Shiki transformers, you can use this package.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"b436269721bc02aa6e2b87b8db32bd8f1713dc97017fd91b867735e43ccd0ba0\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQARk2qVhgwabRcrYBOKlXSaZgN6lSB+yy9PI4wXC2qEXw1ippyRAAmAC+FHQ2DeBGIZDyNHoTDYnB4TRMyRE0BgaggAAk0MpWBZGKjYBYVqRJtMKLxDPM4BYAMJojGYrhoTzUgA8ACFhFA9lAADJyaaCZhXClc1y8tT4GCqAB8fAAvLLeAAFUgQZTsOAwNkksmy2LxRLrJGwRk41jLC4bADsAAZdvtDsdNg7qGsrjdCeisRbnpM3gAWD5fWRiKEA4GgnB4QgkcjnOhe5G8fAW4kyMlWtYbV3BkB7A5HJD5i6e2N+3YBpA2kPfcN/ABsUeoYNjkIT1CTcI4XD43vNuIJaIzpIOFKp3hpvHpZqxzNZU853N5AoOwtFvHFPJgUClMpg8osao1Wp1eoOBriCSSpp92Nx2fWSG2tYLTuLWzdZeueAHvsfKtXhrOsw1+F8ThbTAYxKOMoUTWESkYLB1RwdYMD4XQDgsaJqDgXCn1zQMznfItjlLD1fxKLDpn9YDEAADlAn4IyBEFWxgiF42hbskJQwwyEwPhZxgRcTD8Mk9n3VRlwlXdpMPBYjgPCwFIAJRgaYtRkNpvAAQTAaoAB8ukzA4+XYX42AAVTiSRZJ3PdpVUCkL2mWVCJfRsAGZHTIpAAFZzkom5lNUOi3hIz563AyN2Og8E4M7GEbmQ1DBIwyw7kiMgxMWHSbBy0gzH8QIQjCQr0mQABdXgTO5GB+ADKA8gKIo8AqtIojgIZSGkaUujK3osHYHAXhgJYqBWHMXwYpjSOdF9/mCy4qNufoioQIC3ldZiGyQNjo0SjseMQkAWF7RECq6h5HByAwvBMcwso29JMju/AXDcPKeFKnpOvuGJr2NZJrsB96xlawpijKH4qhqUR5gaJoWjaGAOkGno+kqwZbBGR4cgmKZNLmKdJpAabnwBO15sLRbThW8sSjBoqIaebaXx2EBorAiNA0BaqPjRPAjVvYBYl4bGboyUY9AoWJAQEdVlF4AByAABHIegAKzgAB6NBZZyVXDRvE1xakO9B1YeWwEV/hlbVrWQhNsBYlReRkjTXFeAVDoNGYSyrYA1hGAAAw9uAID2BZWAgaZGG4MOKQtyWaIsVW0DgVXbclsKYAzohLPgbUAFooDWIIc4lqXAenZAa7z7K3qN/RuApPW9d4NlS9L1MyBgRveE73gFjHmvBYV7g8lUVYkFAJN9jgbw8CzkBAUBIA=\"}\nimport {\n  transformerTwoslash,\n} from '@shikijs/twoslash'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst html = await codeToHtml(`console.log()`, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [\n    transformerTwoslash(), // <-- here\n    // ...\n  ],\n})\n```\n\nThe default output is unstyled. You need to add some extra CSS to make them look good.\n\nIf you want to run Twoslash on browsers or workers, reference to the [CDN Usage](#cdn-usage) section.\n\n## Renderers\n\nThanks to the flexibility of [`hast`](https://github.com/syntax-tree/hast), this transformer allows customizing how each piece of information is rendered in the output HTML with ASTs.\n\nWe provide two renderers built-in, and you can also create your own:\n\n---\n\n### `rendererRich`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-rich.ts)\n\n::: tip\nThis is the default renderer since v0.10.0.\n:::\n\nThis renderer provides a more explicit class name is prefixed with `twoslash-` for better scoping.\nIn addition, it runs syntax highlighting on the hover information.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"9bafe2d835b3a768cc39f5a28647084c02c621d41bbebd6324dead19238c244e\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAErsR+RhCzjJcAPyJei2fLLLVAeU0SwPfQBUA7hDisu+Q3LJkAOmHYBbLAhSNGkjTyUVfEoQKAgRBEQQAEEpNhpSMGZxElCPBV40fCzeLFJidnk4XgAjGDR0kpl+dloYKF4RFzgqzL94Ch97dkLeOAwwNGZaXnx2AHN8DgWQ/iCC/BhedjBVgro0ADpouEngpABOKlZZOcKkAEYAJipTubq8GTyTSOiOMFxEAAGKiqZikZhiMgXAC+FHQ2ABBGIUJe+yYbE4PAEwjEVgK4Osq1IfVIDicXTUGi01j0vFsBLgRJJZOcrgAkh5aBZqTZeABlWYAa3Y9OYhKCJJ8/kCwXxYsZErILIp0Vi8TwADEIWgghhsaJqQUIB0ZFlNsx+UL2HLxcSyAI1mhHKy4PgthMYHNwTyjlQTmCGIhHgBmK43O6Ie6Xahgt6B6gMplK50qq7bAHAkCg8GQ8hB4Ow+E4PCEEjkVH0dEcLh8NCJxWklOudSWbS00W25lN10c2Bc1vWbj6AXsYUdhV20hSgJBEJ1+VJxvk1yquIJEBasS6/W4yRGk0wM28C0j4U2ickh2kArdt3bGherJWOC+kD+s6IADs9zDYFuUUjaNXneRJ507ZNl1dX50yQZ4syKHN0iQQFC2oBES2RctqDRRJGFKDQyEwPhx0XZVXG5Z8Dk+YxSHbW93Bo3gAB9eGEWBmn+KBV3VRIAGFBBOCA/FyGiqh1XhYBECpNkIexeEPVR3V2V0IEEVh2lqETPC4v1TkDc4AFZf3/JAAA4XljECQGo8JoP+JBQ3gsFtShINUMwYtElLFFsMrXCMRrLSFFMSkB10fQGPCEKKO0Ic6XosIFGnGUQhs4KfioNV1xSY9WHSTJsk2NL7UKYp8KIaTSCqWp6ntUoYGaVp2k6LgemYPo4AGMAhhGMYJimGZ5kWIaVkdDYlONGh6Ffd9A3uQEjJAa4/wjJ4LNIOMPkS75VDsgFHOzFy8yeaEAF0QWgRFpVnXhgCCnb8Aoc9SNvXhoQEMphIAcgAAVdUd2AAKzgAB6J1IPwL6fB8MCLwgl01GAHxeHu0h9GKiJVEYPgQZB3gAB4AFpCZ8aFuGiPpJiQUB9lkOArDwNAEGhaEgA\"}\nimport { rendererRich, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererRich() // <--\n})\n```\n\nHere are a few examples with the built-in [`style-rich.css`](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-rich.css):\n\n<!-- eslint-skip -->\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"43c9a2581bdd8d8c26b6a00be668c361b400ca9c2034e576e137e282e9ec30ed\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808BLMG0gMwEMBjGAAgBVoESiDhoOpBogCMABioAbGGADmafEgAsVcaRUwpIQVGGLmuRPJBd8E7qyRyAvhXTYLBYmRE16eABRYpBA4khgAlAJCAHRojGhKiLxipMwqImISUtIAnIrKahqIAKw6EvqGcQm4ZmAW0lQ2dlwOiABMLm44eIQk5Dp0hlwQYGK8aEJJAEowHCZgChgAPMYQAHwZulKabfmq6lplegZ4EyYiCuaH1rak9t6IAGyd1O49Xv3Ug6fuvDNzI0WKzWvAAvLxgLxSLN5oteMgAAq8Zi8ADWMAwEDYAgAukl+IicQBuXhOEQmLgIRAgACyHHRvA4CgUvCCITIcXgyLAAihMMBGE2WS0AA49oUkGLqOUTtT/rDBbULNobs1WtIOq5Xt1qb1vAM/NTmKxODwoucqJlJEhigB2cUHRAq3QVPCrC5XJ2NW73cjtaQvTA6zx9HzfamBYKhTCRKqJZJoVKqIXWp55EBKfZFUrS46VeJKD11G3etUPTVdDwARwArmRFV9DSBI+ywrGCzAkik0impI905mJSUjq7qXGahnPTmmncWuXA29dR8w03/ABbAyEKCRADKibSsQgAFUsKEAMIcOAwfzhLv75NUClUkBnkZ9NBwRnM8b4PhMrC2AARgYjBcLwM6+p+KIcAmSYqOMEC8DWp5kFwl4wNEvaOLIViDo60gNLmo7UMeKGkBeV5FhY04+nOfoAMz0QuwZ6p8vhDCMYxnBA0z8gsyyrBslpbI40hSnhRTOjKlRCFRkqlrOrSyMxHhkMEnxWtkbT0Q62aNNAFhtMUmhWGwjCZhwG5MGAsC0LECBUIwUB4GpAC0Rkma50iaLarnFCuhgXmAkBoIycBwIwKg8hMvAAOTjrFvDAWhNZXsioWMJ+MHQnMrkCqyUYchgmH5CQCguaQ6lyYgUoQXRNoqe8oYGoYLbRhE4wdkkHBgA2mmONpuklkRsrUB21W1bRrTFI1S7NY2hhEBIvAAHI1muwGkEka0bWQr6jImNYtBAnxPngACCPIQIBABWMAtD+HChdCQTwMoH6MrwYDrZtvBYoyvVoswUDRLw53fgAUhwS07lwqRYKF327aQWXQrwjyaK5gHxLwbAKBAT1pK5WAQMaX0/WQcAlaIIkyCZQ1PCOo07Zt1VyApvpIMpWpBh4rEBQEG7qNAkQs3tnGHcdpDRFgEhXgAkiw/jdqod5wRQUJzIwtAAPxJEjm23uTyPkhAlJ4Pt76fudsFpAhAPcjQ+jSz4HAqFSyDICAst3GumxwWDtuqPbwxgO+juITBBtkJhOIUF7PuWSIdxQNrgdLQodZJQYADuMDKLwbQA1AvD0Y8j2hXAOBcIwZlcuofCAehf3Yg3xu/SiAAGKsqJ30QADpgPLrf4JljJ6Ot73Ip+IXJMhWCXDAUAaz3n45/E+Cfa9Zm0C3cWyLQiUSHwocRbA0Il7+tBzPdjBrkyA9gODLIQA3pBB+748n5xTlkEvvCwBrvfBQsc4402FHTe0GYCiOilC6UaPsFYsDZlYOqrRbSzWsBANcC8QIjCwnTcSMCiioOwbguInEkCoHAJZDwiCYAADF8ZPREKiYGeAhZblYcDGk0Ba6MEpngQBChj4ZBOmgfg4YQAERAC8MAtC8D0MVgwKgbCbIcM3NAbhNleGpzrijIR90RHQjEZISRTYZFyIUdSNkExebaOcjYwqYQHG6P4YI6kwjRGWnEeYwwliwHDBwUoChowETQh3oolBHN6o1ScIEgy1kTTcD4KsCEg9eCdWqGrNIg8nCD0HqfUK3FeIAn4isIQIJwTAAyVk+MsUAAiMAQl8GYPYRgJAkJXhRrFQ8J5zzoRvBQPJBSWAxHHGCOKAAJZp+NYqjLFtLJRStYoanorFDWchwijMybsvZ+zeAAHpDm1IOWc45IghYcCQKAQYygIr4LHAgJwTggA=\"}\n// @errors: 2540\ninterface Todo {\n  title: string\n}\n\nconst todo: Readonly<Todo> = {\n  title: 'Delete inactive users'.toUpperCase(),\n//  ^?\n}\n\ntodo.title = 'Hello'\n\nNumber.parseInt('123', 10)\n//      ^|\n\n               //\n               //\n```\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c6f2791b81c2170bb12e4d54f17b345c35c290fb6b3e803987a0875ad1778705\",\"data\":\"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\"}\nimport { createHighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nconst highlighter = await createHighlighterCore({\n  engine: createJavaScriptRegexEngine()\n})\n\n// @log: Custom log message\nconst a = 1\n// @error: Custom error message\nconst b = 1\n// @warn: Custom warning message\nconst c = 1\n// @annotate: Custom annotation message\n```\n\n---\n\n### `rendererClassic`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-classic.ts)\n\nThis renderer aligns with the output of legacy [`shiki-twoslash`](https://github.com/shikijs/twoslash).\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"be50298f5ea6976d501abea603d4b03abe8280f3bf0a7b10df97e47172449e7c\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAMKsucdiMbdEvACoB3CHBVx8AJVnyyAHTDsAtlgik00i2TLLV6yiCgQRCIggOvgwvLD8zIKsLjJy7qS8bOwA5rZgKbx67Gj4vLlhTqnsYGy8AAYAAibsANbsAFZwAPRoBkZc+OW8EIJoWH0AdD5waMzOSACcVKyyKblIAIwArFRjpCkwDEFxlkrGaiI+HGC4iAAMVCL448xiZFMAvhTo2GcExA9rdNsgLBxcPhCUTiST5UjMMBwfhOOxkfSGYz4RgQLCgqEAfm0OghUJhpDhpARHRMAEl4rQAPJoiRQrS8ADK+Dq7BxkOhsOstgcThcaFxHIJ8PaSJ8fgCeAAYnc0E4MAJhGJafkILwRDJmDQkozmfVwez8YSBE58iLOrwSjQUhD0XBhlRRuNtgAmABsMzmC0Qi2m1HGm1+/INnKJZpMxxKZ0uIGut3u5EQbuerxweEIJHI33oTGSgP1eJDxKRKJpkjgWN0AsNwsRnXJsCppbp2iZLLZBaFpBs9kcznzgsJRc6Yv8gRA0rEcoVIOVsrVGq1zB1LP71cS+NNtZMFrAVpttLtI3W2wA7AAWD0ZL0+tb+rZ4IMdwdh/AR05IZ1XG4Q+NIc7J6g3jTT5M2oH4mCwUhUTITA+HbAcaxJfBqVtQZdgSCshxMcx4gUXgAB9eGECJIygEcJSCRRBFGCA7FcXCyDgFVwhgER2FgXhCD0XgYDuPIShhXgTF6VgoF4AAjMJ0JkMiHWPKYAA5L3mV9ECUv0NnvHY3AUN8zgAZi/OMaATZ0AMwVMgnTL4wOzIJ/k4Hh6L2Tw4EOTRsRfHC9m7Hk+2kjwDm8KhxTHEIwgiKIYmchIkg4NISkybJcnyUIelIYpSlYCpql1RoWjaLcuh6PoBjQe0QEdCZvXOdTZivVSVlvTTfgC/YvCOGZIyQQyY2/GUHm9MyAF0rmgd4e15XhgBihRXMOChV0LF9eEeAQoLogByXKWSaVoX02mwbEfBDQyKxhgBsXhZrIbQ2vm9RNF4Zpml4AAeABaD6bEebgfDhMYkFAH5ZDUSQHwQR5HiAA=\"}\nimport { rendererClassic, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererClassic() // <--\n})\n```\n\nYou might need to reference `shiki-twoslash`'s CSS to make it look good. [Here](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-classic.css) we also copied the CSS from `shiki-twoslash` but it might need some cleanup.\n\n### `rendererFloatingVue`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/vitepress-twoslash/src/renderer-floating-vue.ts)\n\nThis renderer outputs Vue template syntax that using [Floating Vue](https://floating-vue.starpad.dev/) as the popup component (to render it outside the containers). This renderer is **NOT** directly usable but an internal renderer for the [VitePress integration](/packages/vitepress#twoslash). Listing it here for reference if you want to create your own renderer.\n\n## Options\n\n### Explicit Trigger\n\nWhen integrating with `@shikijs/markdown-it` or `rehype-shiki`, we may not want Twoslash to run on every code block. In this case, we can set `explicitTrigger` to `true` to only run on code blocks with `twoslash` presented in the codeframe.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c33fc7b243f56e1595f93ca6e9e052fed95abb58a9edc5376b448c62984626f1\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQATipWGDBptFzEAEZt6jXpmA3qVIH7LL08jjBcRAAGKhF8NYqaci2AL4UdDYV4EYhkPI0ehMNicHh9GyRe6OHIGLwmcyWW7IjKjZyuOieeY8fyBEJhJHpWLxRLrRFpKKZVG5KgFIp4cqVUjVISieYNJotNowDpdcm9GT9XFDUgjB45CZTGCzNreOBLKgrNYbACsAHYdnsDkdTlRVqRLtcpVSmfick9Jq8AEyfb6yMSQ95AkE4PCEEjkc10a6MLCkQxkTB8SmMlFjYnqhZ0LAcETsNBWdjTS6kLEAIwgEF2cl4AB9eAAlFUAUVoWHLvGEsH4TqgeXZxRA1YAjoJ2C04LwAAZoe34YeC/Oi8PwPY0KBK6T4UUiaCi/OsQpBXiqVaC5hYVPVQ7sIc2uNB87TYrIZD5GD8ZiCVgMKhP1hwXAAXW/WotGwABzHEa+yHEgxy6uaFxXHgKZphmWY5pCOxOkgADMbo/J6/zOgCf4gGusB4LSSS8MADJ3HiCrjACAgRsovAAOQAAI5D0ABWcAAPRjjRTGxLEF5UcyYyMMAsS8Lw8HsOmmakNmuYWDIgiitx3G8AAPAAtNpsQAtweR7swSCgCGexwN4eBoAgAIAkAA=\"}\nimport { transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  explicitTrigger: true // <--\n})\n```\n\n````md\nIn markdown, you can use the following syntax to trigger Twoslash:\n\n```ts\n// this is a normal code block\n```\n\n```ts twoslash\n// this will run Twoslash\n```\n````\n\n## Integrations\n\nWhile you can set up Twoslash with Shiki on your own with the instructions above, you can also find high-level integrations with frameworks and tools here:\n\n- [VitePress](/packages/vitepress#twoslash) - A plugin to enable Twoslash support in VitePress.\n- [Nuxt](/packages/nuxt#twoslash-integration) - A module to enable Twoslash for Nuxt Content.\n- [Vocs](https://vocs.dev/docs/guides/twoslash) - Vocs has TwoSlash support built-in.\n- [Slidev](https://sli.dev/features/twoslash#twoslash-integration) - Slidev has TwoSlash support built-in.\n\n## Recipes\n\n### CDN Usage\n\nBy default [`twoslash`](https://github.com/twoslashes/twoslash/tree/main/packages/twoslash) runs on Node.js and relies on your local system to resolve TypeScript and types for the imports. Import it directly in non-Node.js environments would not work.\n\nLuckily, Twoslash implemented a virtual file system, which allow you to provide your own files for TypeScript to resolve in memory. However, loading these files in the browser is still a challenge. Thanks to the work on the [TypeScript WebSite](https://github.com/microsoft/TypeScript-Website), the TypeScript team has provided some utilities to fetch types on demand through CDN, they call it [Automatic Type Acquisition (ATA)](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ata).\n\nWe make tiny wrappers around the building blocks and provide an easy-to-use API in [`twoslash-cdn`](https://twoslash.netlify.app/packages/cdn). For example:\n\n```js\n// FIXME: Replace with explicit versions in production\nimport { createTransformerFactory, rendererRich } from 'https://esm.sh/@shikijs/twoslash@latest/core'\nimport { codeToHtml } from 'https://esm.sh/shiki@latest'\nimport { createTwoslashFromCDN } from 'https://esm.sh/twoslash-cdn@latest'\nimport { createStorage } from 'https://esm.sh/unstorage@latest'\nimport indexedDbDriver from 'https://esm.sh/unstorage@latest/drivers/indexedb'\n\n// ============= Initialization =============\n\n// An example using unstorage with IndexedDB to cache the virtual file system\nconst storage = createStorage({\n  driver: indexedDbDriver({ base: 'twoslash-cdn' }),\n})\n\nconst twoslash = createTwoslashFromCDN({\n  storage,\n  compilerOptions: {\n    lib: ['esnext', 'dom'],\n  },\n})\n\nconst transformerTwoslash = createTransformerFactory(twoslash.runSync)({\n  renderer: rendererRich(),\n})\n\n// ============= Execution =============\n\nconst app = document.getElementById('app')\n\nconst source = `\nimport { ref } from 'vue'\n\nconsole.log(\"Hi! Shiki + Twoslash on CDN :)\")\n\nconst count = ref(0)\n//     ^?\n`.trim()\n\n// Before rendering, we need to prepare the types, so that the rendering can happen synchronously\nawait twoslash.prepareTypes(source)\n\n// Then we can render the code\napp.innerHTML = await codeToHtml(source, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [transformerTwoslash],\n})\n```\n","docs/packages/vitepress.md":"---\noutline: deep\n---\n\n# VitePress Integration\n\n[VitePress](https://vitepress.dev/) uses Shiki under the hood, so you don't need explicit integration.\n\nVitePress provides [a few options for customizing Shiki](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts#L66-L112). Learn more about them in the [VitePress documentation](https://vitepress.dev/reference/site-config#markdown).\n\n## Twoslash\n\nTo enable [TypeScript Twoslash](/packages/twoslash) (type hover on code snippets) in VitePress, we provide a VitePress plugin for easy setup. Pre-styled, with [Floating Vue](https://floating-vue.starpad.dev/) to display the type information out side of the code container.\n\n<Badges name=\"@shikijs/vitepress-twoslash\" />\n\n### Setup\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/vitepress-twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/vitepress-twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/vitepress-twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/vitepress-twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/vitepress-twoslash\n```\n\n:::\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash() // [!code hl]\n    ],\n    // [!code hl:2]\n    // Explicitly load these languages for types highlighting\n    languages: ['js', 'jsx', 'ts', 'tsx']\n  }\n})\n```\n\nAnd then in your [`.vitepress/theme/index.ts`](https://vitepress.dev/guide/custom-theme), install the Vue plugin and import the css with `@shikijs/vitepress-twoslash/styles.css`.\n\n```ts twoslash [.vitepress/theme/index.ts]\n// @twoslash-cache: {\"v\":1,\"hash\":\"2a5df659524ba4854bc92abbfbd15feefdb74ba936c5a020d6bdc7d308b959b2\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAJ2wNUgDNmAYxi8AomHzMwEgIJYsAYQiC6aADph2AWywRSaabPlKV6zfUog4aZiaQBGACxVWMMAHM0+VwB2KkdSHxgGRBAZOQUYZTUNGltPAVxEAAYqMTlScSFXNwBfCnRsdIJiMjtkyJAWDi4+MQ0HXgAVAHcIOFYufAAxVghmNAEfADUAVxhEXmBdXiX+MAc2VjmWFTmEil4ILDHWgH45oZGx32mYa2F2Hz4AXgA+XiIIdigAbl0i3QMjCYOt1ev1zqNxtc7FAIGIEFFrrwsKwpj4BLw0BAVmtWKxeODLpMZrxOux/LwHBgvHAAHS6XQASUMxlM/nYcF4wimCiOYBWvAABjSiGSYFhSPA4AB6fwwfQwKUCWC0GloOAC3jyKC8KZwSQC5gqGm6mCMLo9PpwQbDCFXGbcDUCOCfSSywXeWKWLAawgQADWNLsa2ciAArAAOTzePwBRAuACcISc4Tq5tBVoJkJmdg4YHSLmyuXy1UQgRKZRweEIJHIIS0TDYnB4vBaq1M7Xwctm80WywAMswMBApmg5gARGB3PPqZl5wQ/PnLD0WeLbXiMMRoWhzGIrhLWWpPV7vT4Lv56ZlAjtdoOhSLuAsgLy+fxIUNJsIRPDX+U5tJIAAmQsnGLchS3LahyirKpa2oesokYcUDjITA+C0bwoDgOYFkXJYByHEdx0nNIZyMOc0AXZZeGXOIEk2TdtzMT1V0SGw0CPN4Pm+X5bycSIANDICn2jV9Sw/FM8HQsBML/PMkGCEAchAzcSwAiDMErKJq2qOtbAQxsmhbVp207eVsN7PDB2HUdeAnKcbggWdvAoizqPMWi1w3Lcd3cr0Dy0DiT24sBzwBFkOlM3AqGDfiADZH2fGM33Er8oh/KKn3/MTFKLFSwJcFx1KgrSYJqeD6nlfxoDQ3yWMYYBNRUXgih85j9ySAK5iC3iQwAwIsmEl9YxcAbQgkqIaK9WT0kjHLlIKRA1NKSDNMqGsyr0+osBAyqyD4Q0sB2FQAB55AwZ4ev48MAGYoyGpBbuoZNUpAA7pqQWalLyPLXFDIrVu02DagbRpmwEIRRAkJi9ysDr6H+S9TF3DzWOB6K70A+MBsS0SXAUsaXuRvy4YYVI5MQT7coWgClorCpAY2upEJ2iI9saw7eASU6wHOy6Hpcd9BqSxBHoJuo3rJ9JEzm76FuKZaNPp0rdKZyrCCgPgubO55jT1Y7kAOXk4FOTUeYAXWeRCUTRMA5gABWtgR9cN9gTjmM6zb2A3Dld1YTY9549hpYOXdaOYADkIAZMBhDIZ2fbd02MAt7gjqwbnzvXABqFx9hrG0Nb5kWEzu4XReeuoTXexBpa+0CPv+pX1pVkGm2aYzgQtMEbUJa5zNw7FHFxTYDrTvZQ79s4e6zByY/uQKuLPBHAXbEFLWtC4Z+hWF4RARFkVRdFMUH9Z8Wnu1JFJclKWpOkwEZRGMXwdlOW5Tdff5IURRocVJRlSLFTSToKqdUpttQmkFAdXWpo0zr0zBfB02IXRP31JNFiPoID+kDOjPiD0AKPRxsNaWYtvxr27pvC+1da5UxLC4NSntFLQAqGFIEit5jQxRv5egzVOSkEcrwAA5N/MUEo4BwAEcvcKsDyG2iJJIYQfD9CCIAAJWnYH6dgAAraUwjf5iIALRoDIVaKUYgODOQEbwKUUpeDIAAIQtFgLwfArAzaSKvJFXh/ChGij0dKWU8oJH3wvCvFRaiNHaKlLo0RcBDHGPwFKG+MAaRwnEVYmx9jHGSBcW44JdBQmwFEFMVgpgcJLCkphOY6UKC9jQQkeq7NmqtRhqjAKPYB5QJNGaeJ8C5F8GsbYhxTDnGuN7CUHiVBKrMCQKAKSzoNB4DVCAIoRQgA=\"}\n// @noErrors: true\nimport type { EnhanceAppContext } from 'vitepress'\nimport TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' // [!code hl]\nimport Theme from 'vitepress/theme'\n\nimport '@shikijs/vitepress-twoslash/style.css' // [!code hl]\n\nexport default {\n  extends: Theme,\n  enhanceApp({ app }: EnhanceAppContext) {\n    app.use(TwoslashFloatingVue) // [!code hl]\n  },\n}\n```\n\n::: details About style.css\n\nFor easier setup, `@shikijs/vitepress-twoslash/styles.css` bundles the styles from `floating-vue` and `@shikijs/twoslash/style-rich.css` so you only need a single entry. If you are using a custom `floating-vue` style or want to have more control of the styles, you can expand them as:\n\n```ts\nimport '@shikijs/vitepress-twoslash/style.css'\n\n// Equivalent to:\nimport '@shikijs/twoslash/style-rich.css'\nimport 'floating-vue/dist/style.css'\nimport '@shikijs/vitepress-twoslash/style-core.css'\n```\n\n:::\n\nThat's it, you can now use `ts twoslash` in your markdown files to enable the beautiful type hover.\n\n````md\n```ts twoslash\nconsole.log('hello')\n//      ^?\n```\n````\n\nIt will be rendered as:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"258fd8e6b019224fc5515598774b6ccef0d85eefda3a3ba0992cbaa911ba9952\",\"data\":\"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\"}\nconsole.log('hello')\n//      ^?\n```\n\n<div class=\"h-100\" /> <!-- leaving some space for the query above -->\n\n### Vue Single File Component\n\nIn addition, this plugin also integrated [`twoslash-vue`](https://twoslash.netlify.app/packages/vue) for you, so that you can also highlight Vue SFC blocks with `vue twoslash`:\n\n```vue twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"e44d27459becb1dd99d3f24e24e643e1cd8fe190f90d461e4713e08207fe0a39\",\"data\":\"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\"}\n<script setup>\nimport { onMounted, ref } from 'vue'\n\n// reactive state\nconst count = ref(0)\n//             ^?\n\n// functions that mutate state and trigger updates\nfunction increment() {\n  count.value++\n}\n\n// lifecycle hooks\nonMounted(() => {\n  console.log(`The initial count is ${count.value}.`)\n})\n</script>\n\n<template>\n  <button @click=\"increment\">\n    Count is: {{ count }}\n  </button>\n</template>\n```\n\n### File System Cache\n\nTo speed up the build process, you can enable the file system cache for the generated types, that shares across multiple builds. By default the cache is stored in the `.vitepress/cache/twoslash` along with other VitePress caches.\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash'\nimport { createFileSystemTypesCache } from '@shikijs/vitepress-twoslash/cache-fs' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash({\n        typesCache: createFileSystemTypesCache() // [!code hl]\n      })\n    ]\n  }\n})\n```\n\n### Inline Cache (experimental)\n\nYou can enable inline caching for the generated types. The `@twoslash-cache: ...` will auto insert into your fenced code block during development and build time.\n\n````md [./your-file.md]{2}\n```ts twoslash\n// @twoslash-cache: [auto generated]\nconst a: string = 'foo'\n```\n````\n\nTo enable the inline cache in your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config), please use the config wrapper created by `createTwoslashWithInlineCache`.\n\n```ts [.vitepress/config.ts]\nimport { createTwoslashWithInlineCache } from '@shikijs/vitepress-twoslash/cache-inline' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nconst withTwoslashInlineCache = createTwoslashWithInlineCache({ // [!code hl]\n  // ... config of transformerTwoslash // [!code hl]\n}) // [!code hl]\n\nexport default withTwoslashInlineCache( // [!code hl]\n  defineConfig({\n    markdown: {\n      codeTransformers: [\n        // move config to the `createTwoslashWithInlineCache()` // [!code error]\n        // transformerTwoslash({ ... }) // [!code error]\n      ]\n    }\n  })\n) // [!code hl]\n```\n\n#### Force re-generate inline cache\n\nTo force re-generate the inline cache and ignore the existing cache, you can use the `TWOSLASH_INLINE_CACHE_IGNORE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress build\n```\n\n#### Remove inline cache\n\nTo remove all inline cache, you can use the `TWOSLASH_INLINE_CACHE_REMOVE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress build\n```\n","docs/references/engine-js-compat.md":"# JavaScript RegExp Engine Compatibility References\n\nCompatibility reference of all built-in grammars with the [JavaScript RegExp engine](/guide/regex-engines#javascript-regexp-engine).\n\n> Generated on Friday, September 11, 2026\n>\n> Version `4.4.3`\n>\n> Runtime: Node.js v24.16.0\n\n## Report Summary\n\n|                 |                       Count |\n| :-------------- | --------------------------: |\n| Total Languages |                         238 |\n| Supported       | [237](#supported-languages) |\n| Mismatched      |  [0](#mismatched-languages) |\n| Unsupported     | [1](#unsupported-languages) |\n\n## Supported Languages\n\nLanguages that work with the JavaScript RegExp engine, and will produce the same result as the WASM engine (with the [sample snippets in the registry](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples)).\nIn some edge cases, it's not guaranteed that the highlighting will be 100% the same. If that happens, please create an issue with the sample snippet.\n\n| Language           | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| ------------------ | :-------------- | ----------------: | --------------: | ---: |\n| abap               | ✅ OK           |                52 |               - |      |\n| actionscript-3     | ✅ OK           |                59 |               - |      |\n| ada                | ✅ OK           |               200 |               - |      |\n| ahk                | ✅ OK           |               125 |               - |      |\n| angular-html       | ✅ OK           |               669 |               - |      |\n| angular-ts         | ✅ OK           |               776 |               - |      |\n| apache             | ✅ OK           |                60 |               - |      |\n| apex               | ✅ OK           |               197 |               - |      |\n| apl                | ✅ OK           |               912 |               - |      |\n| applescript        | ✅ OK           |               152 |               - |      |\n| ara                | ✅ OK           |                54 |               - |      |\n| asciidoc           | ✅ OK           |               319 |               - |      |\n| asm                | ✅ OK           |               298 |               - |      |\n| astro              | ✅ OK           |               610 |               - |      |\n| awk                | ✅ OK           |                36 |               - |      |\n| ballerina          | ✅ OK           |               224 |               - |      |\n| bat                | ✅ OK           |                58 |               - |      |\n| beancount          | ✅ OK           |                42 |               - |      |\n| berry              | ✅ OK           |                21 |               - |      |\n| bibtex             | ✅ OK           |                19 |               - |      |\n| bicep              | ✅ OK           |                31 |               - |      |\n| bird2              | ✅ OK           |               146 |               - |      |\n| blade              | ✅ OK           |              1122 |               - |      |\n| bsl                | ✅ OK           |                97 |               - |      |\n| c                  | ✅ OK           |               176 |               - |      |\n| c3                 | ✅ OK           |               125 |               - |      |\n| cadence            | ✅ OK           |               128 |               - |      |\n| cairo              | ✅ OK           |               236 |               - |      |\n| chapel             | ✅ OK           |               214 |               - |      |\n| clarity            | ✅ OK           |                42 |               - |      |\n| clojure            | ✅ OK           |                38 |               - |      |\n| cmake              | ✅ OK           |                23 |               - |      |\n| cobol              | ✅ OK           |               858 |               - |      |\n| codeowners         | ✅ OK           |                 4 |               - |      |\n| codeql             | ✅ OK           |               147 |               - |      |\n| coffee             | ✅ OK           |               466 |               - |      |\n| common-lisp        | ✅ OK           |                60 |               - |      |\n| coq                | ✅ OK           |                28 |               - |      |\n| cpp                | ✅ OK           |               468 |               - |      |\n| crystal            | ✅ OK           |              1054 |               - |      |\n| csharp             | ✅ OK           |               315 |               - |      |\n| css                | ✅ OK           |               141 |               - |      |\n| csv                | ✅ OK           |                 1 |               - |      |\n| cue                | ✅ OK           |                85 |               - |      |\n| cypher             | ✅ OK           |                39 |               - |      |\n| d                  | ✅ OK           |               272 |               - |      |\n| dart               | ✅ OK           |                79 |               - |      |\n| dax                | ✅ OK           |                23 |               - |      |\n| desktop            | ✅ OK           |                16 |               - |      |\n| diff               | ✅ OK           |                16 |               - |      |\n| docker             | ✅ OK           |                 7 |               - |      |\n| dotenv             | ✅ OK           |                 9 |               - |      |\n| dream-maker        | ✅ OK           |                56 |               - |      |\n| edge               | ✅ OK           |               629 |               - |      |\n| elixir             | ✅ OK           |               704 |               - |      |\n| elm                | ✅ OK           |               241 |               - |      |\n| emacs-lisp         | ✅ OK           |               155 |               - |   22 |\n| erb                | ✅ OK           |              1816 |               - |      |\n| erlang             | ✅ OK           |               270 |               - |      |\n| fennel             | ✅ OK           |                31 |               - |      |\n| fish               | ✅ OK           |                34 |               - |      |\n| fluent             | ✅ OK           |                23 |               - |      |\n| fortran-fixed-form | ✅ OK           |               346 |               - |      |\n| fortran-free-form  | ✅ OK           |               339 |               - |      |\n| fsharp             | ✅ OK           |               242 |               - |      |\n| gdresource         | ✅ OK           |               157 |               - |      |\n| gdscript           | ✅ OK           |                94 |               - |      |\n| gdshader           | ✅ OK           |                39 |               - |      |\n| genie              | ✅ OK           |                20 |               - |      |\n| gherkin            | ✅ OK           |                19 |               - |      |\n| gleam              | ✅ OK           |                26 |               - |      |\n| glimmer-js         | ✅ OK           |               673 |               - |      |\n| glimmer-ts         | ✅ OK           |               673 |               - |      |\n| glsl               | ✅ OK           |               185 |               - |      |\n| gn                 | ✅ OK           |                19 |               - |      |\n| gnuplot            | ✅ OK           |                82 |               - |      |\n| go                 | ✅ OK           |               126 |               - |      |\n| graphql            | ✅ OK           |               445 |               - |      |\n| groovy             | ✅ OK           |               130 |               - |      |\n| hack               | ✅ OK           |               946 |               - |      |\n| haml               | ✅ OK           |               559 |               - |      |\n| handlebars         | ✅ OK           |               696 |               - |      |\n| haskell            | ✅ OK           |               157 |               - |      |\n| haxe               | ✅ OK           |               173 |               - |      |\n| hcl                | ✅ OK           |                67 |               - |      |\n| hjson              | ✅ OK           |                57 |               - |      |\n| hlsl               | ✅ OK           |                52 |               - |      |\n| html               | ✅ OK           |               608 |               - |      |\n| http               | ✅ OK           |               746 |               - |      |\n| hurl               | ✅ OK           |               611 |               - |      |\n| hxml               | ✅ OK           |               182 |               - |      |\n| hy                 | ✅ OK           |                12 |               - |      |\n| imba               | ✅ OK           |               239 |               - |      |\n| ini                | ✅ OK           |                11 |               - |      |\n| java               | ✅ OK           |               141 |               - |      |\n| javascript         | ✅ OK           |               375 |               - |      |\n| jinja              | ✅ OK           |               639 |               - |      |\n| jison              | ✅ OK           |               431 |               - |      |\n| json               | ✅ OK           |                19 |               - |      |\n| json5              | ✅ OK           |                23 |               - |      |\n| jsonc              | ✅ OK           |                19 |               - |      |\n| jsonl              | ✅ OK           |                19 |               - |      |\n| jsonnet            | ✅ OK           |                33 |               - |      |\n| jssm               | ✅ OK           |                30 |               - |      |\n| jsx                | ✅ OK           |               375 |               - |      |\n| julia              | ✅ OK           |              1177 |               - |      |\n| just               | ✅ OK           |              2148 |               - |      |\n| kdl                | ✅ OK           |                30 |               - |      |\n| kotlin             | ✅ OK           |                58 |               - |      |\n| kusto              | ✅ OK           |                60 |               - |      |\n| latex              | ✅ OK           |               312 |               - |      |\n| lean               | ✅ OK           |                31 |               - |      |\n| less               | ✅ OK           |               279 |               - |      |\n| liquid             | ✅ OK           |               689 |               - |      |\n| llvm               | ✅ OK           |                25 |               - |      |\n| log                | ✅ OK           |                31 |               - |      |\n| logo               | ✅ OK           |                 9 |               - |      |\n| lua                | ✅ OK           |               279 |               - |      |\n| luau               | ✅ OK           |                95 |               - |      |\n| make               | ✅ OK           |                51 |               - |      |\n| markdown           | ✅ OK           |               123 |               - |      |\n| marko              | ✅ OK           |               929 |               - |      |\n| matlab             | ✅ OK           |                88 |               - |      |\n| mdc                | ✅ OK           |               786 |               - |      |\n| mdx                | ✅ OK           |               197 |               - |      |\n| mermaid            | ✅ OK           |               175 |               - |      |\n| mipsasm            | ✅ OK           |                17 |               - |      |\n| mojo               | ✅ OK           |               215 |               - |      |\n| moonbit            | ✅ OK           |               101 |               - |      |\n| move               | ✅ OK           |               113 |               - |      |\n| narrat             | ✅ OK           |                34 |               - |      |\n| nextflow           | ✅ OK           |               107 |               - |      |\n| nginx              | ✅ OK           |               378 |               - |      |\n| nim                | ✅ OK           |              1122 |               - |      |\n| nix                | ✅ OK           |                83 |               - |      |\n| nsis               | ✅ OK           |                38 |               - |      |\n| nushell            | ✅ OK           |                85 |               - |      |\n| objective-c        | ✅ OK           |               222 |               - |      |\n| objective-cpp      | ✅ OK           |               306 |               - |      |\n| ocaml              | ✅ OK           |               178 |               - |      |\n| odin               | ✅ OK           |                98 |               - |      |\n| openscad           | ✅ OK           |                24 |               - |      |\n| org                | ✅ OK           |              4715 |               - |      |\n| pascal             | ✅ OK           |                23 |               - |      |\n| perl               | ✅ OK           |               937 |               - |      |\n| php                | ✅ OK           |              1125 |               - |      |\n| pkl                | ✅ OK           |                67 |               - |      |\n| plsql              | ✅ OK           |                45 |               - |      |\n| po                 | ✅ OK           |                23 |               - |      |\n| polar              | ✅ OK           |                31 |               - |      |\n| postcss            | ✅ OK           |                49 |               - |      |\n| powerquery         | ✅ OK           |                30 |               - |      |\n| powershell         | ✅ OK           |                88 |               - |      |\n| prisma             | ✅ OK           |                31 |               - |      |\n| prolog             | ✅ OK           |                26 |               - |      |\n| proto              | ✅ OK           |                33 |               - |      |\n| pug                | ✅ OK           |               683 |               - |      |\n| puppet             | ✅ OK           |                60 |               - |      |\n| purescript         | ✅ OK           |                87 |               - |      |\n| python             | ✅ OK           |               218 |               - |      |\n| qml                | ✅ OK           |               407 |               - |      |\n| qmldir             | ✅ OK           |                 7 |               - |      |\n| qss                | ✅ OK           |                31 |               - |      |\n| r                  | ✅ OK           |                66 |               - |      |\n| racket             | ✅ OK           |                69 |               - |      |\n| raku               | ✅ OK           |                52 |               - |      |\n| razor              | ✅ OK           |               960 |               - |      |\n| rbs                | ✅ OK           |                33 |               - |      |\n| reg                | ✅ OK           |                 9 |               - |      |\n| regexp             | ✅ OK           |                34 |               - |      |\n| rel                | ✅ OK           |                17 |               - |      |\n| riscv              | ✅ OK           |                36 |               - |      |\n| ron                | ✅ OK           |                35 |               - |      |\n| rosmsg             | ✅ OK           |                31 |               - |      |\n| rst                | ✅ OK           |              2057 |               - |      |\n| ruby               | ✅ OK           |              1808 |               - |      |\n| rust               | ✅ OK           |                89 |               - |      |\n| sas                | ✅ OK           |               100 |               - |      |\n| sass               | ✅ OK           |                69 |               - |      |\n| scala              | ✅ OK           |               116 |               - |      |\n| scheme             | ✅ OK           |                34 |               - |      |\n| scss               | ✅ OK           |               233 |               - |      |\n| sdbl               | ✅ OK           |                23 |               - |      |\n| shaderlab          | ✅ OK           |                87 |               - |      |\n| shellscript        | ✅ OK           |               147 |               - |      |\n| shellsession       | ✅ OK           |               149 |               - |      |\n| smalltalk          | ✅ OK           |                64 |               - |      |\n| smithy             | ✅ OK           |                42 |               - |      |\n| solidity           | ✅ OK           |               105 |               - |      |\n| soy                | ✅ OK           |               646 |               - |      |\n| sparql             | ✅ OK           |                19 |               - |      |\n| splunk             | ✅ OK           |                17 |               - |      |\n| sql                | ✅ OK           |                68 |               - |      |\n| ssh-config         | ✅ OK           |                12 |               - |      |\n| stata              | ✅ OK           |               254 |               - |      |\n| stylus             | ✅ OK           |               106 |               - |      |\n| surrealql          | ✅ OK           |               467 |               - |      |\n| svelte             | ✅ OK           |               646 |               - |      |\n| swift              | ✅ OK           |               340 |               - |      |\n| system-verilog     | ✅ OK           |               102 |               - |      |\n| systemd            | ✅ OK           |                32 |               - |      |\n| talonscript        | ✅ OK           |                46 |               - |      |\n| tasl               | ✅ OK           |                23 |               - |      |\n| tcl                | ✅ OK           |                34 |               - |      |\n| templ              | ✅ OK           |               674 |               - |      |\n| terraform          | ✅ OK           |                68 |               - |      |\n| tex                | ✅ OK           |               103 |               - |      |\n| toml               | ✅ OK           |                44 |               - |      |\n| ts-tags            | ✅ OK           |               997 |               - |      |\n| tsv                | ✅ OK           |                 1 |               - |      |\n| tsx                | ✅ OK           |               375 |               - |      |\n| turtle             | ✅ OK           |                15 |               - |      |\n| twig               | ✅ OK           |              2445 |               - |      |\n| typescript         | ✅ OK           |               362 |               - |      |\n| typespec           | ✅ OK           |                73 |               - |      |\n| typst              | ✅ OK           |              5699 |               - |      |\n| v                  | ✅ OK           |                77 |               - |      |\n| vala               | ✅ OK           |                20 |               - |      |\n| vb                 | ✅ OK           |                34 |               - |      |\n| verilog            | ✅ OK           |                34 |               - |      |\n| vhdl               | ✅ OK           |                82 |               - |      |\n| viml               | ✅ OK           |                72 |               - |      |\n| vue                | ✅ OK           |               705 |               - |      |\n| vue-html           | ✅ OK           |               404 |               - |      |\n| vue-vine           | ✅ OK           |              1032 |               - |      |\n| vyper              | ✅ OK           |               238 |               - |      |\n| wasm               | ✅ OK           |                78 |               - |      |\n| wenyan             | ✅ OK           |                18 |               - |      |\n| wgsl               | ✅ OK           |                44 |               - |      |\n| wikitext           | ✅ OK           |               105 |               - |      |\n| wit                | ✅ OK           |                81 |               - |      |\n| wolfram            | ✅ OK           |               501 |               - |      |\n| xml                | ✅ OK           |               168 |               - |      |\n| xsl                | ✅ OK           |               170 |               - |      |\n| yaml               | ✅ OK           |                48 |               - |      |\n| zenscript          | ✅ OK           |                21 |               - |      |\n| zig                | ✅ OK           |                51 |               - |      |\n\n###### Table Field Explanations\n\n- **Highlight Match**: Whether the highlighting results matched with the WASM engine for the [sample snippet](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples).\n- **Patterns Parsable**: Number of regex patterns that can be parsed by the JavaScript RegExp engine.\n- **Patterns Failed**: Number of regex patterns that can't be parsed by the JavaScript RegExp engine (throws error).\n- **Diff**: Length of characters that are different between the highlighting results of the two engines.\n\n## Mismatched Languages\n\nLanguages that do not throw with the JavaScript RegExp engine, but will produce different results than the WASM engine.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n\n## Unsupported Languages\n\nLanguages that throw with the JavaScript RegExp engine, either because they contain syntax we can't polyfill yet or because the grammar contains an invalid Oniguruma regex (that would also fail when using the WASM engine, but silently). You can try these languages with the `forgiving` option to skip errors.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n| ahk2     | ❌ Error        |               188 |               1 |   16 |\n","packages/cli/README.md":"# shiki-cli\n\nShiki in the command line.\n\n[Documentation](https://shiki.style/packages/cli)\n\n## License\n\nMIT\n","packages/codegen/README.md":"# @shikijs/codegen\n\nCodegen for fine-grained Shiki bundles.\n\n[Documentation](https://shiki.style/packages/codegen)\n\n## License\n\nMIT\n","packages/colorized-brackets/README.md":"# @shikijs/colorized-brackets\n\nVSCode-style colorized brackets transformer for [Shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/colorized-brackets)\n\n## License\n\nMIT\n","packages/core/README.md":"# @shikijs/core\n\nThe core functionality of [Shiki](https://github.com/shikijs/shiki), without any grammar of themes bundled.\n\nIt's the same as importing `shiki/core`.\n","packages/engine-javascript/README.md":"# @shikijs/engine-javascript\n\nEngine for Shiki using JavaScript's native RegExp. Uses [Oniguruma-To-ES](https://github.com/slevithan/oniguruma-to-es) to transpile regex syntax and behavior.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n","packages/engine-oniguruma/README.md":"# @shikijs/engine-oniguruma\n\nEngine for Shiki using Oniguruma RegExp engine in WebAssembly.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n","packages/langs-precompiled/README.md":"# @shikijs/langs-precompiled\n\nPrecompiled languages for Shiki that can runs in pure JavaScript environment.\n\nRequires ES2024+ environment.\n\n> **Experimental**\n\n## Unsupported Languages\n\n<!-- TODOs -->\n\n## License\n\nMIT\n","packages/langs/README.md":"# @shikijs/langs\n\nTextMate grammars for Shiki.\n\n## License\n\nMIT\n","packages/magic-move/README.md":"# @shikijs/magic-move\n\nSmoothly animated code blocks with [shiki](https://github.com/shikijs/shiki). Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n[Documentation](https://shiki.style/packages/magic-move)\n\n## License\n\nMIT\n","packages/markdown-exit/README.md":"# @shikijs/markdown-exit\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-exit)\n\n## License\n\nMIT\n","packages/markdown-it/README.md":"# @shikijs/markdown-it\n\n[markdown-it](https://markdown-it.github.io/) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-it)\n\n## License\n\nMIT\n","packages/monaco/README.md":"# @shikijs/monaco\n\nUse [shiki](https://github.com/shikijs/shiki) to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\n[Documentation](https://shiki.style/packages/monaco)\n\n## License\n\nMIT\n","packages/rehype/README.md":"# rehype-shiki\n\n[rehype](https://github.com/rehypejs/rehype) plugin for [shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/rehype)\n\n## License\n\nMIT\n","packages/shiki/README.md":"<img src=\"https://raw.githubusercontent.com/shikijs/shiki/main/docs/public/logo.svg\" width=\"150\" alt=\"Shiki Logo\" />\n\n# Shiki 式\n\n[![NPM version](https://img.shields.io/npm/v/shiki?color=32A9C3&labelColor=1B3C4A&label=npm)](https://www.npmjs.com/package/shiki)\n[![NPM downloads](https://img.shields.io/npm/dm/shiki?color=32A9C3&labelColor=1B3C4A&label=downloads)](https://www.npmjs.com/package/shiki)\n[![Codecov](https://img.shields.io/codecov/c/github/shikijs/shiki?token=B85J0E2I7I&style=flat&labelColor=1B3C4A&color=32A9C3&precision=1)](https://app.codecov.io/gh/shikijs/shiki)\n\nA beautiful syntax highlighter based on TextMate grammars, accurate and powerful.\n\n[📚 **Documentation**](https://shiki.style)\n\n## License\n\n[MIT](./LICENSE)\n","packages/stream/README.md":"# @shikijs/stream\n\nStreaming colorization for [shiki](https://github.com/shikijs/shiki). Useful for highlighting text streams like LLM outputs.\n\n[Documentation](https://shiki.style/packages/stream)\n\n## License\n\nMIT\n","packages/themes/README.md":"# @shikijs/themes\n\nTextMate themes for Shiki.\n\n## License\n\nMIT\n","packages/transformers/README.md":"# @shikijs/transformers\n\nCommon transformers for [shiki](https://github.com/shikijs/shiki), inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n[Documentation](https://shiki.style/packages/transformers)\n\n## License\n\nMIT\n","packages/twoslash/README.md":"# @shikijs/twoslash\n\nA [shiki](https://github.com/shikijs/shiki) transformer for [TypeScript Twoslash](https://www.typescriptlang.org/dev/twoslash/).\n\n[Documentations](https://shiki.style/packages/twoslash)\n\n## License\n\nMIT\n","packages/types/README.md":"# @shikijs/types\n\nTypes for Shiki.\n\n## License\n\nMIT\n","packages/vitepress-twoslash/README.md":"# @shikijs/vitepress-twoslash\n\nEnable Twoslash support in VitePress.\n\n[Documentation](https://shiki.style/packages/vitepress#twoslash)\n\n## License\n\nMIT\n"},"files":{"docs/api.md":"# API References\n\n## `codeToHast`\n\nYou can also get the intermediate `hast` to do custom rendering without serializing them into HTML with `codeToHast`. You can also further integrate the AST with the [unified](https://github.com/unifiedjs) ecosystem.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"aa0ea59b9742ed721640f4d1233696e3e09408080ce58a4fde6a5efd7f40382b\",\"data\":\"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=\"}\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord', 'min-light'],\n  langs: ['javascript'],\n})\n// ---cut---\nconst root = highlighter.codeToHast(\n  'const a = 1',\n  { lang: 'javascript', theme: 'nord' }\n)\n\nconsole.log(root)\n```\n\n<!-- eslint-skip -->\n\n```ts\n{\n  type: 'root',\n  children: [\n    {\n      type: 'element',\n      tagName: 'pre',\n      properties: {\n        class: 'shiki vitesse-light',\n        style: 'background-color:#ffffff;color:#393a34',\n        tabindex: '0'\n      },\n      children: [\n        {\n          type: 'element',\n          tagName: 'code',\n          properties: {},\n          children: [\n            {\n              type: 'element',\n              tagName: 'span',\n              properties: { class: 'line' },\n              children: [\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#AB5959' },\n                  children: [ { type: 'text', value: 'const' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#B07D48' },\n                  children: [ { type: 'text', value: ' a' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#999999' },\n                  children: [ { type: 'text', value: ' =' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#2F798A' },\n                  children: [ { type: 'text', value: ' 1' } ]\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}\n```\n","docs/packages/astro.md":"# Astro Integration\n\nYou don't need explicit integration in [Astro](https://astro.build/) as Astro already uses Shiki under the hood.\n\nLearn more about the configurations in the [Astro documentation](https://docs.astro.build/en/guides/syntax-highlighting/).\n","docs/packages/cli.md":"# @shikijs/cli\n\n<Badges name=\"@shikijs/cli\" />\n\nShiki in the command line.\n\n## Usage\n\nThe Shiki CLI works like `cat` command, but with syntax highlighting.\nIt also supports remote files.\n\n```bash\nnpx @shikijs/cli README.md\n```\n\n```bash\nnpx @shikijs/cli \\\n  'https://github.com/shikijs/shiki/blob/main/taze.config.ts?raw=true'\n```\n\n## Install\n\nYou can also install it globally. Command aliases `@shikijs/cli`, `shiki`, `skat` are registered.\n\n::: code-group\n\n```sh [npm]\nnpm i -g @shikijs/cli\n```\n\n```sh [yarn]\nyarn global add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add -g @shikijs/cli\n```\n\n```sh [bun]\nbun add -g @shikijs/cli\n```\n\n```sh [deno]\ndeno install -gREn skat npm:@shikijs/cli\n```\n\n:::\n\n```sh\nskat src/index.ts\n```\n\n## Options\n\n### `--theme`\n\nSpecify the theme to use. Defaults to `vitesse-dark`.\n\n```bash\nnpx @shikijs/cli README.md --theme=nord\n```\n\n### `--lang`\n\nLanguage is auto-inferred from the file extension. You can override it with `--lang`.\n\n```bash\nnpx @shikijs/cli src/index.js --lang=ts\n```\n\n### `--format`\n\nSpecify the output format. Defaults to `ansi`.\nSupported values: `ansi`, `html`.\n\n```bash\nnpx @shikijs/cli README.md --format=html\n```\n\n## Node.js API\n\nThe `@shikijs/cli` package also provides a Node.js API.\n\n::: code-group\n\n```sh [npm]\nnpm i @shikijs/cli\n```\n\n```sh [yarn]\nyarn add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add @shikijs/cli\n```\n\n```sh [bun]\nbun add @shikijs/cli\n```\n\n```sh [deno]\ndeno add npm:@shikijs/cli\n```\n\n:::\n\n### `codeToANSI`\n\nThe asynchronous `codeToANSI` function allows you to convert code to ANSI escape codes for terminal output.\nThis is useful for rendering syntax-highlighted code in the terminal.\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord')\n\nconsole.log(highlighted)\n```\n\n`codeToANSI` takes three required parameters:\n\n1. `code: string`\n2. `lang: BundledLanguage`\n3. `theme: BundledTheme`\n\nand one optional parameter:\n\n4. `options?: CodeToANSIOptions`\n\nThe color level of the emitted escape codes is explicit instead of being inferred from the environment, and defaults to `3` (truecolor). Use `options.colorLevel` to target a different level — pass the level reported by `ansis` to follow the current terminal, or `0` to get plain text:\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\nimport ansis from 'ansis'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord', {\n  colorLevel: ansis.level,\n})\n```\n","docs/packages/codegen.md":"# shiki-codegen\n\n<Badges name=\"shiki-codegen\" />\n\nCodegen for Shiki to create optimized bundles dedicated for your usage.\n\n## Usage\n\n### CLI\n\n```bash\nnpx shiki-codegen \\\n  --langs typescript,javascript,vue \\\n  --themes light-plus,dark-plus \\\n  --engine javascript \\\n  ./shiki.bundle.ts\n```\n\nFile `shiki.bundle.ts` will be created with the code that you can use in your project.\n\nThen you can use it in your project:\n\n```ts\nimport { codeToHtml } from './shiki.bundle'\n\nconst html = await codeToHtml(code, { lang: 'typescript', theme: 'light-plus' })\n```\n\n### Programmatic\n\nYou can also use `shiki-codegen` programmatically, and write the generated code to a file:\n\n```ts\nimport { codegen } from 'shiki-codegen'\n\nconst { code } = await codegen({\n  langs: ['typescript', 'javascript', 'vue'],\n  themes: ['light-plus', 'dark-plus'],\n  engine: 'javascript',\n  typescript: true\n})\n\n// Write the code to a file\n```\n","docs/packages/colorized-brackets.md":"---\noutline: deep\n---\n\n# @shikijs/colorized-brackets\n\n<Badges name=\"@shikijs/colorized-brackets\" />\n\nVSCode-style colorized brackets transformer for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/colorized-brackets\n```\n\n```sh [yarn]\nyarn add -D @shikijs/colorized-brackets\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/colorized-brackets\n```\n\n```sh [bun]\nbun add -D @shikijs/colorized-brackets\n```\n\n```sh [deno]\ndeno add npm:@shikijs/colorized-brackets\n```\n\n:::\n\n## Usage\n\nAdd to your Shiki transformers:\n\n```ts colorize-brackets\nimport { transformerColorizedBrackets } from '@shikijs/colorized-brackets'\nimport { codeToHtml } from 'shiki'\n\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: 'dark-plus',\n  transformers: [transformerColorizedBrackets()],\n})\n```\n\n### Colors\n\nBrackets are automatically colored according to your Shiki theme (or themes if using [dual themes](https://shiki.style/guide/dual-themes)), with support for all of Shiki's built-in themes. However, you can customize colors if you've added custom themes to Shiki, or if you want to override the colors of a built-in theme:\n\n```ts colorize-brackets\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: myCustomTheme,\n  transformers: [transformerColorizedBrackets({\n    themes: {\n      'my-custom-theme': ['goldenrod', 'blueviolet', 'dodgerblue', 'crimson'],\n    },\n  })],\n})\n```\n\nThe final color is the mismatched bracket color. The other colors are for each \"level\" of bracket pair. Any valid CSS color can be used.\n\nIf no bracket colors are found for a theme, it falls back to the default `dark-plus` theme.\n\n### Brackets\n\nYou can customize the bracket pairs:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  bracketPairs: [{ opener: '{', closer: '}' }],\n})\n```\n\nThe above would only colorize `{}` curly brackets. The default config colorizes `[]` square brackets, `{}` curly brackets, `()` parentheses, and `<>` angle brackets (only in TS type annotations).\n\nFor advanced usage, you can specify which TextMate scopes a bracket pair is allowed or denied in, using `scopesAllowList` and `scopesDenyList`. For example, the default config for `<>` angle brackets is:\n\n```ts colorize-brackets\nconst bracketPair = {\n  opener: '<',\n  closer: '>',\n  scopesAllowList: [\n    'punctuation.definition.typeparameters.begin.ts',\n    'punctuation.definition.typeparameters.end.ts',\n  ],\n}\n```\n\n### Language-specific Overrides\n\nAll settings can be overridden for specific languages using the `langs` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  langs: { ts: myCustomTypescriptConfig },\n})\n```\n\n### Explicit Trigger\n\nIf you do not want colorized brackets for all code blocks, you can enable the `explicitTrigger` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  explicitTrigger: true,\n})\n```\n\nThen, only code blocks with the `colorize-brackets` [meta string](/guide/transformers#meta) will have bracket colorizing enabled.\n\n````md\n```ts\n// no bracket colorizing\n```\n\n```ts colorize-brackets\n// brackets will be colorized\n```\n````\n","docs/packages/magic-move.md":"---\noutline: deep\n---\n\n# @shikijs/magic-move\n\n<Badges name=\"@shikijs/magic-move\" />\n\nSmoothly animated code blocks with Shiki. Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n`@shikijs/magic-move` is a low-level library: at its core is a framework-agnostic [diff/animation machine](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/core.ts) and [renderer](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/renderer.ts), with thin wrappers for Vue, React, Solid, Svelte, and a Web Component.\n\nEach framework wrapper provides three components:\n\n- **`ShikiMagicMove`** — the main component; wraps a code block and animates whenever `code` changes\n- **`ShikiMagicMovePrecompiled`** — animations for compiled tokens, without the Shiki dependency at runtime\n- **`ShikiMagicMoveRenderer`** — the low-level renderer component\n\n`ShikiMagicMove` needs a Shiki highlighter instance plus the bundled stylesheet (`@shikijs/magic-move/style.css`). Whenever `code` changes, the component animates the diff.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/magic-move shiki\n```\n\n```sh [yarn]\nyarn add -D @shikijs/magic-move shiki\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/magic-move shiki\n```\n\n```sh [bun]\nbun add -D @shikijs/magic-move shiki\n```\n\n```sh [deno]\ndeno add npm:@shikijs/magic-move npm:shiki\n```\n\n:::\n\n## Usage\n\n### Vue\n\nImport `@shikijs/magic-move/vue` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```vue\n<script setup>\nimport { ShikiMagicMove } from '@shikijs/magic-move/vue'\nimport { createHighlighter } from 'shiki'\nimport { ref } from 'vue'\n\nimport '@shikijs/magic-move/style.css'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst code = ref(`const hello = 'world'`)\n\nfunction animate() {\n  code.value = `let hi = 'hello'`\n}\n</script>\n\n<template>\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    :options=\"{ duration: 800, stagger: 0.3, lineNumbers: true }\"\n  />\n  <button @click=\"animate\">\n    Animate\n  </button>\n</template>\n```\n\n### React\n\nImport `@shikijs/magic-move/react` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport type { HighlighterCore } from 'shiki'\nimport { ShikiMagicMove } from '@shikijs/magic-move/react'\nimport { useEffect, useState } from 'react'\nimport { createHighlighter } from 'shiki'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = useState(`const hello = 'world'`)\n  const [highlighter, setHighlighter] = useState<HighlighterCore>()\n\n  useEffect(() => {\n    async function initializeHighlighter() {\n      const h = await createHighlighter({\n        themes: ['nord'],\n        langs: ['javascript', 'typescript'],\n      })\n      setHighlighter(h)\n    }\n    initializeHighlighter()\n  }, [])\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      {highlighter && (\n        <>\n          <ShikiMagicMove\n            lang=\"ts\"\n            theme=\"nord\"\n            highlighter={highlighter}\n            code={code}\n            options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n          />\n          <button onClick={animate}>Animate</button>\n        </>\n      )}\n    </div>\n  )\n}\n```\n\n### Solid\n\nImport `@shikijs/magic-move/solid` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport { ShikiMagicMove } from '@shikijs/magic-move/solid'\nimport { bundledLanguages, bundledThemes, createHighlighter } from 'shiki'\nimport { createResource, createSignal, Show } from 'solid-js'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = createSignal(`const hello = 'world'`)\n\n  const [highlighter] = createResource(async () => {\n    return await createHighlighter({\n      themes: Object.keys(bundledThemes),\n      langs: Object.keys(bundledLanguages),\n    })\n  })\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      <Show when={highlighter()}>\n        {h => (\n          <>\n            <ShikiMagicMove\n              lang=\"ts\"\n              theme=\"nord\"\n              highlighter={h()}\n              code={code()}\n              options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n            />\n            <button onClick={animate}>Animate</button>\n          </>\n        )}\n      </Show>\n    </div>\n  )\n}\n```\n\n### Svelte\n\nImport `@shikijs/magic-move/svelte` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```svelte\n<script lang=\"ts\">\n  import { ShikiMagicMove } from '@shikijs/magic-move/svelte'\n  import { createHighlighter } from 'shiki'\n\n  import '@shikijs/magic-move/style.css'\n\n  const highlighter = createHighlighter({\n    themes: ['nord'],\n    langs: ['javascript', 'typescript'],\n  })\n\n  let code = $state(`const hello = 'world'`)\n\n  function animate() {\n    code = `let hi = 'hello'`\n  }\n</script>\n\n{#await highlighter then highlighter}\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    {highlighter}\n    {code}\n    options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n  />\n  <button onclick={animate}>Animate</button>\n{/await}\n```\n\n## `ShikiMagicMovePrecompiled`\n\n`ShikiMagicMovePrecompiled` is a lighter variant of `ShikiMagicMove` that doesn't need Shiki at runtime — useful when you want to ship pre-tokenized step data (e.g. produced at build time) and animate between steps in the browser.\n\n```vue\n<script setup>\nimport { ShikiMagicMovePrecompiled } from '@shikijs/magic-move/vue'\nimport { ref } from 'vue'\n\nconst step = ref(1)\nconst compiledSteps = [/* Compiled token steps */]\n</script>\n\n<template>\n  <ShikiMagicMovePrecompiled\n    :steps=\"compiledSteps\"\n    :step=\"step\"\n  />\n  <button @click=\"step++\">\n    Next\n  </button>\n</template>\n```\n\nTo produce the compiled tokens, run this somewhere with access to Shiki (build script, server, etc.) and serialize the result:\n\n```ts\nimport { codeToKeyedTokens, createMagicMoveMachine } from '@shikijs/magic-move/core'\nimport { createHighlighter } from 'shiki'\n\nconst shiki = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst codeSteps = [\n  `const hello = 'world'`,\n  `let hi = 'hello'`,\n]\n\nconst machine = createMagicMoveMachine(\n  code => codeToKeyedTokens(shiki, code, {\n    lang: 'ts',\n    theme: 'nord',\n  }),\n  {\n    // options\n  },\n)\n\nconst compiledSteps = codeSteps.map(code => machine.commit(code).current)\n\n// Pass `compiledSteps` to the precompiled component.\n// Since these are plain serialisable objects, you can stringify them at build time\n// and rehydrate them in the browser without needing Shiki.\n```\n\n## How it works\n\nFor a deep dive into the algorithm behind the animations, see Anthony's article [**The Magic In Shiki Magic Move**](https://antfu.me/posts/shiki-magic-move).\n","docs/packages/markdown-exit.md":"# @shikijs/markdown-exit\n\n<Badges name=\"@shikijs/markdown-exit\" />\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for Shiki.\n\n`markdown-exit` is a modern TypeScript rewrite of `markdown-it` with native async rendering support — no extra library needed for async highlighting.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-exit\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-exit\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-exit\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-exit\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-exit\n```\n\n:::\n\n## Usage\n\nThe default export uses Shiki's [shorthands](/guide/shorthands) for on-demand loading of themes and languages. Since highlighting is async, use `md.renderAsync()` to render:\n\n````ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n\nconst html = await md.renderAsync(md_string)\n```\n\n## Custom `codeToHtml`\n\nIf you have a custom `codeToHtml` function (e.g., from a fine-grained shorthand bundle), use `fromAsyncCodeToHtml`:\n\n````ts\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\nconst md = createMarkdownExit()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-exit/core` and pass your own highlighter:\n\n```ts\nimport { fromHighlighter } from '@shikijs/markdown-exit/core'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = createMarkdownExit()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n","docs/packages/markdown-it.md":"# @shikijs/markdown-it\n\n<Badges name=\"@shikijs/markdown-it\" />\n\n[markdown-it](https://markdown-it.github.io/) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-it\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-it\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-it\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-it\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-it\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"959709c97c288ea5ed5a231f28e5eebf48f1676e9c76559e68208cb76e2b6711\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n```\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"7251d42df549db899085560c6ca05a99dc9f338642b7849507ef0ead24fa6dba\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n```\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-it/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4cce3b72c2224ceff07c637806719480ab0b5bcdb0fafc8ad599ec8c8ad5d255\",\"data\":\"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\"}\n// @noErrors: true\nimport { fromHighlighter } from '@shikijs/markdown-it/core'\nimport MarkdownIt from 'markdown-it'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = MarkdownIt()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n\n## With Shorthands\n\nShiki's [shorthands](/guide/shorthands) provides on-demand loading of themes and languages, but also makes the highlighting process asynchronous. Unfortunately, `markdown-it` itself [does NOT support async highlighting](https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#i-need-async-rule-how-to-do-it) out of the box.\n\nTo workaround this, you can use [`markdown-it-async`](https://github.com/antfu/markdown-it-async) by [Anthony Fu](https://github.com/antfu). Where Shiki also provides an integration with it, you can import `fromAsyncCodeToHtml` from `@shikijs/markdown-it/async`.\n\n````ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4d4fcf8100ee107a1813af12192e944bfcf04449a77daa41fca68ea887412763\",\"data\":\"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\"}\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async'\nimport MarkdownItAsync from 'markdown-it-async'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\n// Initialize MarkdownIt instance with markdown-it-async\nconst md = MarkdownItAsync()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    // Pass the codeToHtml function\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformer Caveats\n\n`markdown-it` defaults to enforcing `<pre><code>` as the outermost wrappers of code block html. If you use a custom Shiki [transformer](/guide/transformers), this behavior may be undesirable. For example, if the transformer produces\n\n```html\n<div class=\"fenced-code-block\">\n  <pre>\n    <code>\n      …\n    </code>\n  </pre>\n</div>\n```\n\nthe result after `markdown-it` processing will be\n\n```html\n<pre>\n  <code>\n    <div class=\"fenced-code-block\">\n      <pre>\n        <code>\n          …\n        </code>\n      </pre>\n    </div>\n  </code>\n</pre>\n```\n\nWork around this by adding [olets/markdown-it-wrapperless-fence-rule](https://github.com/olets/markdown-it-wrapperless-fence-rule) to your `markdown-it` configuration, or by writing your own `markdown-it` fence rule (see [markdown-it#269](https://github.com/markdown-it/markdown-it/issues/269)).\n","docs/packages/monaco.md":"# Monaco Editor Integration\n\nShiki uses the same TextMate grammar and themes as VS Code, so it can be used to highlight Monaco Editor. Shiki provides an official integration for Monaco Editor. You can also use [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration.\n\n## @shikijs/monaco\n\n<Badges name=\"@shikijs/monaco\" />\n\nUse Shiki to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\nMonaco's built-in highlighter does not use the full TextMate grammar, which in some cases is not accurate enough. This package allows you to use Shiki's syntax highlighting engine to highlight Monaco, with shared grammars and themes from Shiki.\n\nHeavily inspired by [`monaco-editor-textmate`](https://github.com/zikaari/monaco-editor-textmate).\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/monaco\n```\n\n```sh [yarn]\nyarn add -D @shikijs/monaco\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/monaco\n```\n\n```sh [bun]\nbun add -D @shikijs/monaco\n```\n\n```sh [deno]\ndeno add npm:@shikijs/monaco\n```\n\n:::\n\n### Usage\n\n```ts\nimport { shikiToMonaco } from '@shikijs/monaco'\nimport * as monaco from 'monaco-editor-core'\nimport { createHighlighter } from 'shiki'\n\n// Create the highlighter, it can be reused\nconst highlighter = await createHighlighter({\n  themes: [\n    'vitesse-dark',\n    'vitesse-light',\n  ],\n  langs: [\n    'javascript',\n    'typescript',\n    'vue'\n  ],\n})\n\n// Register the languageIds first. Only registered languages will be highlighted.\nmonaco.languages.register({ id: 'vue' })\nmonaco.languages.register({ id: 'typescript' })\nmonaco.languages.register({ id: 'javascript' })\n\n// Register the themes from Shiki, and provide syntax highlighting for Monaco. // [!code highlight:2]\nshikiToMonaco(highlighter, monaco)\n\n// Create the editor\nconst editor = monaco.editor.create(document.getElementById('container'), {\n  value: 'const a = 1',\n  language: 'javascript',\n  theme: 'vitesse-dark',\n})\n\n// ...As you use the editor normally\n```\n\n## modern-monaco\n\n<Badges name=\"modern-monaco\" />\n\nWe highly recommend using [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration. It provides a more convenient API for building Monaco Editor.\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D modern-monaco\n```\n\n```sh [yarn]\nyarn add -D modern-monaco\n```\n\n```sh [pnpm]\npnpm add -D modern-monaco\n```\n\n```sh [bun]\nbun add -D modern-monaco\n```\n\n```sh [deno]\ndeno add npm:modern-monaco\n```\n\n:::\n\nOr import it from [esm.sh](https://esm.sh) CDN in the browser without a build step:\n\n```js\nimport * as monaco from 'https://esm.sh/modern-monaco'\n```\n\n### Usage\n\n```html\n<!-- index.html -->\n<monaco-editor theme=\"vitesse-dark\"></monaco-editor>\n<script src=\"app.js\" type=\"module\"></script>\n```\n\n```js\n// app.js\nimport { lazy, Workspace } from 'modern-monaco'\n\n// create a workspace with initial files\nconst workspace = new Workspace({\n  initialFiles: {\n    'index.html': `<html><body>...</body></html>`,\n    'main.js': `console.log('Hello, world!')`,\n  },\n  entryFile: 'index.html',\n})\n\n// initialize the editor lazily\nawait lazy({ workspace })\n\n// write a file and open it in the editor\nworkspace.fs.writeFile('util.js', 'export function add(a, b) { return a + b; }')\nworkspace.openTextDocument('util.js')\n```\n\nMore usage please see the [modern-monaco](https://github.com/esm-dev/modern-monaco) repository.\n","docs/packages/next.md":"# Next.js\n\nShiki does not provide an official integration for [Next.js](https://nextjs.org), but it is rather straightforward to use Shiki in Next.js applications.\n\n::: info\nUsing Shiki on Edge Runtime might cause unintended problems, Shiki relies on lazy imports to load languages and themes.\n\nServerless Runtime is recommended.\n:::\n\n## React Server Component\n\nSince Server Components are server-only, you can use the bundled highlighter without worrying the bundle size.\n\n```tsx\nimport type { BundledLanguage } from 'shiki'\nimport { codeToHtml } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHtml(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return <div dangerouslySetInnerHTML={{ __html: out }} />\n}\n```\n\n### Custom Components\n\nYou can also call `codeToHast` to get the HTML abstract syntax tree, and render it using [`hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime). With this method, you can render your own `pre` and `code` components.\n\n```tsx\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHast(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n    components: {\n      // your custom `pre` element\n      pre: props => <pre data-custom-codeblock {...props} />\n    },\n  }) as JSX.Element\n}\n```\n\n## React Client Component\n\nFor client components, they are pre-rendered on server and hydrated/rendered on client.\nWe can start by creating a client `CodeBlock` component.\n\nCreate a `shared.ts` for highlighter:\n\n```ts\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki/bundle/web'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki/bundle/web'\n\nexport async function highlight(code: string, lang: BundledLanguage) {\n  const out = await codeToHast(code, {\n    lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n  }) as JSX.Element\n}\n```\n\nIn your `codeblock.tsx`:\n\n```tsx\n'use client'\nimport { JSX, useLayoutEffect, useState } from 'react'\nimport { highlight } from './shared'\n\nexport function CodeBlock({ initial }: { initial?: JSX.Element }) {\n  const [nodes, setNodes] = useState(initial)\n\n  useLayoutEffect(() => {\n    void highlight('console.log(\"Rendered on client\")', 'ts').then(setNodes)\n  }, [])\n\n  return nodes ?? <p>Loading...</p>\n}\n```\n\nThe `initial` prop can be passed from a server component to pre-render the code block on server.\n\nIn your `page.tsx`:\n\n```tsx\nimport { CodeBlock } from './codeblock'\nimport { highlight } from './shared'\n\nexport default async function Page() {\n  // `initial` is optional.\n  return (\n    <main>\n      <CodeBlock initial={await highlight('console.log(\"Rendered on server\")', 'ts')} />\n    </main>\n  )\n}\n```\n\n::: info\nThe above example uses the `shiki/bundle/web` bundle. You can change it to [Fine-grained Bundle](/guide/bundles#fine-grained-bundle) to fully control the bundled languages/themes.\n:::\n\n### Performance\n\nShiki lazy loads the requested languages and themes, the Next.js bundler can handle lazy imports automatically.\nImporting `shiki` or its web bundle is efficient enough for most Next.js applications, Fine-grained Bundle won't significantly impact the bundle size.\n\nIn addition, you can use the `createHighlighter` API to preload specific languages and themes.\nPlease refer to [Highlighter Usage](/guide/install#highlighter-usage) for further details.\n\n### Highlighter Instance\n\nIf you define a highlighter (without `await`) as a global variable, you can reference it directly from server and client components.\n\n```ts\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript'],\n})\n\n// Inside an async server component, or client side `useEffect`\nconst html = (await highlighter).codeToHtml('const a = 1', {\n  lang: 'javascript',\n  theme: 'nord'\n})\n```\n","docs/packages/nuxt.md":"# Nuxt\n\n[Nuxt](https://nuxt.com) is a general-purpose meta-framework that gives you full control over your application. You can install Shiki along with integrations like ([markdown-it](/packages/markdown-it), [rehype](/packages/rehype)) or import manually as you needed.\n\nOn top of that, Nuxt also provide some module integrations for Shiki allowing you use it easier:\n\n- [`nuxt-shiki`](https://github.com/pi0/nuxt-shiki) - Shiki integration for client and server sides, with component usage.\n- [`@nuxt/content`](https://github.com/nuxt/content) - Nuxt Content has Shiki built-in for markdown files. [You can enable it with the `highlight` option](https://content.nuxt.com/docs/getting-started/configuration#highlight).\n  - [`@nuxtjs/mdc`](https://github.com/nuxt-modules/mdc) - The underlying module of `@nuxt/content` that provides Markdown Component (MDC) syntax as well as Shiki for syntax highlighting.\n\n## TwoSlash Integration\n\n- [`nuxt-content-twoslash`](https://github.com/antfu/nuxt-content-twoslash) - A Nuxt module that adds Twoslash support to Nuxt Content. Twoslash information are evaluated at build time.\n","docs/packages/rehype.md":"---\noutline: deep\n---\n\n# @shikijs/rehype\n\n<Badges name=\"@shikijs/rehype\" />\n\n[rehype](https://github.com/rehypejs/rehype) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/rehype\n```\n\n```sh [yarn]\nyarn add -D @shikijs/rehype\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/rehype\n```\n\n```sh [bun]\nbun add -D @shikijs/rehype\n```\n\n```sh [deno]\ndeno add npm:@shikijs/rehype\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"f652dc1d308709739c1be11a9172b77ef0b59d02c30ad9b2f5dc7195fad4cd45\",\"data\":\"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=\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThe default export of `@shikijs/rehype` uses a shared instance of `shiki` from `getSingletonHighlighter`, which will persist across processes. If you want full control over the highlighter lifecycle, use [Fine-grained Bundle `@shikijs/rehype/core`](#fine-grained-bundle) instead.\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import `rehypeShikiFromHighlighter` from `@shikijs/rehype/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"141199456275121b3ddecb36bbeedc3ec800ba9c5d4c78ec0a3f651e44ac22ee\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShikiFromHighlighter from '@shikijs/rehype/core'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nimport { unified } from 'unified'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst raw = await fs.readFile('./input.md')\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShikiFromHighlighter, highlighter, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .processSync(raw) // it's also possible to process synchronously\n```\n\n## Features\n\n### Inline Code\n\nYou can also highlight inline codes with the `inline` option.\n\n| Option                  | Example          | Description                                                 |\n| ----------------------- | ---------------- | ----------------------------------------------------------- |\n| `false`                 | -                | Disable inline code highlighting (default)                  |\n| `'tailing-curly-colon'` | `let a = 1{:js}` | Highlight with a `{:language}` marker inside the code block |\n\nEnable `inline` on the Rehype plugin:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"549ef2ad84b55c413cb40bcedc19dcf805008cf25a703dd1f3614dff89dbdd93\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    inline: 'tailing-curly-colon', // or other options\n    // ...\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThen you can use inline code in markdown:\n\n```md\nThis code `console.log(\"Hello World\"){:js}` will be highlighted.\n```\n\n## Postprocess Transformers\n\n::: info\nThe `postprocess` transformer hook is only invoked when producing HTML strings (i.e., when using `codeToHtml`). Since `@shikijs/rehype` operates on HAST (Hypertext Abstract Syntax Tree) rather than HTML strings, postprocess transformers will not be executed.\n:::\n\nThis design is intentional: running `postprocess` hooks in rehype would require converting HAST → HTML → running postprocess → parsing back to HAST, which changes the semantics and could surprise users expecting HAST-only transformers.\n\n### Workaround for HTML-based Postprocessing\n\nIf you need to run HTML-based postprocessing with rehype, you can apply a `root` transformer that:\n\n1. Converts the HAST fragment to HTML using `hast-util-to-html`\n2. Runs your HTML transformers\n3. Converts back to HAST using `hast-util-from-html`\n\nExample:\n\n```ts\nimport { fromHtml } from 'hast-util-from-html'\nimport { toHtml } from 'hast-util-to-html'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    },\n    transformers: [\n      {\n        name: 'custom-html-postprocessor',\n        root(node) {\n          // Convert HAST to HTML\n          const html = toHtml(node)\n\n          // Apply your HTML transformations\n          const processedHtml = myCustomPostprocess(html)\n\n          // Parse back to HAST\n          const newNode = fromHtml(processedHtml, { fragment: true })\n\n          // Replace the node\n          return newNode\n        }\n      }\n    ]\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n","docs/packages/stream.md":"---\noutline: deep\n---\n\n# @shikijs/stream\n\n<Badges name=\"@shikijs/stream\" />\n\nStreaming colorization for Shiki. Useful for highlighting text streams like LLM outputs, where code arrives incrementally and you want each chunk highlighted as it lands without re-tokenizing the whole document.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/stream\n```\n\n```sh [yarn]\nyarn add -D @shikijs/stream\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/stream\n```\n\n```sh [bun]\nbun add -D @shikijs/stream\n```\n\n```sh [deno]\ndeno add npm:@shikijs/stream\n```\n\n:::\n\n## Usage\n\nCreate a transform stream with `CodeToTokenTransformStream` and `.pipeThrough` your text stream:\n\n```ts\nimport { CodeToTokenTransformStream } from '@shikijs/stream'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\n\n// Initialize the Shiki highlighter somewhere in your app\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\n// The ReadableStream<string> you want to highlight\nconst textStream = getTextStreamFromSomewhere()\n\n// Pipe the text stream through the token stream\nconst tokensStream = textStream\n  .pipeThrough(new CodeToTokenTransformStream({\n    highlighter,\n    lang: 'javascript',\n    theme: 'nord',\n    allowRecalls: true, // see explanation below\n  }))\n```\n\n### `allowRecalls`\n\nDue to the fact that highlighting may change based on the context of the code, themed tokens can be re-evaluated as the stream progresses. Because streams are one-directional, `@shikijs/stream` emits a special **recall** token that tells the receiver to discard the last N tokens that changed.\n\nBy default, `CodeToTokenTransformStream` only emits **stable** tokens — no recalls. The trade-off is coarser granularity, usually one line at a time.\n\nFor stream consumers that can handle recalls (e.g. the bundled Vue, React, Solid, and Svelte components), set `allowRecalls: true` to get finer-grained tokens.\n\nTypically recalls should be handled like:\n\n```ts\nimport type { RecallToken } from '@shikijs/stream'\nimport type { ThemedToken } from 'shiki'\n\nconst receivedTokens: ThemedToken[] = []\n\ntokensStream.pipeTo(new WritableStream<ThemedToken | RecallToken>({\n  async write(token) {\n    if ('recall' in token) {\n      // discard the last `token.recall` tokens\n      receivedTokens.length -= token.recall\n    }\n    else {\n      receivedTokens.push(token)\n    }\n  },\n}))\n```\n\n## Consume the Token Stream\n\n### Manually\n\n```ts\ntokensStream.pipeTo(new WritableStream({\n  async write(token) {\n    console.log(token)\n  },\n}))\n```\n\nOr in Node.js:\n\n```ts\nfor await (const token of tokensStream) {\n  console.log(token)\n}\n```\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/vue'\n\n// get the token stream\n</script>\n\n<template>\n  <ShikiStreamRenderer :stream=\"tokensStream\" />\n</template>\n```\n\n### React\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/react'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Solid\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/solid'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Svelte\n\n```svelte\n<script lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/svelte'\n\n// get the token stream\n</script>\n\n<ShikiStreamRenderer stream={tokensStream} />\n```\n\n## Cached Renderer\n\n`@shikijs/stream` also ships a simplified renderer for the common case of an incrementally-updated code string (rather than a token stream).\n\n::: warning Experimental\nThis API is experimental and may change.\n:::\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiCachedRenderer } from '@shikijs/stream/vue'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\nimport { onMounted, ref } from 'vue'\n\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\nconst code = ref('') // code should only be updated incrementally\n\n// for demo purposes\nonMounted(() => {\n  setInterval(() => {\n    code.value += '\\nconsole.log(\"Hello, world!\");'\n  }, 1000)\n})\n</script>\n\n<template>\n  <ShikiCachedRenderer\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    lang=\"js\"\n    theme=\"vitesse-light\"\n  />\n</template>\n```\n","docs/packages/transformers.md":"---\noutline: deep\n---\n\n# @shikijs/transformers\n\n<Badges name=\"@shikijs/transformers\" />\n\nCommon transformers for Shiki, inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/transformers\n```\n\n```sh [yarn]\nyarn add -D @shikijs/transformers\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/transformers\n```\n\n```sh [bun]\nbun add -D @shikijs/transformers\n```\n\n```sh [deno]\ndeno add npm:@shikijs/transformers\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"8efec5d385627b3d23e03e4c9bdf13f9a3c80178f3105cfb878cd54cef1eacb9\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZAHIQ0zcZIAi7fv0YQsO+QH5EvACqz5iles3aJYfYYDyp1zysBlfHYAa3ZbOQUlVVIAHTB2ZSwlNGk7CMdSDS0zd35KECgIEQREEABVOBheAANkAEIRaEqAaiaAXSreOShquobYXgBaAfbpCF5lZlIgzqhYbq7eUhhlYhhujjB4ADo8uC1SBkQAZgAWKlYYMABzNHwkACYjqn2rmEPqVIcozJc9A1zzuxNg8qCJ8JNmGIyA8AL4UdDYXAlQgkcjPOjvFgcLh8BryZJ9GDWCAACTQylYVkYhKse1IQKuFF4JjMcCsAGFGsSSVw0F5WQAeABCwigFygABk5FdBMxXkyRWAxWtrPhljAAHx8AC8Gt4AAVSBBlOwKgK6QyNbF4okDrxCdzyaxdvtDgBGN0ABnOlxud0QXuek1e7wdpKdeQ2SIAbKDwbIoeREPc4QicHgUdD0fQ8Hi9vbGlZoiA8xALltWBArowAORq1iVmvcYsuybuk5nEAXa63JCdl5vXONSNApEATjjEMTSGjqeoiIzqzR1AxQ/xvHwTtpMgZrYOSDdAA5vV3fb3EP3g4PkRHAcCAyewVOaEnZ/D5+nkUu8jQcyUsZwPAFrAjoUtSha8Ba1xMiyPgclypK8vyPjCqK4pStcsryrwirKlAqrqlqViGsapowOaO7XFacQJEkwFEuGFJ7u6Y5PKePb+oG1BXqGCFkkxd5IlxT4Ji+B5jnOmCfgQ37Zrx640rwxaluWlbVnWMANhATYtlQextg8nqdt2fp9kGpAhkOsAjvewnxpCYnHJ6kkLl+qI/qu/5YEaOAHBgfCsNKRbUHAukgPp+7Jm6xlnv6l4WdeXbSjZQlupOonQsmLnSZmy6/pi3kmGQmB8JysDIZIcB+AyFwEaoqFKuKdWalstzqlYzUAEowFcpoyL8YAAIJgBgvAAD68H4lFXBK7AvmwpRxJIDV4c1TJQVcGrMQ89yHj6HFIAArOZlklG1qgpQe9zpQ5mUpu+UlIjJ7lyUwhW+SVNifJEZAVfIrXfekcCWJNgQhGE9g/aQyCtONvCijA/CjlAeQFEUeAQ2kURwAISjSGqoPBOwvBYOwOBRjsemug8JzHexpkBtd3EJe8/WQ0Dl0BmxIm3Um91pk9uUeX+IAATiKThF8ThZK4OTGN4lUg5jUsZM42T/H9viE+DgNRNatF2mzWPSwNOSo4UxRlBUPT1I0vAtCMCw1Lb/RDCMaBjBMUwzHMnRKosyyrOso5wJT4XU8m0Z0yZ56PCdiVGyrPzq4YnPRTd04XjCrSgsOJQAPT57wvR24EVz4Bw5doIgh2tPrtrJMAsS8BL7PfGrsv/BQze8IXvBbAPsQwgIRrKLwNYAAJwGD7AAFZwPnidQ3ANb13RTdSPRoGsN3YDD/wo/j9PROr2AsR5gSdvatUKkwBWVa1vWjbcFU5+Vckm4Urw1/MAA7swc0t6MVYOBWATIN4t0CtcKwNY0Ar13i3c6MAYGQFIFAGsCDW7G1IGyYuPdEG6xNinIw3AmR9xLv0MuFd2BVzrpvFufcB5bB7jnIe3A8iqC0EgUAGJLhwFcHgOBIAYQwiAA===\"}\n// [!code highlight:5]\nimport {\n  transformerNotationDiff,\n  // ...\n} from '@shikijs/transformers'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff(), // [!code highlight]\n    // ...\n  ],\n})\n```\n\n## Unstyled\n\nTransformers only applies classes and does not come with styles; you can provide your own CSS rules to style them properly.\n\n## Matching Algorithm\n\nWe found that the algorithm for matching comments in v1 is sometime conterintuitive, where we are trying to fix it in a progressive way. Since v1.29.0, we introduced a new `matchAlgorithm` option to most of the transformer for you to toggle between different matching algorithms. Right now, the default is `v1` which is the old algorithm, and `v3` is the new algorithm. When Shiki v3 is landed, the default will be `v3`.\n\n```ts\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff({\n      matchAlgorithm: 'v3', // [!code hl]\n    }),\n  ],\n})\n```\n\n### `matchAlgorithm: 'v1'`\n\nThe matching algorithm mostly affects the single-line comment matching, in `v1`, it will count the comment line as the first line, while in `v3`, it will count start from the comment line:\n\n```ts\n// [\\!code highlight:3]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n### `matchAlgorithm: 'v3'`\n\nIn `v3`, the matching algorithm will start counting from the line below the comment:\n\n```ts\n// [\\!code highlight:2]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n## Transformers\n\n### `transformerNotationDiff`\n\nUse `[!code ++]` and `[!code --]` to mark added and removed lines.\n\n````md\n```ts\nconsole.log('hewwo') // [\\!code --]\nconsole.log('hello') // [\\!code ++]\nconsole.log('goodbye')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('hewwo') // [!code --]\nconsole.log('hello') // [!code ++]\nconsole.log('goodbye')\n```\n\n- `// [!code ++]` outputs: `<span class=\"line diff add\">`\n- `// [!code --]` outputs: `<span class=\"line diff remove\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-diff\">`\n\n::: details HTML Output\n\n```html\n<!-- Output (stripped of `style` attributes for clarity) -->\n<pre class=\"shiki has-diff\"> <!-- Notice `has-diff` -->\n  <code>\n    <span class=\"line\"></span>\n    <span class=\"line\"><span>function</span><span>()</span><span></span><span>{</span></span>\n    <span class=\"line diff remove\">  <!-- Notice `diff` and `remove` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hewwo</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line diff add\">  <!-- Notice `diff` and `add` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hello</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line\"><span></span><span>}</span></span>\n    <span class=\"line\"><span></span></span>\n  </code>\n</pre>\n```\n\n:::\n\n---\n\n### `transformerNotationHighlight`\n\nUse `[!code highlight]` to highlight a line.\n\n````md\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [\\!code highlight]\nconsole.log('Not highlighted')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [!code highlight]\nconsole.log('Not highlighted')\n```\n\n- `// [!code highlight]` outputs: `<span class=\"line highlighted\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nYou can also highlight multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [\\!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n````\n\nRenders:\n\n```ts\n// [!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n---\n\n### `transformerNotationWordHighlight`\n\nUse `[!code word:Hello]` to highlight the word `Hello` in any subsequent code.\n\n````md\n```ts\n// [\\!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\n// [!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\nYou can also specify the number of lines to highlight words on, e.g. `[!code word:Hello:1]` will only highlight occurrences of `Hello` on the next line.\n\n````md\n```ts\n// [\\!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders:\n\n```ts\n// [!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\n---\n\n### `transformerNotationFocus`\n\nUse `[!code focus]` to focus a line.\n\n````md\n```ts\nconsole.log('Not focused');\nconsole.log('Focused') // [\\!code focus]\nconsole.log('Not focused');\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not focused')\nconsole.log('Focused') // [!code focus]\nconsole.log('Not focused')\n```\n\n- Outputs: `<span class=\"line focused\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-focused\">`\n\nYou can also focus multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n````\n\nRenders:\n\n```ts\n// [!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n\n---\n\n### `transformerNotationErrorLevel`\n\nUse `[!code error]`, `[!code warning]`, and `[!code info]` to mark a line with an error, warning, or info levels.\n\n````md\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [\\!code error]\nconsole.warn('Warning') // [\\!code warning]\nconsole.log('Info') // [\\!code info]\n```\n````\n\n- Outputs: `<span class=\"line highlighted error\">` for errors\n- Outputs: `<span class=\"line highlighted warning\">` for warnings\n- Outputs: `<span class=\"line highlighted info\">` for info\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nWith some additional CSS rules, you can make it look like this:\n\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [!code error]\nconsole.warn('Warning') // [!code warning]\nconsole.log('Info') // [!code info]\n```\n\n---\n\n### `transformerRenderWhitespace`\n\nRender whitespaces (tabs and spaces) as individual spans, with classes `tab` and `space`.\n\nOptions:\n\n- `position`: `'all' | 'boundary' | 'trailing' | 'leading'`. Default `'all'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#AB5959;--shiki-dark:#CB7676;\">function</span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">block</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">{</span></span>\n<span class=\"line\"><span class=\"space\"> </span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">space</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span></span>\n<span class=\"line\"><span class=\"tab\">&#9;</span><span class=\"tab\">&#9;</span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">tab</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span style=\"--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;\"> </span></span>\n<span class=\"line\"><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .tab,\npre.shiki .space {\n  position: relative;\n}\n\npre.shiki .tab::before {\n  content: '⇥';\n  position: absolute;\n  opacity: 0.3;\n}\n\npre.shiki .space::before {\n  content: '·';\n  position: absolute;\n  opacity: 0.3;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderIndentGuides`\n\nRender indentations as individual spans, with class `indent`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CB7676\">function</span><span style=\"color:#80A665\"> func</span><span style=\"color:#666666\">()</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">1</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\" style=\"--indent-offset: 0ch;\"></span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#4D9375\">for</span><span style=\"color:#666666\"> (</span><span style=\"color:#CB7676\">const </span><span style=\"color:#BD976A\">i</span><span style=\"color:#CB7676\"> of</span><span style=\"color:#666666\"> [])</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">2</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#666666\">}</span></span>\n<span class=\"line\"><span style=\"color:#666666\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .indent {\n  display: inline-block;\n  position: relative;\n  left: var(--indent-offset);\n}\n\npre.shiki .indent:empty {\n  height: 1lh;\n  vertical-align: bottom;\n}\n\npre.shiki .indent::before {\n  content: '';\n  position: absolute;\n  opacity: 0.15;\n  width: 1px;\n  height: 100%;\n  background-color: currentColor;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderLineNumber`\n\nRender line numbers as individual spans, with class `line-number`.\n\n```ts\nimport { transformerRenderLineNumber } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  transformers: [\n    transformerRenderLineNumber(),\n  ],\n})\n```\n\nOptions:\n\n- `start`: Start number. Default `1`.\n- `classLineNumber`: Class for line number. Default `'line-number'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n```css\npre.shiki .line-number {\n  user-select: none;\n  opacity: 0.5;\n  margin-right: 1em;\n}\n```\n\n---\n\n### `transformerMetaHighlight`\n\nHighlight lines based on the [meta string](/guide/transformers#meta) provided on the code snippet.\n\n````md\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n````\n\nRenders (with custom CSS rules):\n\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n\n- Outputs: `<span class=\"line highlighted\">` for included lines.\n\n### `transformerMetaWordHighlight`\n\nHighlight words based on the meta string provided on the code snippet.\n\n````md\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg)\nconsole.log(msg) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\n---\n\n### `transformerCompactLineOptions`\n\nSupport for `shiki`'s `lineOptions` that is removed in `shiki`.\n\n---\n\n### `transformerRemoveLineBreak`\n\nRemove line breaks between `<span class=\"line\">`. Useful when you set `display: block` to `.line` in CSS.\n\n---\n\n### `transformerRemoveNotationEscape`\n\nTransform `// [\\!code ...]` to `// [!code ...]`.\nAvoid rendering the escaped notation syntax as it is.\n\n---\n\n### `transformerStyleToClass`\n\nConvert Shiki's inline styles to unique classes.\n\nClass names are generated based on the hash value of the style object with the prefix/suffix you provide. You can put this transformer in multiple highlights passes and then get the CSS at the end to reuse the exact same styles. As Shiki doesn't handle CSS, it's on your integration to decide how to extract and apply/bundle the CSS.\n\nFor example:\n\n```ts\nimport { transformerStyleToClass } from '@shikijs/transformers'\nimport { codeToHtml } from 'shiki'\n\nconst toClass = transformerStyleToClass({ // [!code highlight:3]\n  classPrefix: '__shiki_',\n})\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  themes: {\n    dark: 'vitesse-dark',\n    light: 'vitesse-light',\n  },\n  defaultColor: false,\n  transformers: [toClass], // [!code highlight]\n})\n\n// The transformer instance exposes some methods to get the CSS\nconst css = toClass.getCSS() // [!code highlight]\n\n// use `html` and `css` in your app\n```\n\nHTML output:\n\n```html\n<pre class=\"shiki shiki-themes vitesse-dark vitesse-light __shiki_9knfln\" tabindex=\"0\"><code><span class=\"line\">\n  <span class=\"__shiki_14cn0u\">console</span>\n  <span class=\"__shiki_ps5uht\">.</span>\n  <span class=\"__shiki_1zrdwt\">log</span>\n  <span class=\"__shiki_ps5uht\">(</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_1g4r39\">hello</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_ps5uht\">)</span>\n</span></code></pre>\n```\n\nCSS output:\n\n```css\n.__shiki_14cn0u {\n  --shiki-dark: #bd976a;\n  --shiki-light: #b07d48;\n}\n.__shiki_ps5uht {\n  --shiki-dark: #666666;\n  --shiki-light: #999999;\n}\n.__shiki_1zrdwt {\n  --shiki-dark: #80a665;\n  --shiki-light: #59873a;\n}\n.__shiki_236mh3 {\n  --shiki-dark: #c98a7d77;\n  --shiki-light: #b5695977;\n}\n.__shiki_1g4r39 {\n  --shiki-dark: #c98a7d;\n  --shiki-light: #b56959;\n}\n.__shiki_9knfln {\n  --shiki-dark: #dbd7caee;\n  --shiki-light: #393a34;\n  --shiki-dark-bg: #121212;\n  --shiki-light-bg: #ffffff;\n}\n```\n\n### `transformerRemoveComments`\n\nRemove comments from the code. It works by checking the internal grammar token metadata to determine if the token is a comment.\n\nThis transformer requires `includeExplanation: true` to work.\n\n```ts\nimport { transformerRemoveComments } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  includeExplanation: true, // [!code highlight]\n  transformers: [\n    transformerRemoveComments(), // [!code highlight]\n  ],\n})\n```\n\nOptions:\n\n- `removeEmptyLines`: Remove lines that become empty after removing comments. Default `true`.\n\nFor example:\n\n````md\n```js\n// This is a comment\nconst x = 1 // Inline comment\n/* Block comment */\nconst y = 2\n\n// Another comment\n```\n````\n\nWill renders:\n\n```js\nconst x = 1\nconst y = 2\n```\n","docs/packages/twoslash.md":"---\noutline: deep\n---\n\n# @shikijs/twoslash\n\n<Badges name=\"@shikijs/twoslash\" />\n\nA Shiki transformer for [Twoslash](https://github.com/twoslashes/twoslash), provide inline type hover inside code blocks.\n\n[TwoSlash Notation Reference](https://twoslash.netlify.app/refs/notations).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm install -D @shikijs/twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/twoslash\n```\n\n:::\n\nThis package is **a transformer addon** to Shiki. This means that for every integration that supports passing Shiki transformers, you can use this package.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"b436269721bc02aa6e2b87b8db32bd8f1713dc97017fd91b867735e43ccd0ba0\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQARk2qVhgwabRcrYBOKlXSaZgN6lSB+yy9PI4wXC2qEXw1ippyRAAmAC+FHQ2DeBGIZDyNHoTDYnB4TRMyRE0BgaggAAk0MpWBZGKjYBYVqRJtMKLxDPM4BYAMJojGYrhoTzUgA8ACFhFA9lAADJyaaCZhXClc1y8tT4GCqAB8fAAvLLeAAFUgQZTsOAwNkksmy2LxRLrJGwRk41jLC4bADsAAZdvtDsdNg7qGsrjdCeisRbnpM3gAWD5fWRiKEA4GgnB4QgkcjnOhe5G8fAW4kyMlWtYbV3BkB7A5HJD5i6e2N+3YBpA2kPfcN/ABsUeoYNjkIT1CTcI4XD43vNuIJaIzpIOFKp3hpvHpZqxzNZU853N5AoOwtFvHFPJgUClMpg8osao1Wp1eoOBriCSSpp92Nx2fWSG2tYLTuLWzdZeueAHvsfKtXhrOsw1+F8ThbTAYxKOMoUTWESkYLB1RwdYMD4XQDgsaJqDgXCn1zQMznfItjlLD1fxKLDpn9YDEAADlAn4IyBEFWxgiF42hbskJQwwyEwPhZxgRcTD8Mk9n3VRlwlXdpMPBYjgPCwFIAJRgaYtRkNpvAAQTAaoAB8ukzA4+XYX42AAVTiSRZJ3PdpVUCkL2mWVCJfRsAGZHTIpAAFZzkom5lNUOi3hIz563AyN2Og8E4M7GEbmQ1DBIwyw7kiMgxMWHSbBy0gzH8QIQjCQr0mQABdXgTO5GB+ADKA8gKIo8AqtIojgIZSGkaUujK3osHYHAXhgJYqBWHMXwYpjSOdF9/mCy4qNufoioQIC3ldZiGyQNjo0SjseMQkAWF7RECq6h5HByAwvBMcwso29JMju/AXDcPKeFKnpOvuGJr2NZJrsB96xlawpijKH4qhqUR5gaJoWjaGAOkGno+kqwZbBGR4cgmKZNLmKdJpAabnwBO15sLRbThW8sSjBoqIaebaXx2EBorAiNA0BaqPjRPAjVvYBYl4bGboyUY9AoWJAQEdVlF4AByAABHIegAKzgAB6NBZZyVXDRvE1xakO9B1YeWwEV/hlbVrWQhNsBYlReRkjTXFeAVDoNGYSyrYA1hGAAAw9uAID2BZWAgaZGG4MOKQtyWaIsVW0DgVXbclsKYAzohLPgbUAFooDWIIc4lqXAenZAa7z7K3qN/RuApPW9d4NlS9L1MyBgRveE73gFjHmvBYV7g8lUVYkFAJN9jgbw8CzkBAUBIA=\"}\nimport {\n  transformerTwoslash,\n} from '@shikijs/twoslash'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst html = await codeToHtml(`console.log()`, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [\n    transformerTwoslash(), // <-- here\n    // ...\n  ],\n})\n```\n\nThe default output is unstyled. You need to add some extra CSS to make them look good.\n\nIf you want to run Twoslash on browsers or workers, reference to the [CDN Usage](#cdn-usage) section.\n\n## Renderers\n\nThanks to the flexibility of [`hast`](https://github.com/syntax-tree/hast), this transformer allows customizing how each piece of information is rendered in the output HTML with ASTs.\n\nWe provide two renderers built-in, and you can also create your own:\n\n---\n\n### `rendererRich`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-rich.ts)\n\n::: tip\nThis is the default renderer since v0.10.0.\n:::\n\nThis renderer provides a more explicit class name is prefixed with `twoslash-` for better scoping.\nIn addition, it runs syntax highlighting on the hover information.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"9bafe2d835b3a768cc39f5a28647084c02c621d41bbebd6324dead19238c244e\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAErsR+RhCzjJcAPyJei2fLLLVAeU0SwPfQBUA7hDisu+Q3LJkAOmHYBbLAhSNGkjTyUVfEoQKAgRBEQQAEEpNhpSMGZxElCPBV40fCzeLFJidnk4XgAjGDR0kpl+dloYKF4RFzgqzL94Ch97dkLeOAwwNGZaXnx2AHN8DgWQ/iCC/BhedjBVgro0ADpouEngpABOKlZZOcKkAEYAJipTubq8GTyTSOiOMFxEAAGKiqZikZhiMgXAC+FHQ2ABBGIUJe+yYbE4PAEwjEVgK4Osq1IfVIDicXTUGi01j0vFsBLgRJJZOcrgAkh5aBZqTZeABlWYAa3Y9OYhKCJJ8/kCwXxYsZErILIp0Vi8TwADEIWgghhsaJqQUIB0ZFlNsx+UL2HLxcSyAI1mhHKy4PgthMYHNwTyjlQTmCGIhHgBmK43O6Ie6Xahgt6B6gMplK50qq7bAHAkCg8GQ8hB4Ow+E4PCEEjkVH0dEcLh8NCJxWklOudSWbS00W25lN10c2Bc1vWbj6AXsYUdhV20hSgJBEJ1+VJxvk1yquIJEBasS6/W4yRGk0wM28C0j4U2ickh2kArdt3bGherJWOC+kD+s6IADs9zDYFuUUjaNXneRJ507ZNl1dX50yQZ4syKHN0iQQFC2oBES2RctqDRRJGFKDQyEwPhx0XZVXG5Z8Dk+YxSHbW93Bo3gAB9eGEWBmn+KBV3VRIAGFBBOCA/FyGiqh1XhYBECpNkIexeEPVR3V2V0IEEVh2lqETPC4v1TkDc4AFZf3/JAAA4XljECQGo8JoP+JBQ3gsFtShINUMwYtElLFFsMrXCMRrLSFFMSkB10fQGPCEKKO0Ic6XosIFGnGUQhs4KfioNV1xSY9WHSTJsk2NL7UKYp8KIaTSCqWp6ntUoYGaVp2k6LgemYPo4AGMAhhGMYJimGZ5kWIaVkdDYlONGh6Ffd9A3uQEjJAa4/wjJ4LNIOMPkS75VDsgFHOzFy8yeaEAF0QWgRFpVnXhgCCnb8Aoc9SNvXhoQEMphIAcgAAVdUd2AAKzgAB6J1IPwL6fB8MCLwgl01GAHxeHu0h9GKiJVEYPgQZB3gAB4AFpCZ8aFuGiPpJiQUB9lkOArDwNAEGhaEgA\"}\nimport { rendererRich, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererRich() // <--\n})\n```\n\nHere are a few examples with the built-in [`style-rich.css`](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-rich.css):\n\n<!-- eslint-skip -->\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"43c9a2581bdd8d8c26b6a00be668c361b400ca9c2034e576e137e282e9ec30ed\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808BLMG0gMwEMBjGAAgBVoESiDhoOpBogCMABioAbGGADmafEgAsVcaRUwpIQVGGLmuRPJBd8E7qyRyAvhXTYLBYmRE16eABRYpBA4khgAlAJCAHRojGhKiLxipMwqImISUtIAnIrKahqIAKw6EvqGcQm4ZmAW0lQ2dlwOiABMLm44eIQk5Dp0hlwQYGK8aEJJAEowHCZgChgAPMYQAHwZulKabfmq6lplegZ4EyYiCuaH1rak9t6IAGyd1O49Xv3Ug6fuvDNzI0WKzWvAAvLxgLxSLN5oteMgAAq8Zi8ADWMAwEDYAgAukl+IicQBuXhOEQmLgIRAgACyHHRvA4CgUvCCITIcXgyLAAihMMBGE2WS0AA49oUkGLqOUTtT/rDBbULNobs1WtIOq5Xt1qb1vAM/NTmKxODwoucqJlJEhigB2cUHRAq3QVPCrC5XJ2NW73cjtaQvTA6zx9HzfamBYKhTCRKqJZJoVKqIXWp55EBKfZFUrS46VeJKD11G3etUPTVdDwARwArmRFV9DSBI+ywrGCzAkik0impI905mJSUjq7qXGahnPTmmncWuXA29dR8w03/ABbAyEKCRADKibSsQgAFUsKEAMIcOAwfzhLv75NUClUkBnkZ9NBwRnM8b4PhMrC2AARgYjBcLwM6+p+KIcAmSYqOMEC8DWp5kFwl4wNEvaOLIViDo60gNLmo7UMeKGkBeV5FhY04+nOfoAMz0QuwZ6p8vhDCMYxnBA0z8gsyyrBslpbI40hSnhRTOjKlRCFRkqlrOrSyMxHhkMEnxWtkbT0Q62aNNAFhtMUmhWGwjCZhwG5MGAsC0LECBUIwUB4GpAC0Rkma50iaLarnFCuhgXmAkBoIycBwIwKg8hMvAAOTjrFvDAWhNZXsioWMJ+MHQnMrkCqyUYchgmH5CQCguaQ6lyYgUoQXRNoqe8oYGoYLbRhE4wdkkHBgA2mmONpuklkRsrUB21W1bRrTFI1S7NY2hhEBIvAAHI1muwGkEka0bWQr6jImNYtBAnxPngACCPIQIBABWMAtD+HChdCQTwMoH6MrwYDrZtvBYoyvVoswUDRLw53fgAUhwS07lwqRYKF327aQWXQrwjyaK5gHxLwbAKBAT1pK5WAQMaX0/WQcAlaIIkyCZQ1PCOo07Zt1VyApvpIMpWpBh4rEBQEG7qNAkQs3tnGHcdpDRFgEhXgAkiw/jdqod5wRQUJzIwtAAPxJEjm23uTyPkhAlJ4Pt76fudsFpAhAPcjQ+jSz4HAqFSyDICAst3GumxwWDtuqPbwxgO+juITBBtkJhOIUF7PuWSIdxQNrgdLQodZJQYADuMDKLwbQA1AvD0Y8j2hXAOBcIwZlcuofCAehf3Yg3xu/SiAAGKsqJ30QADpgPLrf4JljJ6Ot73Ip+IXJMhWCXDAUAaz3n45/E+Cfa9Zm0C3cWyLQiUSHwocRbA0Il7+tBzPdjBrkyA9gODLIQA3pBB+748n5xTlkEvvCwBrvfBQsc4402FHTe0GYCiOilC6UaPsFYsDZlYOqrRbSzWsBANcC8QIjCwnTcSMCiioOwbguInEkCoHAJZDwiCYAADF8ZPREKiYGeAhZblYcDGk0Ba6MEpngQBChj4ZBOmgfg4YQAERAC8MAtC8D0MVgwKgbCbIcM3NAbhNleGpzrijIR90RHQjEZISRTYZFyIUdSNkExebaOcjYwqYQHG6P4YI6kwjRGWnEeYwwliwHDBwUoChowETQh3oolBHN6o1ScIEgy1kTTcD4KsCEg9eCdWqGrNIg8nCD0HqfUK3FeIAn4isIQIJwTAAyVk+MsUAAiMAQl8GYPYRgJAkJXhRrFQ8J5zzoRvBQPJBSWAxHHGCOKAAJZp+NYqjLFtLJRStYoanorFDWchwijMybsvZ+zeAAHpDm1IOWc45IghYcCQKAQYygIr4LHAgJwTggA=\"}\n// @errors: 2540\ninterface Todo {\n  title: string\n}\n\nconst todo: Readonly<Todo> = {\n  title: 'Delete inactive users'.toUpperCase(),\n//  ^?\n}\n\ntodo.title = 'Hello'\n\nNumber.parseInt('123', 10)\n//      ^|\n\n               //\n               //\n```\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c6f2791b81c2170bb12e4d54f17b345c35c290fb6b3e803987a0875ad1778705\",\"data\":\"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\"}\nimport { createHighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nconst highlighter = await createHighlighterCore({\n  engine: createJavaScriptRegexEngine()\n})\n\n// @log: Custom log message\nconst a = 1\n// @error: Custom error message\nconst b = 1\n// @warn: Custom warning message\nconst c = 1\n// @annotate: Custom annotation message\n```\n\n---\n\n### `rendererClassic`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-classic.ts)\n\nThis renderer aligns with the output of legacy [`shiki-twoslash`](https://github.com/shikijs/twoslash).\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"be50298f5ea6976d501abea603d4b03abe8280f3bf0a7b10df97e47172449e7c\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAMKsucdiMbdEvACoB3CHBVx8AJVnyyAHTDsAtlgik00i2TLLV6yiCgQRCIggOvgwvLD8zIKsLjJy7qS8bOwA5rZgKbx67Gj4vLlhTqnsYGy8AAYAAibsANbsAFZwAPRoBkZc+OW8EIJoWH0AdD5waMzOSACcVKyyKblIAIwArFRjpCkwDEFxlkrGaiI+HGC4iAAMVCL448xiZFMAvhTo2GcExA9rdNsgLBxcPhCUTiST5UjMMBwfhOOxkfSGYz4RgQLCgqEAfm0OghUJhpDhpARHRMAEl4rQAPJoiRQrS8ADK+Dq7BxkOhsOstgcThcaFxHIJ8PaSJ8fgCeAAYnc0E4MAJhGJafkILwRDJmDQkozmfVwez8YSBE58iLOrwSjQUhD0XBhlRRuNtgAmABsMzmC0Qi2m1HGm1+/INnKJZpMxxKZ0uIGut3u5EQbuerxweEIJHI33oTGSgP1eJDxKRKJpkjgWN0AsNwsRnXJsCppbp2iZLLZBaFpBs9kcznzgsJRc6Yv8gRA0rEcoVIOVsrVGq1zB1LP71cS+NNtZMFrAVpttLtI3W2wA7AAWD0ZL0+tb+rZ4IMdwdh/AR05IZ1XG4Q+NIc7J6g3jTT5M2oH4mCwUhUTITA+HbAcaxJfBqVtQZdgSCshxMcx4gUXgAB9eGECJIygEcJSCRRBFGCA7FcXCyDgFVwhgER2FgXhCD0XgYDuPIShhXgTF6VgoF4AAjMJ0JkMiHWPKYAA5L3mV9ECUv0NnvHY3AUN8zgAZi/OMaATZ0AMwVMgnTL4wOzIJ/k4Hh6L2Tw4EOTRsRfHC9m7Hk+2kjwDm8KhxTHEIwgiKIYmchIkg4NISkybJcnyUIelIYpSlYCpql1RoWjaLcuh6PoBjQe0QEdCZvXOdTZivVSVlvTTfgC/YvCOGZIyQQyY2/GUHm9MyAF0rmgd4e15XhgBihRXMOChV0LF9eEeAQoLogByXKWSaVoX02mwbEfBDQyKxhgBsXhZrIbQ2vm9RNF4Zpml4AAeABaD6bEebgfDhMYkFAH5ZDUSQHwQR5HiAA=\"}\nimport { rendererClassic, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererClassic() // <--\n})\n```\n\nYou might need to reference `shiki-twoslash`'s CSS to make it look good. [Here](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-classic.css) we also copied the CSS from `shiki-twoslash` but it might need some cleanup.\n\n### `rendererFloatingVue`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/vitepress-twoslash/src/renderer-floating-vue.ts)\n\nThis renderer outputs Vue template syntax that using [Floating Vue](https://floating-vue.starpad.dev/) as the popup component (to render it outside the containers). This renderer is **NOT** directly usable but an internal renderer for the [VitePress integration](/packages/vitepress#twoslash). Listing it here for reference if you want to create your own renderer.\n\n## Options\n\n### Explicit Trigger\n\nWhen integrating with `@shikijs/markdown-it` or `rehype-shiki`, we may not want Twoslash to run on every code block. In this case, we can set `explicitTrigger` to `true` to only run on code blocks with `twoslash` presented in the codeframe.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c33fc7b243f56e1595f93ca6e9e052fed95abb58a9edc5376b448c62984626f1\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQATipWGDBptFzEAEZt6jXpmA3qVIH7LL08jjBcRAAGKhF8NYqaci2AL4UdDYV4EYhkPI0ehMNicHh9GyRe6OHIGLwmcyWW7IjKjZyuOieeY8fyBEJhJHpWLxRLrRFpKKZVG5KgFIp4cqVUjVISieYNJotNowDpdcm9GT9XFDUgjB45CZTGCzNreOBLKgrNYbACsAHYdnsDkdTlRVqRLtcpVSmfick9Jq8AEyfb6yMSQ95AkE4PCEEjkc10a6MLCkQxkTB8SmMlFjYnqhZ0LAcETsNBWdjTS6kLEAIwgEF2cl4AB9eAAlFUAUVoWHLvGEsH4TqgeXZxRA1YAjoJ2C04LwAAZoe34YeC/Oi8PwPY0KBK6T4UUiaCi/OsQpBXiqVaC5hYVPVQ7sIc2uNB87TYrIZD5GD8ZiCVgMKhP1hwXAAXW/WotGwABzHEa+yHEgxy6uaFxXHgKZphmWY5pCOxOkgADMbo/J6/zOgCf4gGusB4LSSS8MADJ3HiCrjACAgRsovAAOQAAI5D0ABWcAAPRjjRTGxLEF5UcyYyMMAsS8Lw8HsOmmakNmuYWDIgiitx3G8AAPAAtNpsQAtweR7swSCgCGexwN4eBoAgAIAkAA=\"}\nimport { transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  explicitTrigger: true // <--\n})\n```\n\n````md\nIn markdown, you can use the following syntax to trigger Twoslash:\n\n```ts\n// this is a normal code block\n```\n\n```ts twoslash\n// this will run Twoslash\n```\n````\n\n## Integrations\n\nWhile you can set up Twoslash with Shiki on your own with the instructions above, you can also find high-level integrations with frameworks and tools here:\n\n- [VitePress](/packages/vitepress#twoslash) - A plugin to enable Twoslash support in VitePress.\n- [Nuxt](/packages/nuxt#twoslash-integration) - A module to enable Twoslash for Nuxt Content.\n- [Vocs](https://vocs.dev/docs/guides/twoslash) - Vocs has TwoSlash support built-in.\n- [Slidev](https://sli.dev/features/twoslash#twoslash-integration) - Slidev has TwoSlash support built-in.\n\n## Recipes\n\n### CDN Usage\n\nBy default [`twoslash`](https://github.com/twoslashes/twoslash/tree/main/packages/twoslash) runs on Node.js and relies on your local system to resolve TypeScript and types for the imports. Import it directly in non-Node.js environments would not work.\n\nLuckily, Twoslash implemented a virtual file system, which allow you to provide your own files for TypeScript to resolve in memory. However, loading these files in the browser is still a challenge. Thanks to the work on the [TypeScript WebSite](https://github.com/microsoft/TypeScript-Website), the TypeScript team has provided some utilities to fetch types on demand through CDN, they call it [Automatic Type Acquisition (ATA)](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ata).\n\nWe make tiny wrappers around the building blocks and provide an easy-to-use API in [`twoslash-cdn`](https://twoslash.netlify.app/packages/cdn). For example:\n\n```js\n// FIXME: Replace with explicit versions in production\nimport { createTransformerFactory, rendererRich } from 'https://esm.sh/@shikijs/twoslash@latest/core'\nimport { codeToHtml } from 'https://esm.sh/shiki@latest'\nimport { createTwoslashFromCDN } from 'https://esm.sh/twoslash-cdn@latest'\nimport { createStorage } from 'https://esm.sh/unstorage@latest'\nimport indexedDbDriver from 'https://esm.sh/unstorage@latest/drivers/indexedb'\n\n// ============= Initialization =============\n\n// An example using unstorage with IndexedDB to cache the virtual file system\nconst storage = createStorage({\n  driver: indexedDbDriver({ base: 'twoslash-cdn' }),\n})\n\nconst twoslash = createTwoslashFromCDN({\n  storage,\n  compilerOptions: {\n    lib: ['esnext', 'dom'],\n  },\n})\n\nconst transformerTwoslash = createTransformerFactory(twoslash.runSync)({\n  renderer: rendererRich(),\n})\n\n// ============= Execution =============\n\nconst app = document.getElementById('app')\n\nconst source = `\nimport { ref } from 'vue'\n\nconsole.log(\"Hi! Shiki + Twoslash on CDN :)\")\n\nconst count = ref(0)\n//     ^?\n`.trim()\n\n// Before rendering, we need to prepare the types, so that the rendering can happen synchronously\nawait twoslash.prepareTypes(source)\n\n// Then we can render the code\napp.innerHTML = await codeToHtml(source, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [transformerTwoslash],\n})\n```\n","docs/packages/vitepress.md":"---\noutline: deep\n---\n\n# VitePress Integration\n\n[VitePress](https://vitepress.dev/) uses Shiki under the hood, so you don't need explicit integration.\n\nVitePress provides [a few options for customizing Shiki](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts#L66-L112). Learn more about them in the [VitePress documentation](https://vitepress.dev/reference/site-config#markdown).\n\n## Twoslash\n\nTo enable [TypeScript Twoslash](/packages/twoslash) (type hover on code snippets) in VitePress, we provide a VitePress plugin for easy setup. Pre-styled, with [Floating Vue](https://floating-vue.starpad.dev/) to display the type information out side of the code container.\n\n<Badges name=\"@shikijs/vitepress-twoslash\" />\n\n### Setup\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/vitepress-twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/vitepress-twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/vitepress-twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/vitepress-twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/vitepress-twoslash\n```\n\n:::\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash() // [!code hl]\n    ],\n    // [!code hl:2]\n    // Explicitly load these languages for types highlighting\n    languages: ['js', 'jsx', 'ts', 'tsx']\n  }\n})\n```\n\nAnd then in your [`.vitepress/theme/index.ts`](https://vitepress.dev/guide/custom-theme), install the Vue plugin and import the css with `@shikijs/vitepress-twoslash/styles.css`.\n\n```ts twoslash [.vitepress/theme/index.ts]\n// @twoslash-cache: {\"v\":1,\"hash\":\"2a5df659524ba4854bc92abbfbd15feefdb74ba936c5a020d6bdc7d308b959b2\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAJ2wNUgDNmAYxi8AomHzMwEgIJYsAYQiC6aADph2AWywRSaabPlKV6zfUog4aZiaQBGACxVWMMAHM0+VwB2KkdSHxgGRBAZOQUYZTUNGltPAVxEAAYqMTlScSFXNwBfCnRsdIJiMjtkyJAWDi4+MQ0HXgAVAHcIOFYufAAxVghmNAEfADUAVxhEXmBdXiX+MAc2VjmWFTmEil4ILDHWgH45oZGx32mYa2F2Hz4AXgA+XiIIdigAbl0i3QMjCYOt1ev1zqNxtc7FAIGIEFFrrwsKwpj4BLw0BAVmtWKxeODLpMZrxOux/LwHBgvHAAHS6XQASUMxlM/nYcF4wimCiOYBWvAABjSiGSYFhSPA4AB6fwwfQwKUCWC0GloOAC3jyKC8KZwSQC5gqGm6mCMLo9PpwQbDCFXGbcDUCOCfSSywXeWKWLAawgQADWNLsa2ciAArAAOTzePwBRAuACcISc4Tq5tBVoJkJmdg4YHSLmyuXy1UQgRKZRweEIJHIIS0TDYnB4vBaq1M7Xwctm80WywAMswMBApmg5gARGB3PPqZl5wQ/PnLD0WeLbXiMMRoWhzGIrhLWWpPV7vT4Lv56ZlAjtdoOhSLuAsgLy+fxIUNJsIRPDX+U5tJIAAmQsnGLchS3LahyirKpa2oesokYcUDjITA+C0bwoDgOYFkXJYByHEdx0nNIZyMOc0AXZZeGXOIEk2TdtzMT1V0SGw0CPN4Pm+X5bycSIANDICn2jV9Sw/FM8HQsBML/PMkGCEAchAzcSwAiDMErKJq2qOtbAQxsmhbVp207eVsN7PDB2HUdeAnKcbggWdvAoizqPMWi1w3Lcd3cr0Dy0DiT24sBzwBFkOlM3AqGDfiADZH2fGM33Er8oh/KKn3/MTFKLFSwJcFx1KgrSYJqeD6nlfxoDQ3yWMYYBNRUXgih85j9ySAK5iC3iQwAwIsmEl9YxcAbQgkqIaK9WT0kjHLlIKRA1NKSDNMqGsyr0+osBAyqyD4Q0sB2FQAB55AwZ4ev48MAGYoyGpBbuoZNUpAA7pqQWalLyPLXFDIrVu02DagbRpmwEIRRAkJi9ysDr6H+S9TF3DzWOB6K70A+MBsS0SXAUsaXuRvy4YYVI5MQT7coWgClorCpAY2upEJ2iI9saw7eASU6wHOy6Hpcd9BqSxBHoJuo3rJ9JEzm76FuKZaNPp0rdKZyrCCgPgubO55jT1Y7kAOXk4FOTUeYAXWeRCUTRMA5gABWtgR9cN9gTjmM6zb2A3Dld1YTY9549hpYOXdaOYADkIAZMBhDIZ2fbd02MAt7gjqwbnzvXABqFx9hrG0Nb5kWEzu4XReeuoTXexBpa+0CPv+pX1pVkGm2aYzgQtMEbUJa5zNw7FHFxTYDrTvZQ79s4e6zByY/uQKuLPBHAXbEFLWtC4Z+hWF4RARFkVRdFMUH9Z8Wnu1JFJclKWpOkwEZRGMXwdlOW5Tdff5IURRocVJRlSLFTSToKqdUpttQmkFAdXWpo0zr0zBfB02IXRP31JNFiPoID+kDOjPiD0AKPRxsNaWYtvxr27pvC+1da5UxLC4NSntFLQAqGFIEit5jQxRv5egzVOSkEcrwAA5N/MUEo4BwAEcvcKsDyG2iJJIYQfD9CCIAAJWnYH6dgAAraUwjf5iIALRoDIVaKUYgODOQEbwKUUpeDIAAIQtFgLwfArAzaSKvJFXh/ChGij0dKWU8oJH3wvCvFRaiNHaKlLo0RcBDHGPwFKG+MAaRwnEVYmx9jHGSBcW44JdBQmwFEFMVgpgcJLCkphOY6UKC9jQQkeq7NmqtRhqjAKPYB5QJNGaeJ8C5F8GsbYhxTDnGuN7CUHiVBKrMCQKAKSzoNB4DVCAIoRQgA=\"}\n// @noErrors: true\nimport type { EnhanceAppContext } from 'vitepress'\nimport TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' // [!code hl]\nimport Theme from 'vitepress/theme'\n\nimport '@shikijs/vitepress-twoslash/style.css' // [!code hl]\n\nexport default {\n  extends: Theme,\n  enhanceApp({ app }: EnhanceAppContext) {\n    app.use(TwoslashFloatingVue) // [!code hl]\n  },\n}\n```\n\n::: details About style.css\n\nFor easier setup, `@shikijs/vitepress-twoslash/styles.css` bundles the styles from `floating-vue` and `@shikijs/twoslash/style-rich.css` so you only need a single entry. If you are using a custom `floating-vue` style or want to have more control of the styles, you can expand them as:\n\n```ts\nimport '@shikijs/vitepress-twoslash/style.css'\n\n// Equivalent to:\nimport '@shikijs/twoslash/style-rich.css'\nimport 'floating-vue/dist/style.css'\nimport '@shikijs/vitepress-twoslash/style-core.css'\n```\n\n:::\n\nThat's it, you can now use `ts twoslash` in your markdown files to enable the beautiful type hover.\n\n````md\n```ts twoslash\nconsole.log('hello')\n//      ^?\n```\n````\n\nIt will be rendered as:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"258fd8e6b019224fc5515598774b6ccef0d85eefda3a3ba0992cbaa911ba9952\",\"data\":\"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\"}\nconsole.log('hello')\n//      ^?\n```\n\n<div class=\"h-100\" /> <!-- leaving some space for the query above -->\n\n### Vue Single File Component\n\nIn addition, this plugin also integrated [`twoslash-vue`](https://twoslash.netlify.app/packages/vue) for you, so that you can also highlight Vue SFC blocks with `vue twoslash`:\n\n```vue twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"e44d27459becb1dd99d3f24e24e643e1cd8fe190f90d461e4713e08207fe0a39\",\"data\":\"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\"}\n<script setup>\nimport { onMounted, ref } from 'vue'\n\n// reactive state\nconst count = ref(0)\n//             ^?\n\n// functions that mutate state and trigger updates\nfunction increment() {\n  count.value++\n}\n\n// lifecycle hooks\nonMounted(() => {\n  console.log(`The initial count is ${count.value}.`)\n})\n</script>\n\n<template>\n  <button @click=\"increment\">\n    Count is: {{ count }}\n  </button>\n</template>\n```\n\n### File System Cache\n\nTo speed up the build process, you can enable the file system cache for the generated types, that shares across multiple builds. By default the cache is stored in the `.vitepress/cache/twoslash` along with other VitePress caches.\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash'\nimport { createFileSystemTypesCache } from '@shikijs/vitepress-twoslash/cache-fs' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash({\n        typesCache: createFileSystemTypesCache() // [!code hl]\n      })\n    ]\n  }\n})\n```\n\n### Inline Cache (experimental)\n\nYou can enable inline caching for the generated types. The `@twoslash-cache: ...` will auto insert into your fenced code block during development and build time.\n\n````md [./your-file.md]{2}\n```ts twoslash\n// @twoslash-cache: [auto generated]\nconst a: string = 'foo'\n```\n````\n\nTo enable the inline cache in your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config), please use the config wrapper created by `createTwoslashWithInlineCache`.\n\n```ts [.vitepress/config.ts]\nimport { createTwoslashWithInlineCache } from '@shikijs/vitepress-twoslash/cache-inline' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nconst withTwoslashInlineCache = createTwoslashWithInlineCache({ // [!code hl]\n  // ... config of transformerTwoslash // [!code hl]\n}) // [!code hl]\n\nexport default withTwoslashInlineCache( // [!code hl]\n  defineConfig({\n    markdown: {\n      codeTransformers: [\n        // move config to the `createTwoslashWithInlineCache()` // [!code error]\n        // transformerTwoslash({ ... }) // [!code error]\n      ]\n    }\n  })\n) // [!code hl]\n```\n\n#### Force re-generate inline cache\n\nTo force re-generate the inline cache and ignore the existing cache, you can use the `TWOSLASH_INLINE_CACHE_IGNORE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress build\n```\n\n#### Remove inline cache\n\nTo remove all inline cache, you can use the `TWOSLASH_INLINE_CACHE_REMOVE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress build\n```\n","docs/references/engine-js-compat.md":"# JavaScript RegExp Engine Compatibility References\n\nCompatibility reference of all built-in grammars with the [JavaScript RegExp engine](/guide/regex-engines#javascript-regexp-engine).\n\n> Generated on Friday, September 11, 2026\n>\n> Version `4.4.3`\n>\n> Runtime: Node.js v24.16.0\n\n## Report Summary\n\n|                 |                       Count |\n| :-------------- | --------------------------: |\n| Total Languages |                         238 |\n| Supported       | [237](#supported-languages) |\n| Mismatched      |  [0](#mismatched-languages) |\n| Unsupported     | [1](#unsupported-languages) |\n\n## Supported Languages\n\nLanguages that work with the JavaScript RegExp engine, and will produce the same result as the WASM engine (with the [sample snippets in the registry](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples)).\nIn some edge cases, it's not guaranteed that the highlighting will be 100% the same. If that happens, please create an issue with the sample snippet.\n\n| Language           | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| ------------------ | :-------------- | ----------------: | --------------: | ---: |\n| abap               | ✅ OK           |                52 |               - |      |\n| actionscript-3     | ✅ OK           |                59 |               - |      |\n| ada                | ✅ OK           |               200 |               - |      |\n| ahk                | ✅ OK           |               125 |               - |      |\n| angular-html       | ✅ OK           |               669 |               - |      |\n| angular-ts         | ✅ OK           |               776 |               - |      |\n| apache             | ✅ OK           |                60 |               - |      |\n| apex               | ✅ OK           |               197 |               - |      |\n| apl                | ✅ OK           |               912 |               - |      |\n| applescript        | ✅ OK           |               152 |               - |      |\n| ara                | ✅ OK           |                54 |               - |      |\n| asciidoc           | ✅ OK           |               319 |               - |      |\n| asm                | ✅ OK           |               298 |               - |      |\n| astro              | ✅ OK           |               610 |               - |      |\n| awk                | ✅ OK           |                36 |               - |      |\n| ballerina          | ✅ OK           |               224 |               - |      |\n| bat                | ✅ OK           |                58 |               - |      |\n| beancount          | ✅ OK           |                42 |               - |      |\n| berry              | ✅ OK           |                21 |               - |      |\n| bibtex             | ✅ OK           |                19 |               - |      |\n| bicep              | ✅ OK           |                31 |               - |      |\n| bird2              | ✅ OK           |               146 |               - |      |\n| blade              | ✅ OK           |              1122 |               - |      |\n| bsl                | ✅ OK           |                97 |               - |      |\n| c                  | ✅ OK           |               176 |               - |      |\n| c3                 | ✅ OK           |               125 |               - |      |\n| cadence            | ✅ OK           |               128 |               - |      |\n| cairo              | ✅ OK           |               236 |               - |      |\n| chapel             | ✅ OK           |               214 |               - |      |\n| clarity            | ✅ OK           |                42 |               - |      |\n| clojure            | ✅ OK           |                38 |               - |      |\n| cmake              | ✅ OK           |                23 |               - |      |\n| cobol              | ✅ OK           |               858 |               - |      |\n| codeowners         | ✅ OK           |                 4 |               - |      |\n| codeql             | ✅ OK           |               147 |               - |      |\n| coffee             | ✅ OK           |               466 |               - |      |\n| common-lisp        | ✅ OK           |                60 |               - |      |\n| coq                | ✅ OK           |                28 |               - |      |\n| cpp                | ✅ OK           |               468 |               - |      |\n| crystal            | ✅ OK           |              1054 |               - |      |\n| csharp             | ✅ OK           |               315 |               - |      |\n| css                | ✅ OK           |               141 |               - |      |\n| csv                | ✅ OK           |                 1 |               - |      |\n| cue                | ✅ OK           |                85 |               - |      |\n| cypher             | ✅ OK           |                39 |               - |      |\n| d                  | ✅ OK           |               272 |               - |      |\n| dart               | ✅ OK           |                79 |               - |      |\n| dax                | ✅ OK           |                23 |               - |      |\n| desktop            | ✅ OK           |                16 |               - |      |\n| diff               | ✅ OK           |                16 |               - |      |\n| docker             | ✅ OK           |                 7 |               - |      |\n| dotenv             | ✅ OK           |                 9 |               - |      |\n| dream-maker        | ✅ OK           |                56 |               - |      |\n| edge               | ✅ OK           |               629 |               - |      |\n| elixir             | ✅ OK           |               704 |               - |      |\n| elm                | ✅ OK           |               241 |               - |      |\n| emacs-lisp         | ✅ OK           |               155 |               - |   22 |\n| erb                | ✅ OK           |              1816 |               - |      |\n| erlang             | ✅ OK           |               270 |               - |      |\n| fennel             | ✅ OK           |                31 |               - |      |\n| fish               | ✅ OK           |                34 |               - |      |\n| fluent             | ✅ OK           |                23 |               - |      |\n| fortran-fixed-form | ✅ OK           |               346 |               - |      |\n| fortran-free-form  | ✅ OK           |               339 |               - |      |\n| fsharp             | ✅ OK           |               242 |               - |      |\n| gdresource         | ✅ OK           |               157 |               - |      |\n| gdscript           | ✅ OK           |                94 |               - |      |\n| gdshader           | ✅ OK           |                39 |               - |      |\n| genie              | ✅ OK           |                20 |               - |      |\n| gherkin            | ✅ OK           |                19 |               - |      |\n| gleam              | ✅ OK           |                26 |               - |      |\n| glimmer-js         | ✅ OK           |               673 |               - |      |\n| glimmer-ts         | ✅ OK           |               673 |               - |      |\n| glsl               | ✅ OK           |               185 |               - |      |\n| gn                 | ✅ OK           |                19 |               - |      |\n| gnuplot            | ✅ OK           |                82 |               - |      |\n| go                 | ✅ OK           |               126 |               - |      |\n| graphql            | ✅ OK           |               445 |               - |      |\n| groovy             | ✅ OK           |               130 |               - |      |\n| hack               | ✅ OK           |               946 |               - |      |\n| haml               | ✅ OK           |               559 |               - |      |\n| handlebars         | ✅ OK           |               696 |               - |      |\n| haskell            | ✅ OK           |               157 |               - |      |\n| haxe               | ✅ OK           |               173 |               - |      |\n| hcl                | ✅ OK           |                67 |               - |      |\n| hjson              | ✅ OK           |                57 |               - |      |\n| hlsl               | ✅ OK           |                52 |               - |      |\n| html               | ✅ OK           |               608 |               - |      |\n| http               | ✅ OK           |               746 |               - |      |\n| hurl               | ✅ OK           |               611 |               - |      |\n| hxml               | ✅ OK           |               182 |               - |      |\n| hy                 | ✅ OK           |                12 |               - |      |\n| imba               | ✅ OK           |               239 |               - |      |\n| ini                | ✅ OK           |                11 |               - |      |\n| java               | ✅ OK           |               141 |               - |      |\n| javascript         | ✅ OK           |               375 |               - |      |\n| jinja              | ✅ OK           |               639 |               - |      |\n| jison              | ✅ OK           |               431 |               - |      |\n| json               | ✅ OK           |                19 |               - |      |\n| json5              | ✅ OK           |                23 |               - |      |\n| jsonc              | ✅ OK           |                19 |               - |      |\n| jsonl              | ✅ OK           |                19 |               - |      |\n| jsonnet            | ✅ OK           |                33 |               - |      |\n| jssm               | ✅ OK           |                30 |               - |      |\n| jsx                | ✅ OK           |               375 |               - |      |\n| julia              | ✅ OK           |              1177 |               - |      |\n| just               | ✅ OK           |              2148 |               - |      |\n| kdl                | ✅ OK           |                30 |               - |      |\n| kotlin             | ✅ OK           |                58 |               - |      |\n| kusto              | ✅ OK           |                60 |               - |      |\n| latex              | ✅ OK           |               312 |               - |      |\n| lean               | ✅ OK           |                31 |               - |      |\n| less               | ✅ OK           |               279 |               - |      |\n| liquid             | ✅ OK           |               689 |               - |      |\n| llvm               | ✅ OK           |                25 |               - |      |\n| log                | ✅ OK           |                31 |               - |      |\n| logo               | ✅ OK           |                 9 |               - |      |\n| lua                | ✅ OK           |               279 |               - |      |\n| luau               | ✅ OK           |                95 |               - |      |\n| make               | ✅ OK           |                51 |               - |      |\n| markdown           | ✅ OK           |               123 |               - |      |\n| marko              | ✅ OK           |               929 |               - |      |\n| matlab             | ✅ OK           |                88 |               - |      |\n| mdc                | ✅ OK           |               786 |               - |      |\n| mdx                | ✅ OK           |               197 |               - |      |\n| mermaid            | ✅ OK           |               175 |               - |      |\n| mipsasm            | ✅ OK           |                17 |               - |      |\n| mojo               | ✅ OK           |               215 |               - |      |\n| moonbit            | ✅ OK           |               101 |               - |      |\n| move               | ✅ OK           |               113 |               - |      |\n| narrat             | ✅ OK           |                34 |               - |      |\n| nextflow           | ✅ OK           |               107 |               - |      |\n| nginx              | ✅ OK           |               378 |               - |      |\n| nim                | ✅ OK           |              1122 |               - |      |\n| nix                | ✅ OK           |                83 |               - |      |\n| nsis               | ✅ OK           |                38 |               - |      |\n| nushell            | ✅ OK           |                85 |               - |      |\n| objective-c        | ✅ OK           |               222 |               - |      |\n| objective-cpp      | ✅ OK           |               306 |               - |      |\n| ocaml              | ✅ OK           |               178 |               - |      |\n| odin               | ✅ OK           |                98 |               - |      |\n| openscad           | ✅ OK           |                24 |               - |      |\n| org                | ✅ OK           |              4715 |               - |      |\n| pascal             | ✅ OK           |                23 |               - |      |\n| perl               | ✅ OK           |               937 |               - |      |\n| php                | ✅ OK           |              1125 |               - |      |\n| pkl                | ✅ OK           |                67 |               - |      |\n| plsql              | ✅ OK           |                45 |               - |      |\n| po                 | ✅ OK           |                23 |               - |      |\n| polar              | ✅ OK           |                31 |               - |      |\n| postcss            | ✅ OK           |                49 |               - |      |\n| powerquery         | ✅ OK           |                30 |               - |      |\n| powershell         | ✅ OK           |                88 |               - |      |\n| prisma             | ✅ OK           |                31 |               - |      |\n| prolog             | ✅ OK           |                26 |               - |      |\n| proto              | ✅ OK           |                33 |               - |      |\n| pug                | ✅ OK           |               683 |               - |      |\n| puppet             | ✅ OK           |                60 |               - |      |\n| purescript         | ✅ OK           |                87 |               - |      |\n| python             | ✅ OK           |               218 |               - |      |\n| qml                | ✅ OK           |               407 |               - |      |\n| qmldir             | ✅ OK           |                 7 |               - |      |\n| qss                | ✅ OK           |                31 |               - |      |\n| r                  | ✅ OK           |                66 |               - |      |\n| racket             | ✅ OK           |                69 |               - |      |\n| raku               | ✅ OK           |                52 |               - |      |\n| razor              | ✅ OK           |               960 |               - |      |\n| rbs                | ✅ OK           |                33 |               - |      |\n| reg                | ✅ OK           |                 9 |               - |      |\n| regexp             | ✅ OK           |                34 |               - |      |\n| rel                | ✅ OK           |                17 |               - |      |\n| riscv              | ✅ OK           |                36 |               - |      |\n| ron                | ✅ OK           |                35 |               - |      |\n| rosmsg             | ✅ OK           |                31 |               - |      |\n| rst                | ✅ OK           |              2057 |               - |      |\n| ruby               | ✅ OK           |              1808 |               - |      |\n| rust               | ✅ OK           |                89 |               - |      |\n| sas                | ✅ OK           |               100 |               - |      |\n| sass               | ✅ OK           |                69 |               - |      |\n| scala              | ✅ OK           |               116 |               - |      |\n| scheme             | ✅ OK           |                34 |               - |      |\n| scss               | ✅ OK           |               233 |               - |      |\n| sdbl               | ✅ OK           |                23 |               - |      |\n| shaderlab          | ✅ OK           |                87 |               - |      |\n| shellscript        | ✅ OK           |               147 |               - |      |\n| shellsession       | ✅ OK           |               149 |               - |      |\n| smalltalk          | ✅ OK           |                64 |               - |      |\n| smithy             | ✅ OK           |                42 |               - |      |\n| solidity           | ✅ OK           |               105 |               - |      |\n| soy                | ✅ OK           |               646 |               - |      |\n| sparql             | ✅ OK           |                19 |               - |      |\n| splunk             | ✅ OK           |                17 |               - |      |\n| sql                | ✅ OK           |                68 |               - |      |\n| ssh-config         | ✅ OK           |                12 |               - |      |\n| stata              | ✅ OK           |               254 |               - |      |\n| stylus             | ✅ OK           |               106 |               - |      |\n| surrealql          | ✅ OK           |               467 |               - |      |\n| svelte             | ✅ OK           |               646 |               - |      |\n| swift              | ✅ OK           |               340 |               - |      |\n| system-verilog     | ✅ OK           |               102 |               - |      |\n| systemd            | ✅ OK           |                32 |               - |      |\n| talonscript        | ✅ OK           |                46 |               - |      |\n| tasl               | ✅ OK           |                23 |               - |      |\n| tcl                | ✅ OK           |                34 |               - |      |\n| templ              | ✅ OK           |               674 |               - |      |\n| terraform          | ✅ OK           |                68 |               - |      |\n| tex                | ✅ OK           |               103 |               - |      |\n| toml               | ✅ OK           |                44 |               - |      |\n| ts-tags            | ✅ OK           |               997 |               - |      |\n| tsv                | ✅ OK           |                 1 |               - |      |\n| tsx                | ✅ OK           |               375 |               - |      |\n| turtle             | ✅ OK           |                15 |               - |      |\n| twig               | ✅ OK           |              2445 |               - |      |\n| typescript         | ✅ OK           |               362 |               - |      |\n| typespec           | ✅ OK           |                73 |               - |      |\n| typst              | ✅ OK           |              5699 |               - |      |\n| v                  | ✅ OK           |                77 |               - |      |\n| vala               | ✅ OK           |                20 |               - |      |\n| vb                 | ✅ OK           |                34 |               - |      |\n| verilog            | ✅ OK           |                34 |               - |      |\n| vhdl               | ✅ OK           |                82 |               - |      |\n| viml               | ✅ OK           |                72 |               - |      |\n| vue                | ✅ OK           |               705 |               - |      |\n| vue-html           | ✅ OK           |               404 |               - |      |\n| vue-vine           | ✅ OK           |              1032 |               - |      |\n| vyper              | ✅ OK           |               238 |               - |      |\n| wasm               | ✅ OK           |                78 |               - |      |\n| wenyan             | ✅ OK           |                18 |               - |      |\n| wgsl               | ✅ OK           |                44 |               - |      |\n| wikitext           | ✅ OK           |               105 |               - |      |\n| wit                | ✅ OK           |                81 |               - |      |\n| wolfram            | ✅ OK           |               501 |               - |      |\n| xml                | ✅ OK           |               168 |               - |      |\n| xsl                | ✅ OK           |               170 |               - |      |\n| yaml               | ✅ OK           |                48 |               - |      |\n| zenscript          | ✅ OK           |                21 |               - |      |\n| zig                | ✅ OK           |                51 |               - |      |\n\n###### Table Field Explanations\n\n- **Highlight Match**: Whether the highlighting results matched with the WASM engine for the [sample snippet](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples).\n- **Patterns Parsable**: Number of regex patterns that can be parsed by the JavaScript RegExp engine.\n- **Patterns Failed**: Number of regex patterns that can't be parsed by the JavaScript RegExp engine (throws error).\n- **Diff**: Length of characters that are different between the highlighting results of the two engines.\n\n## Mismatched Languages\n\nLanguages that do not throw with the JavaScript RegExp engine, but will produce different results than the WASM engine.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n\n## Unsupported Languages\n\nLanguages that throw with the JavaScript RegExp engine, either because they contain syntax we can't polyfill yet or because the grammar contains an invalid Oniguruma regex (that would also fail when using the WASM engine, but silently). You can try these languages with the `forgiving` option to skip errors.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n| ahk2     | ❌ Error        |               188 |               1 |   16 |\n","packages/cli/README.md":"# shiki-cli\n\nShiki in the command line.\n\n[Documentation](https://shiki.style/packages/cli)\n\n## License\n\nMIT\n","packages/codegen/README.md":"# @shikijs/codegen\n\nCodegen for fine-grained Shiki bundles.\n\n[Documentation](https://shiki.style/packages/codegen)\n\n## License\n\nMIT\n","packages/colorized-brackets/README.md":"# @shikijs/colorized-brackets\n\nVSCode-style colorized brackets transformer for [Shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/colorized-brackets)\n\n## License\n\nMIT\n","packages/core/README.md":"# @shikijs/core\n\nThe core functionality of [Shiki](https://github.com/shikijs/shiki), without any grammar of themes bundled.\n\nIt's the same as importing `shiki/core`.\n","packages/engine-javascript/README.md":"# @shikijs/engine-javascript\n\nEngine for Shiki using JavaScript's native RegExp. Uses [Oniguruma-To-ES](https://github.com/slevithan/oniguruma-to-es) to transpile regex syntax and behavior.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n","packages/engine-oniguruma/README.md":"# @shikijs/engine-oniguruma\n\nEngine for Shiki using Oniguruma RegExp engine in WebAssembly.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n","packages/langs-precompiled/README.md":"# @shikijs/langs-precompiled\n\nPrecompiled languages for Shiki that can runs in pure JavaScript environment.\n\nRequires ES2024+ environment.\n\n> **Experimental**\n\n## Unsupported Languages\n\n<!-- TODOs -->\n\n## License\n\nMIT\n","packages/langs/README.md":"# @shikijs/langs\n\nTextMate grammars for Shiki.\n\n## License\n\nMIT\n","packages/magic-move/README.md":"# @shikijs/magic-move\n\nSmoothly animated code blocks with [shiki](https://github.com/shikijs/shiki). Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n[Documentation](https://shiki.style/packages/magic-move)\n\n## License\n\nMIT\n","packages/markdown-exit/README.md":"# @shikijs/markdown-exit\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-exit)\n\n## License\n\nMIT\n","packages/markdown-it/README.md":"# @shikijs/markdown-it\n\n[markdown-it](https://markdown-it.github.io/) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-it)\n\n## License\n\nMIT\n","packages/monaco/README.md":"# @shikijs/monaco\n\nUse [shiki](https://github.com/shikijs/shiki) to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\n[Documentation](https://shiki.style/packages/monaco)\n\n## License\n\nMIT\n","packages/rehype/README.md":"# rehype-shiki\n\n[rehype](https://github.com/rehypejs/rehype) plugin for [shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/rehype)\n\n## License\n\nMIT\n","packages/shiki/README.md":"<img src=\"https://raw.githubusercontent.com/shikijs/shiki/main/docs/public/logo.svg\" width=\"150\" alt=\"Shiki Logo\" />\n\n# Shiki 式\n\n[![NPM version](https://img.shields.io/npm/v/shiki?color=32A9C3&labelColor=1B3C4A&label=npm)](https://www.npmjs.com/package/shiki)\n[![NPM downloads](https://img.shields.io/npm/dm/shiki?color=32A9C3&labelColor=1B3C4A&label=downloads)](https://www.npmjs.com/package/shiki)\n[![Codecov](https://img.shields.io/codecov/c/github/shikijs/shiki?token=B85J0E2I7I&style=flat&labelColor=1B3C4A&color=32A9C3&precision=1)](https://app.codecov.io/gh/shikijs/shiki)\n\nA beautiful syntax highlighter based on TextMate grammars, accurate and powerful.\n\n[📚 **Documentation**](https://shiki.style)\n\n## License\n\n[MIT](./LICENSE)\n","packages/stream/README.md":"# @shikijs/stream\n\nStreaming colorization for [shiki](https://github.com/shikijs/shiki). Useful for highlighting text streams like LLM outputs.\n\n[Documentation](https://shiki.style/packages/stream)\n\n## License\n\nMIT\n","packages/themes/README.md":"# @shikijs/themes\n\nTextMate themes for Shiki.\n\n## License\n\nMIT\n","packages/transformers/README.md":"# @shikijs/transformers\n\nCommon transformers for [shiki](https://github.com/shikijs/shiki), inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n[Documentation](https://shiki.style/packages/transformers)\n\n## License\n\nMIT\n","packages/twoslash/README.md":"# @shikijs/twoslash\n\nA [shiki](https://github.com/shikijs/shiki) transformer for [TypeScript Twoslash](https://www.typescriptlang.org/dev/twoslash/).\n\n[Documentations](https://shiki.style/packages/twoslash)\n\n## License\n\nMIT\n","packages/types/README.md":"# @shikijs/types\n\nTypes for Shiki.\n\n## License\n\nMIT\n","packages/vitepress-twoslash/README.md":"# @shikijs/vitepress-twoslash\n\nEnable Twoslash support in VitePress.\n\n[Documentation](https://shiki.style/packages/vitepress#twoslash)\n\n## License\n\nMIT\n"},"items":[{"name":"astro.md","path":"docs/packages/astro.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/astro.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# Astro Integration\n\nYou don't need explicit integration in [Astro](https://astro.build/) as Astro already uses Shiki under the hood.\n\nLearn more about the configurations in the [Astro documentation](https://docs.astro.build/en/guides/syntax-highlighting/).\n","isInternal":false,"tokens":58,"sizeBytes":258},{"name":"cli.md","path":"docs/packages/cli.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/cli.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# @shikijs/cli\n\n<Badges name=\"@shikijs/cli\" />\n\nShiki in the command line.\n\n## Usage\n\nThe Shiki CLI works like `cat` command, but with syntax highlighting.\nIt also supports remote files.\n\n```bash\nnpx @shikijs/cli README.md\n```\n\n```bash\nnpx @shikijs/cli \\\n  'https://github.com/shikijs/shiki/blob/main/taze.config.ts?raw=true'\n```\n\n## Install\n\nYou can also install it globally. Command aliases `@shikijs/cli`, `shiki`, `skat` are registered.\n\n::: code-group\n\n```sh [npm]\nnpm i -g @shikijs/cli\n```\n\n```sh [yarn]\nyarn global add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add -g @shikijs/cli\n```\n\n```sh [bun]\nbun add -g @shikijs/cli\n```\n\n```sh [deno]\ndeno install -gREn skat npm:@shikijs/cli\n```\n\n:::\n\n```sh\nskat src/index.ts\n```\n\n## Options\n\n### `--theme`\n\nSpecify the theme to use. Defaults to `vitesse-dark`.\n\n```bash\nnpx @shikijs/cli README.md --theme=nord\n```\n\n### `--lang`\n\nLanguage is auto-inferred from the file extension. You can override it with `--lang`.\n\n```bash\nnpx @shikijs/cli src/index.js --lang=ts\n```\n\n### `--format`\n\nSpecify the output format. Defaults to `ansi`.\nSupported values: `ansi`, `html`.\n\n```bash\nnpx @shikijs/cli README.md --format=html\n```\n\n## Node.js API\n\nThe `@shikijs/cli` package also provides a Node.js API.\n\n::: code-group\n\n```sh [npm]\nnpm i @shikijs/cli\n```\n\n```sh [yarn]\nyarn add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add @shikijs/cli\n```\n\n```sh [bun]\nbun add @shikijs/cli\n```\n\n```sh [deno]\ndeno add npm:@shikijs/cli\n```\n\n:::\n\n### `codeToANSI`\n\nThe asynchronous `codeToANSI` function allows you to convert code to ANSI escape codes for terminal output.\nThis is useful for rendering syntax-highlighted code in the terminal.\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord')\n\nconsole.log(highlighted)\n```\n\n`codeToANSI` takes three required parameters:\n\n1. `code: string`\n2. `lang: BundledLanguage`\n3. `theme: BundledTheme`\n\nand one optional parameter:\n\n4. `options?: CodeToANSIOptions`\n\nThe color level of the emitted escape codes is explicit instead of being inferred from the environment, and defaults to `3` (truecolor). Use `options.colorLevel` to target a different level — pass the level reported by `ansis` to follow the current terminal, or `0` to get plain text:\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\nimport ansis from 'ansis'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord', {\n  colorLevel: ansis.level,\n})\n```\n","isInternal":false,"tokens":737,"sizeBytes":2445},{"name":"codegen.md","path":"docs/packages/codegen.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/codegen.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# shiki-codegen\n\n<Badges name=\"shiki-codegen\" />\n\nCodegen for Shiki to create optimized bundles dedicated for your usage.\n\n## Usage\n\n### CLI\n\n```bash\nnpx shiki-codegen \\\n  --langs typescript,javascript,vue \\\n  --themes light-plus,dark-plus \\\n  --engine javascript \\\n  ./shiki.bundle.ts\n```\n\nFile `shiki.bundle.ts` will be created with the code that you can use in your project.\n\nThen you can use it in your project:\n\n```ts\nimport { codeToHtml } from './shiki.bundle'\n\nconst html = await codeToHtml(code, { lang: 'typescript', theme: 'light-plus' })\n```\n\n### Programmatic\n\nYou can also use `shiki-codegen` programmatically, and write the generated code to a file:\n\n```ts\nimport { codegen } from 'shiki-codegen'\n\nconst { code } = await codegen({\n  langs: ['typescript', 'javascript', 'vue'],\n  themes: ['light-plus', 'dark-plus'],\n  engine: 'javascript',\n  typescript: true\n})\n\n// Write the code to a file\n```\n","isInternal":false,"tokens":245,"sizeBytes":908},{"name":"colorized-brackets.md","path":"docs/packages/colorized-brackets.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/colorized-brackets.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# @shikijs/colorized-brackets\n\n<Badges name=\"@shikijs/colorized-brackets\" />\n\nVSCode-style colorized brackets transformer for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/colorized-brackets\n```\n\n```sh [yarn]\nyarn add -D @shikijs/colorized-brackets\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/colorized-brackets\n```\n\n```sh [bun]\nbun add -D @shikijs/colorized-brackets\n```\n\n```sh [deno]\ndeno add npm:@shikijs/colorized-brackets\n```\n\n:::\n\n## Usage\n\nAdd to your Shiki transformers:\n\n```ts colorize-brackets\nimport { transformerColorizedBrackets } from '@shikijs/colorized-brackets'\nimport { codeToHtml } from 'shiki'\n\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: 'dark-plus',\n  transformers: [transformerColorizedBrackets()],\n})\n```\n\n### Colors\n\nBrackets are automatically colored according to your Shiki theme (or themes if using [dual themes](https://shiki.style/guide/dual-themes)), with support for all of Shiki's built-in themes. However, you can customize colors if you've added custom themes to Shiki, or if you want to override the colors of a built-in theme:\n\n```ts colorize-brackets\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: myCustomTheme,\n  transformers: [transformerColorizedBrackets({\n    themes: {\n      'my-custom-theme': ['goldenrod', 'blueviolet', 'dodgerblue', 'crimson'],\n    },\n  })],\n})\n```\n\nThe final color is the mismatched bracket color. The other colors are for each \"level\" of bracket pair. Any valid CSS color can be used.\n\nIf no bracket colors are found for a theme, it falls back to the default `dark-plus` theme.\n\n### Brackets\n\nYou can customize the bracket pairs:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  bracketPairs: [{ opener: '{', closer: '}' }],\n})\n```\n\nThe above would only colorize `{}` curly brackets. The default config colorizes `[]` square brackets, `{}` curly brackets, `()` parentheses, and `<>` angle brackets (only in TS type annotations).\n\nFor advanced usage, you can specify which TextMate scopes a bracket pair is allowed or denied in, using `scopesAllowList` and `scopesDenyList`. For example, the default config for `<>` angle brackets is:\n\n```ts colorize-brackets\nconst bracketPair = {\n  opener: '<',\n  closer: '>',\n  scopesAllowList: [\n    'punctuation.definition.typeparameters.begin.ts',\n    'punctuation.definition.typeparameters.end.ts',\n  ],\n}\n```\n\n### Language-specific Overrides\n\nAll settings can be overridden for specific languages using the `langs` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  langs: { ts: myCustomTypescriptConfig },\n})\n```\n\n### Explicit Trigger\n\nIf you do not want colorized brackets for all code blocks, you can enable the `explicitTrigger` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  explicitTrigger: true,\n})\n```\n\nThen, only code blocks with the `colorize-brackets` [meta string](/guide/transformers#meta) will have bracket colorizing enabled.\n\n````md\n```ts\n// no bracket colorizing\n```\n\n```ts colorize-brackets\n// brackets will be colorized\n```\n````\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":820,"sizeBytes":3174},{"name":"magic-move.md","path":"docs/packages/magic-move.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/magic-move.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# @shikijs/magic-move\n\n<Badges name=\"@shikijs/magic-move\" />\n\nSmoothly animated code blocks with Shiki. Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n`@shikijs/magic-move` is a low-level library: at its core is a framework-agnostic [diff/animation machine](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/core.ts) and [renderer](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/renderer.ts), with thin wrappers for Vue, React, Solid, Svelte, and a Web Component.\n\nEach framework wrapper provides three components:\n\n- **`ShikiMagicMove`** — the main component; wraps a code block and animates whenever `code` changes\n- **`ShikiMagicMovePrecompiled`** — animations for compiled tokens, without the Shiki dependency at runtime\n- **`ShikiMagicMoveRenderer`** — the low-level renderer component\n\n`ShikiMagicMove` needs a Shiki highlighter instance plus the bundled stylesheet (`@shikijs/magic-move/style.css`). Whenever `code` changes, the component animates the diff.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/magic-move shiki\n```\n\n```sh [yarn]\nyarn add -D @shikijs/magic-move shiki\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/magic-move shiki\n```\n\n```sh [bun]\nbun add -D @shikijs/magic-move shiki\n```\n\n```sh [deno]\ndeno add npm:@shikijs/magic-move npm:shiki\n```\n\n:::\n\n## Usage\n\n### Vue\n\nImport `@shikijs/magic-move/vue` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```vue\n<script setup>\nimport { ShikiMagicMove } from '@shikijs/magic-move/vue'\nimport { createHighlighter } from 'shiki'\nimport { ref } from 'vue'\n\nimport '@shikijs/magic-move/style.css'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst code = ref(`const hello = 'world'`)\n\nfunction animate() {\n  code.value = `let hi = 'hello'`\n}\n</script>\n\n<template>\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    :options=\"{ duration: 800, stagger: 0.3, lineNumbers: true }\"\n  />\n  <button @click=\"animate\">\n    Animate\n  </button>\n</template>\n```\n\n### React\n\nImport `@shikijs/magic-move/react` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport type { HighlighterCore } from 'shiki'\nimport { ShikiMagicMove } from '@shikijs/magic-move/react'\nimport { useEffect, useState } from 'react'\nimport { createHighlighter } from 'shiki'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = useState(`const hello = 'world'`)\n  const [highlighter, setHighlighter] = useState<HighlighterCore>()\n\n  useEffect(() => {\n    async function initializeHighlighter() {\n      const h = await createHighlighter({\n        themes: ['nord'],\n        langs: ['javascript', 'typescript'],\n      })\n      setHighlighter(h)\n    }\n    initializeHighlighter()\n  }, [])\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      {highlighter && (\n        <>\n          <ShikiMagicMove\n            lang=\"ts\"\n            theme=\"nord\"\n            highlighter={highlighter}\n            code={code}\n            options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n          />\n          <button onClick={animate}>Animate</button>\n        </>\n      )}\n    </div>\n  )\n}\n```\n\n### Solid\n\nImport `@shikijs/magic-move/solid` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport { ShikiMagicMove } from '@shikijs/magic-move/solid'\nimport { bundledLanguages, bundledThemes, createHighlighter } from 'shiki'\nimport { createResource, createSignal, Show } from 'solid-js'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = createSignal(`const hello = 'world'`)\n\n  const [highlighter] = createResource(async () => {\n    return await createHighlighter({\n      themes: Object.keys(bundledThemes),\n      langs: Object.keys(bundledLanguages),\n    })\n  })\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      <Show when={highlighter()}>\n        {h => (\n          <>\n            <ShikiMagicMove\n              lang=\"ts\"\n              theme=\"nord\"\n              highlighter={h()}\n              code={code()}\n              options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n            />\n            <button onClick={animate}>Animate</button>\n          </>\n        )}\n      </Show>\n    </div>\n  )\n}\n```\n\n### Svelte\n\nImport `@shikijs/magic-move/svelte` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```svelte\n<script lang=\"ts\">\n  import { ShikiMagicMove } from '@shikijs/magic-move/svelte'\n  import { createHighlighter } from 'shiki'\n\n  import '@shikijs/magic-move/style.css'\n\n  const highlighter = createHighlighter({\n    themes: ['nord'],\n    langs: ['javascript', 'typescript'],\n  })\n\n  let code = $state(`const hello = 'world'`)\n\n  function animate() {\n    code = `let hi = 'hello'`\n  }\n</script>\n\n{#await highlighter then highlighter}\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    {highlighter}\n    {code}\n    options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n  />\n  <button onclick={animate}>Animate</button>\n{/await}\n```\n\n## `ShikiMagicMovePrecompiled`\n\n`ShikiMagicMovePrecompiled` is a lighter variant of `ShikiMagicMove` that doesn't need Shiki at runtime — useful when you want to ship pre-tokenized step data (e.g. produced at build time) and animate between steps in the browser.\n\n```vue\n<script setup>\nimport { ShikiMagicMovePrecompiled } from '@shikijs/magic-move/vue'\nimport { ref } from 'vue'\n\nconst step = ref(1)\nconst compiledSteps = [/* Compiled token steps */]\n</script>\n\n<template>\n  <ShikiMagicMovePrecompiled\n    :steps=\"compiledSteps\"\n    :step=\"step\"\n  />\n  <button @click=\"step++\">\n    Next\n  </button>\n</template>\n```\n\nTo produce the compiled tokens, run this somewhere with access to Shiki (build script, server, etc.) and serialize the result:\n\n```ts\nimport { codeToKeyedTokens, createMagicMoveMachine } from '@shikijs/magic-move/core'\nimport { createHighlighter } from 'shiki'\n\nconst shiki = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst codeSteps = [\n  `const hello = 'world'`,\n  `let hi = 'hello'`,\n]\n\nconst machine = createMagicMoveMachine(\n  code => codeToKeyedTokens(shiki, code, {\n    lang: 'ts',\n    theme: 'nord',\n  }),\n  {\n    // options\n  },\n)\n\nconst compiledSteps = codeSteps.map(code => machine.commit(code).current)\n\n// Pass `compiledSteps` to the precompiled component.\n// Since these are plain serialisable objects, you can stringify them at build time\n// and rehydrate them in the browser without needing Shiki.\n```\n\n## How it works\n\nFor a deep dive into the algorithm behind the animations, see Anthony's article [**The Magic In Shiki Magic Move**](https://antfu.me/posts/shiki-magic-move).\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":1857,"sizeBytes":6935},{"name":"markdown-exit.md","path":"docs/packages/markdown-exit.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/markdown-exit.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# @shikijs/markdown-exit\n\n<Badges name=\"@shikijs/markdown-exit\" />\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for Shiki.\n\n`markdown-exit` is a modern TypeScript rewrite of `markdown-it` with native async rendering support — no extra library needed for async highlighting.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-exit\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-exit\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-exit\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-exit\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-exit\n```\n\n:::\n\n## Usage\n\nThe default export uses Shiki's [shorthands](/guide/shorthands) for on-demand loading of themes and languages. Since highlighting is async, use `md.renderAsync()` to render:\n\n````ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n\nconst html = await md.renderAsync(md_string)\n```\n\n## Custom `codeToHtml`\n\nIf you have a custom `codeToHtml` function (e.g., from a fine-grained shorthand bundle), use `fromAsyncCodeToHtml`:\n\n````ts\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\nconst md = createMarkdownExit()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-exit/core` and pass your own highlighter:\n\n```ts\nimport { fromHighlighter } from '@shikijs/markdown-exit/core'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = createMarkdownExit()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n","isInternal":false,"tokens":868,"sizeBytes":3115},{"name":"markdown-it.md","path":"docs/packages/markdown-it.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/markdown-it.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# @shikijs/markdown-it\n\n<Badges name=\"@shikijs/markdown-it\" />\n\n[markdown-it](https://markdown-it.github.io/) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-it\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-it\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-it\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-it\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-it\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"959709c97c288ea5ed5a231f28e5eebf48f1676e9c76559e68208cb76e2b6711\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n```\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"7251d42df549db899085560c6ca05a99dc9f338642b7849507ef0ead24fa6dba\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n```\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-it/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4cce3b72c2224ceff07c637806719480ab0b5bcdb0fafc8ad599ec8c8ad5d255\",\"data\":\"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\"}\n// @noErrors: true\nimport { fromHighlighter } from '@shikijs/markdown-it/core'\nimport MarkdownIt from 'markdown-it'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = MarkdownIt()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n\n## With Shorthands\n\nShiki's [shorthands](/guide/shorthands) provides on-demand loading of themes and languages, but also makes the highlighting process asynchronous. Unfortunately, `markdown-it` itself [does NOT support async highlighting](https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#i-need-async-rule-how-to-do-it) out of the box.\n\nTo workaround this, you can use [`markdown-it-async`](https://github.com/antfu/markdown-it-async) by [Anthony Fu](https://github.com/antfu). Where Shiki also provides an integration with it, you can import `fromAsyncCodeToHtml` from `@shikijs/markdown-it/async`.\n\n````ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4d4fcf8100ee107a1813af12192e944bfcf04449a77daa41fca68ea887412763\",\"data\":\"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\"}\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async'\nimport MarkdownItAsync from 'markdown-it-async'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\n// Initialize MarkdownIt instance with markdown-it-async\nconst md = MarkdownItAsync()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    // Pass the codeToHtml function\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformer Caveats\n\n`markdown-it` defaults to enforcing `<pre><code>` as the outermost wrappers of code block html. If you use a custom Shiki [transformer](/guide/transformers), this behavior may be undesirable. For example, if the transformer produces\n\n```html\n<div class=\"fenced-code-block\">\n  <pre>\n    <code>\n      …\n    </code>\n  </pre>\n</div>\n```\n\nthe result after `markdown-it` processing will be\n\n```html\n<pre>\n  <code>\n    <div class=\"fenced-code-block\">\n      <pre>\n        <code>\n          …\n        </code>\n      </pre>\n    </div>\n  </code>\n</pre>\n```\n\nWork around this by adding [olets/markdown-it-wrapperless-fence-rule](https://github.com/olets/markdown-it-wrapperless-fence-rule) to your `markdown-it` configuration, or by writing your own `markdown-it` fence rule (see [markdown-it#269](https://github.com/markdown-it/markdown-it/issues/269)).\n","isInternal":false,"tokens":14060,"sizeBytes":22466},{"name":"monaco.md","path":"docs/packages/monaco.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/monaco.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# Monaco Editor Integration\n\nShiki uses the same TextMate grammar and themes as VS Code, so it can be used to highlight Monaco Editor. Shiki provides an official integration for Monaco Editor. You can also use [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration.\n\n## @shikijs/monaco\n\n<Badges name=\"@shikijs/monaco\" />\n\nUse Shiki to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\nMonaco's built-in highlighter does not use the full TextMate grammar, which in some cases is not accurate enough. This package allows you to use Shiki's syntax highlighting engine to highlight Monaco, with shared grammars and themes from Shiki.\n\nHeavily inspired by [`monaco-editor-textmate`](https://github.com/zikaari/monaco-editor-textmate).\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/monaco\n```\n\n```sh [yarn]\nyarn add -D @shikijs/monaco\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/monaco\n```\n\n```sh [bun]\nbun add -D @shikijs/monaco\n```\n\n```sh [deno]\ndeno add npm:@shikijs/monaco\n```\n\n:::\n\n### Usage\n\n```ts\nimport { shikiToMonaco } from '@shikijs/monaco'\nimport * as monaco from 'monaco-editor-core'\nimport { createHighlighter } from 'shiki'\n\n// Create the highlighter, it can be reused\nconst highlighter = await createHighlighter({\n  themes: [\n    'vitesse-dark',\n    'vitesse-light',\n  ],\n  langs: [\n    'javascript',\n    'typescript',\n    'vue'\n  ],\n})\n\n// Register the languageIds first. Only registered languages will be highlighted.\nmonaco.languages.register({ id: 'vue' })\nmonaco.languages.register({ id: 'typescript' })\nmonaco.languages.register({ id: 'javascript' })\n\n// Register the themes from Shiki, and provide syntax highlighting for Monaco. // [!code highlight:2]\nshikiToMonaco(highlighter, monaco)\n\n// Create the editor\nconst editor = monaco.editor.create(document.getElementById('container'), {\n  value: 'const a = 1',\n  language: 'javascript',\n  theme: 'vitesse-dark',\n})\n\n// ...As you use the editor normally\n```\n\n## modern-monaco\n\n<Badges name=\"modern-monaco\" />\n\nWe highly recommend using [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration. It provides a more convenient API for building Monaco Editor.\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D modern-monaco\n```\n\n```sh [yarn]\nyarn add -D modern-monaco\n```\n\n```sh [pnpm]\npnpm add -D modern-monaco\n```\n\n```sh [bun]\nbun add -D modern-monaco\n```\n\n```sh [deno]\ndeno add npm:modern-monaco\n```\n\n:::\n\nOr import it from [esm.sh](https://esm.sh) CDN in the browser without a build step:\n\n```js\nimport * as monaco from 'https://esm.sh/modern-monaco'\n```\n\n### Usage\n\n```html\n<!-- index.html -->\n<monaco-editor theme=\"vitesse-dark\"></monaco-editor>\n<script src=\"app.js\" type=\"module\"></script>\n```\n\n```js\n// app.js\nimport { lazy, Workspace } from 'modern-monaco'\n\n// create a workspace with initial files\nconst workspace = new Workspace({\n  initialFiles: {\n    'index.html': `<html><body>...</body></html>`,\n    'main.js': `console.log('Hello, world!')`,\n  },\n  entryFile: 'index.html',\n})\n\n// initialize the editor lazily\nawait lazy({ workspace })\n\n// write a file and open it in the editor\nworkspace.fs.writeFile('util.js', 'export function add(a, b) { return a + b; }')\nworkspace.openTextDocument('util.js')\n```\n\nMore usage please see the [modern-monaco](https://github.com/esm-dev/modern-monaco) repository.\n","isInternal":false,"tokens":932,"sizeBytes":3394},{"name":"next.md","path":"docs/packages/next.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/next.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# Next.js\n\nShiki does not provide an official integration for [Next.js](https://nextjs.org), but it is rather straightforward to use Shiki in Next.js applications.\n\n::: info\nUsing Shiki on Edge Runtime might cause unintended problems, Shiki relies on lazy imports to load languages and themes.\n\nServerless Runtime is recommended.\n:::\n\n## React Server Component\n\nSince Server Components are server-only, you can use the bundled highlighter without worrying the bundle size.\n\n```tsx\nimport type { BundledLanguage } from 'shiki'\nimport { codeToHtml } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHtml(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return <div dangerouslySetInnerHTML={{ __html: out }} />\n}\n```\n\n### Custom Components\n\nYou can also call `codeToHast` to get the HTML abstract syntax tree, and render it using [`hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime). With this method, you can render your own `pre` and `code` components.\n\n```tsx\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHast(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n    components: {\n      // your custom `pre` element\n      pre: props => <pre data-custom-codeblock {...props} />\n    },\n  }) as JSX.Element\n}\n```\n\n## React Client Component\n\nFor client components, they are pre-rendered on server and hydrated/rendered on client.\nWe can start by creating a client `CodeBlock` component.\n\nCreate a `shared.ts` for highlighter:\n\n```ts\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki/bundle/web'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki/bundle/web'\n\nexport async function highlight(code: string, lang: BundledLanguage) {\n  const out = await codeToHast(code, {\n    lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n  }) as JSX.Element\n}\n```\n\nIn your `codeblock.tsx`:\n\n```tsx\n'use client'\nimport { JSX, useLayoutEffect, useState } from 'react'\nimport { highlight } from './shared'\n\nexport function CodeBlock({ initial }: { initial?: JSX.Element }) {\n  const [nodes, setNodes] = useState(initial)\n\n  useLayoutEffect(() => {\n    void highlight('console.log(\"Rendered on client\")', 'ts').then(setNodes)\n  }, [])\n\n  return nodes ?? <p>Loading...</p>\n}\n```\n\nThe `initial` prop can be passed from a server component to pre-render the code block on server.\n\nIn your `page.tsx`:\n\n```tsx\nimport { CodeBlock } from './codeblock'\nimport { highlight } from './shared'\n\nexport default async function Page() {\n  // `initial` is optional.\n  return (\n    <main>\n      <CodeBlock initial={await highlight('console.log(\"Rendered on server\")', 'ts')} />\n    </main>\n  )\n}\n```\n\n::: info\nThe above example uses the `shiki/bundle/web` bundle. You can change it to [Fine-grained Bundle](/guide/bundles#fine-grained-bundle) to fully control the bundled languages/themes.\n:::\n\n### Performance\n\nShiki lazy loads the requested languages and themes, the Next.js bundler can handle lazy imports automatically.\nImporting `shiki` or its web bundle is efficient enough for most Next.js applications, Fine-grained Bundle won't significantly impact the bundle size.\n\nIn addition, you can use the `createHighlighter` API to preload specific languages and themes.\nPlease refer to [Highlighter Usage](/guide/install#highlighter-usage) for further details.\n\n### Highlighter Instance\n\nIf you define a highlighter (without `await`) as a global variable, you can reference it directly from server and client components.\n\n```ts\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript'],\n})\n\n// Inside an async server component, or client side `useEffect`\nconst html = (await highlighter).codeToHtml('const a = 1', {\n  lang: 'javascript',\n  theme: 'nord'\n})\n```\n","isInternal":false,"tokens":1228,"sizeBytes":4897},{"name":"nuxt.md","path":"docs/packages/nuxt.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/nuxt.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"# Nuxt\n\n[Nuxt](https://nuxt.com) is a general-purpose meta-framework that gives you full control over your application. You can install Shiki along with integrations like ([markdown-it](/packages/markdown-it), [rehype](/packages/rehype)) or import manually as you needed.\n\nOn top of that, Nuxt also provide some module integrations for Shiki allowing you use it easier:\n\n- [`nuxt-shiki`](https://github.com/pi0/nuxt-shiki) - Shiki integration for client and server sides, with component usage.\n- [`@nuxt/content`](https://github.com/nuxt/content) - Nuxt Content has Shiki built-in for markdown files. [You can enable it with the `highlight` option](https://content.nuxt.com/docs/getting-started/configuration#highlight).\n  - [`@nuxtjs/mdc`](https://github.com/nuxt-modules/mdc) - The underlying module of `@nuxt/content` that provides Markdown Component (MDC) syntax as well as Shiki for syntax highlighting.\n\n## TwoSlash Integration\n\n- [`nuxt-content-twoslash`](https://github.com/antfu/nuxt-content-twoslash) - A Nuxt module that adds Twoslash support to Nuxt Content. Twoslash information are evaluated at build time.\n","isInternal":false,"tokens":277,"sizeBytes":1121},{"name":"rehype.md","path":"docs/packages/rehype.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/rehype.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# @shikijs/rehype\n\n<Badges name=\"@shikijs/rehype\" />\n\n[rehype](https://github.com/rehypejs/rehype) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/rehype\n```\n\n```sh [yarn]\nyarn add -D @shikijs/rehype\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/rehype\n```\n\n```sh [bun]\nbun add -D @shikijs/rehype\n```\n\n```sh [deno]\ndeno add npm:@shikijs/rehype\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"f652dc1d308709739c1be11a9172b77ef0b59d02c30ad9b2f5dc7195fad4cd45\",\"data\":\"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=\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThe default export of `@shikijs/rehype` uses a shared instance of `shiki` from `getSingletonHighlighter`, which will persist across processes. If you want full control over the highlighter lifecycle, use [Fine-grained Bundle `@shikijs/rehype/core`](#fine-grained-bundle) instead.\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import `rehypeShikiFromHighlighter` from `@shikijs/rehype/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"141199456275121b3ddecb36bbeedc3ec800ba9c5d4c78ec0a3f651e44ac22ee\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShikiFromHighlighter from '@shikijs/rehype/core'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nimport { unified } from 'unified'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst raw = await fs.readFile('./input.md')\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShikiFromHighlighter, highlighter, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .processSync(raw) // it's also possible to process synchronously\n```\n\n## Features\n\n### Inline Code\n\nYou can also highlight inline codes with the `inline` option.\n\n| Option                  | Example          | Description                                                 |\n| ----------------------- | ---------------- | ----------------------------------------------------------- |\n| `false`                 | -                | Disable inline code highlighting (default)                  |\n| `'tailing-curly-colon'` | `let a = 1{:js}` | Highlight with a `{:language}` marker inside the code block |\n\nEnable `inline` on the Rehype plugin:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"549ef2ad84b55c413cb40bcedc19dcf805008cf25a703dd1f3614dff89dbdd93\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    inline: 'tailing-curly-colon', // or other options\n    // ...\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThen you can use inline code in markdown:\n\n```md\nThis code `console.log(\"Hello World\"){:js}` will be highlighted.\n```\n\n## Postprocess Transformers\n\n::: info\nThe `postprocess` transformer hook is only invoked when producing HTML strings (i.e., when using `codeToHtml`). Since `@shikijs/rehype` operates on HAST (Hypertext Abstract Syntax Tree) rather than HTML strings, postprocess transformers will not be executed.\n:::\n\nThis design is intentional: running `postprocess` hooks in rehype would require converting HAST → HTML → running postprocess → parsing back to HAST, which changes the semantics and could surprise users expecting HAST-only transformers.\n\n### Workaround for HTML-based Postprocessing\n\nIf you need to run HTML-based postprocessing with rehype, you can apply a `root` transformer that:\n\n1. Converts the HAST fragment to HTML using `hast-util-to-html`\n2. Runs your HTML transformers\n3. Converts back to HAST using `hast-util-from-html`\n\nExample:\n\n```ts\nimport { fromHtml } from 'hast-util-from-html'\nimport { toHtml } from 'hast-util-to-html'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    },\n    transformers: [\n      {\n        name: 'custom-html-postprocessor',\n        root(node) {\n          // Convert HAST to HTML\n          const html = toHtml(node)\n\n          // Apply your HTML transformations\n          const processedHtml = myCustomPostprocess(html)\n\n          // Parse back to HAST\n          const newNode = fromHtml(processedHtml, { fragment: true })\n\n          // Replace the node\n          return newNode\n        }\n      }\n    ]\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":28922,"sizeBytes":44079},{"name":"stream.md","path":"docs/packages/stream.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/stream.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# @shikijs/stream\n\n<Badges name=\"@shikijs/stream\" />\n\nStreaming colorization for Shiki. Useful for highlighting text streams like LLM outputs, where code arrives incrementally and you want each chunk highlighted as it lands without re-tokenizing the whole document.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/stream\n```\n\n```sh [yarn]\nyarn add -D @shikijs/stream\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/stream\n```\n\n```sh [bun]\nbun add -D @shikijs/stream\n```\n\n```sh [deno]\ndeno add npm:@shikijs/stream\n```\n\n:::\n\n## Usage\n\nCreate a transform stream with `CodeToTokenTransformStream` and `.pipeThrough` your text stream:\n\n```ts\nimport { CodeToTokenTransformStream } from '@shikijs/stream'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\n\n// Initialize the Shiki highlighter somewhere in your app\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\n// The ReadableStream<string> you want to highlight\nconst textStream = getTextStreamFromSomewhere()\n\n// Pipe the text stream through the token stream\nconst tokensStream = textStream\n  .pipeThrough(new CodeToTokenTransformStream({\n    highlighter,\n    lang: 'javascript',\n    theme: 'nord',\n    allowRecalls: true, // see explanation below\n  }))\n```\n\n### `allowRecalls`\n\nDue to the fact that highlighting may change based on the context of the code, themed tokens can be re-evaluated as the stream progresses. Because streams are one-directional, `@shikijs/stream` emits a special **recall** token that tells the receiver to discard the last N tokens that changed.\n\nBy default, `CodeToTokenTransformStream` only emits **stable** tokens — no recalls. The trade-off is coarser granularity, usually one line at a time.\n\nFor stream consumers that can handle recalls (e.g. the bundled Vue, React, Solid, and Svelte components), set `allowRecalls: true` to get finer-grained tokens.\n\nTypically recalls should be handled like:\n\n```ts\nimport type { RecallToken } from '@shikijs/stream'\nimport type { ThemedToken } from 'shiki'\n\nconst receivedTokens: ThemedToken[] = []\n\ntokensStream.pipeTo(new WritableStream<ThemedToken | RecallToken>({\n  async write(token) {\n    if ('recall' in token) {\n      // discard the last `token.recall` tokens\n      receivedTokens.length -= token.recall\n    }\n    else {\n      receivedTokens.push(token)\n    }\n  },\n}))\n```\n\n## Consume the Token Stream\n\n### Manually\n\n```ts\ntokensStream.pipeTo(new WritableStream({\n  async write(token) {\n    console.log(token)\n  },\n}))\n```\n\nOr in Node.js:\n\n```ts\nfor await (const token of tokensStream) {\n  console.log(token)\n}\n```\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/vue'\n\n// get the token stream\n</script>\n\n<template>\n  <ShikiStreamRenderer :stream=\"tokensStream\" />\n</template>\n```\n\n### React\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/react'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Solid\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/solid'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Svelte\n\n```svelte\n<script lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/svelte'\n\n// get the token stream\n</script>\n\n<ShikiStreamRenderer stream={tokensStream} />\n```\n\n## Cached Renderer\n\n`@shikijs/stream` also ships a simplified renderer for the common case of an incrementally-updated code string (rather than a token stream).\n\n::: warning Experimental\nThis API is experimental and may change.\n:::\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiCachedRenderer } from '@shikijs/stream/vue'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\nimport { onMounted, ref } from 'vue'\n\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\nconst code = ref('') // code should only be updated incrementally\n\n// for demo purposes\nonMounted(() => {\n  setInterval(() => {\n    code.value += '\\nconsole.log(\"Hello, world!\");'\n  }, 1000)\n})\n</script>\n\n<template>\n  <ShikiCachedRenderer\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    lang=\"js\"\n    theme=\"vitesse-light\"\n  />\n</template>\n```\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":1120,"sizeBytes":4400},{"name":"transformers.md","path":"docs/packages/transformers.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/transformers.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# @shikijs/transformers\n\n<Badges name=\"@shikijs/transformers\" />\n\nCommon transformers for Shiki, inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/transformers\n```\n\n```sh [yarn]\nyarn add -D @shikijs/transformers\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/transformers\n```\n\n```sh [bun]\nbun add -D @shikijs/transformers\n```\n\n```sh [deno]\ndeno add npm:@shikijs/transformers\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"8efec5d385627b3d23e03e4c9bdf13f9a3c80178f3105cfb878cd54cef1eacb9\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZAHIQ0zcZIAi7fv0YQsO+QH5EvACqz5iles3aJYfYYDyp1zysBlfHYAa3ZbOQUlVVIAHTB2ZSwlNGk7CMdSDS0zd35KECgIEQREEABVOBheAANkAEIRaEqAaiaAXSreOShquobYXgBaAfbpCF5lZlIgzqhYbq7eUhhlYhhujjB4ADo8uC1SBkQAZgAWKlYYMABzNHwkACYjqn2rmEPqVIcozJc9A1zzuxNg8qCJ8JNmGIyA8AL4UdDYXAlQgkcjPOjvFgcLh8BryZJ9GDWCAACTQylYVkYhKse1IQKuFF4JjMcCsAGFGsSSVw0F5WQAeABCwigFygABk5FdBMxXkyRWAxWtrPhljAAHx8AC8Gt4AAVSBBlOwKgK6QyNbF4okDrxCdzyaxdvtDgBGN0ABnOlxud0QXuek1e7wdpKdeQ2SIAbKDwbIoeREPc4QicHgUdD0fQ8Hi9vbGlZoiA8xALltWBArowAORq1iVmvcYsuybuk5nEAXa63JCdl5vXONSNApEATjjEMTSGjqeoiIzqzR1AxQ/xvHwTtpMgZrYOSDdAA5vV3fb3EP3g4PkRHAcCAyewVOaEnZ/D5+nkUu8jQcyUsZwPAFrAjoUtSha8Ba1xMiyPgclypK8vyPjCqK4pStcsryrwirKlAqrqlqViGsapowOaO7XFacQJEkwFEuGFJ7u6Y5PKePb+oG1BXqGCFkkxd5IlxT4Ji+B5jnOmCfgQ37Zrx640rwxaluWlbVnWMANhATYtlQextg8nqdt2fp9kGpAhkOsAjvewnxpCYnHJ6kkLl+qI/qu/5YEaOAHBgfCsNKRbUHAukgPp+7Jm6xlnv6l4WdeXbSjZQlupOonQsmLnSZmy6/pi3kmGQmB8JysDIZIcB+AyFwEaoqFKuKdWalstzqlYzUAEowFcpoyL8YAAIJgBgvAAD68H4lFXBK7AvmwpRxJIDV4c1TJQVcGrMQ89yHj6HFIAArOZlklG1qgpQe9zpQ5mUpu+UlIjJ7lyUwhW+SVNifJEZAVfIrXfekcCWJNgQhGE9g/aQyCtONvCijA/CjlAeQFEUeAQ2kURwAISjSGqoPBOwvBYOwOBRjsemug8JzHexpkBtd3EJe8/WQ0Dl0BmxIm3Um91pk9uUeX+IAATiKThF8ThZK4OTGN4lUg5jUsZM42T/H9viE+DgNRNatF2mzWPSwNOSo4UxRlBUPT1I0vAtCMCw1Lb/RDCMaBjBMUwzHMnRKosyyrOso5wJT4XU8m0Z0yZ56PCdiVGyrPzq4YnPRTd04XjCrSgsOJQAPT57wvR24EVz4Bw5doIgh2tPrtrJMAsS8BL7PfGrsv/BQze8IXvBbAPsQwgIRrKLwNYAAJwGD7AAFZwPnidQ3ANb13RTdSPRoGsN3YDD/wo/j9PROr2AsR5gSdvatUKkwBWVa1vWjbcFU5+Vckm4Urw1/MAA7swc0t6MVYOBWATIN4t0CtcKwNY0Ar13i3c6MAYGQFIFAGsCDW7G1IGyYuPdEG6xNinIw3AmR9xLv0MuFd2BVzrpvFufcB5bB7jnIe3A8iqC0EgUAGJLhwFcHgOBIAYQwiAA===\"}\n// [!code highlight:5]\nimport {\n  transformerNotationDiff,\n  // ...\n} from '@shikijs/transformers'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff(), // [!code highlight]\n    // ...\n  ],\n})\n```\n\n## Unstyled\n\nTransformers only applies classes and does not come with styles; you can provide your own CSS rules to style them properly.\n\n## Matching Algorithm\n\nWe found that the algorithm for matching comments in v1 is sometime conterintuitive, where we are trying to fix it in a progressive way. Since v1.29.0, we introduced a new `matchAlgorithm` option to most of the transformer for you to toggle between different matching algorithms. Right now, the default is `v1` which is the old algorithm, and `v3` is the new algorithm. When Shiki v3 is landed, the default will be `v3`.\n\n```ts\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff({\n      matchAlgorithm: 'v3', // [!code hl]\n    }),\n  ],\n})\n```\n\n### `matchAlgorithm: 'v1'`\n\nThe matching algorithm mostly affects the single-line comment matching, in `v1`, it will count the comment line as the first line, while in `v3`, it will count start from the comment line:\n\n```ts\n// [\\!code highlight:3]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n### `matchAlgorithm: 'v3'`\n\nIn `v3`, the matching algorithm will start counting from the line below the comment:\n\n```ts\n// [\\!code highlight:2]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n## Transformers\n\n### `transformerNotationDiff`\n\nUse `[!code ++]` and `[!code --]` to mark added and removed lines.\n\n````md\n```ts\nconsole.log('hewwo') // [\\!code --]\nconsole.log('hello') // [\\!code ++]\nconsole.log('goodbye')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('hewwo') // [!code --]\nconsole.log('hello') // [!code ++]\nconsole.log('goodbye')\n```\n\n- `// [!code ++]` outputs: `<span class=\"line diff add\">`\n- `// [!code --]` outputs: `<span class=\"line diff remove\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-diff\">`\n\n::: details HTML Output\n\n```html\n<!-- Output (stripped of `style` attributes for clarity) -->\n<pre class=\"shiki has-diff\"> <!-- Notice `has-diff` -->\n  <code>\n    <span class=\"line\"></span>\n    <span class=\"line\"><span>function</span><span>()</span><span></span><span>{</span></span>\n    <span class=\"line diff remove\">  <!-- Notice `diff` and `remove` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hewwo</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line diff add\">  <!-- Notice `diff` and `add` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hello</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line\"><span></span><span>}</span></span>\n    <span class=\"line\"><span></span></span>\n  </code>\n</pre>\n```\n\n:::\n\n---\n\n### `transformerNotationHighlight`\n\nUse `[!code highlight]` to highlight a line.\n\n````md\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [\\!code highlight]\nconsole.log('Not highlighted')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [!code highlight]\nconsole.log('Not highlighted')\n```\n\n- `// [!code highlight]` outputs: `<span class=\"line highlighted\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nYou can also highlight multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [\\!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n````\n\nRenders:\n\n```ts\n// [!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n---\n\n### `transformerNotationWordHighlight`\n\nUse `[!code word:Hello]` to highlight the word `Hello` in any subsequent code.\n\n````md\n```ts\n// [\\!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\n// [!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\nYou can also specify the number of lines to highlight words on, e.g. `[!code word:Hello:1]` will only highlight occurrences of `Hello` on the next line.\n\n````md\n```ts\n// [\\!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders:\n\n```ts\n// [!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\n---\n\n### `transformerNotationFocus`\n\nUse `[!code focus]` to focus a line.\n\n````md\n```ts\nconsole.log('Not focused');\nconsole.log('Focused') // [\\!code focus]\nconsole.log('Not focused');\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not focused')\nconsole.log('Focused') // [!code focus]\nconsole.log('Not focused')\n```\n\n- Outputs: `<span class=\"line focused\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-focused\">`\n\nYou can also focus multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n````\n\nRenders:\n\n```ts\n// [!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n\n---\n\n### `transformerNotationErrorLevel`\n\nUse `[!code error]`, `[!code warning]`, and `[!code info]` to mark a line with an error, warning, or info levels.\n\n````md\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [\\!code error]\nconsole.warn('Warning') // [\\!code warning]\nconsole.log('Info') // [\\!code info]\n```\n````\n\n- Outputs: `<span class=\"line highlighted error\">` for errors\n- Outputs: `<span class=\"line highlighted warning\">` for warnings\n- Outputs: `<span class=\"line highlighted info\">` for info\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nWith some additional CSS rules, you can make it look like this:\n\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [!code error]\nconsole.warn('Warning') // [!code warning]\nconsole.log('Info') // [!code info]\n```\n\n---\n\n### `transformerRenderWhitespace`\n\nRender whitespaces (tabs and spaces) as individual spans, with classes `tab` and `space`.\n\nOptions:\n\n- `position`: `'all' | 'boundary' | 'trailing' | 'leading'`. Default `'all'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#AB5959;--shiki-dark:#CB7676;\">function</span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">block</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">{</span></span>\n<span class=\"line\"><span class=\"space\"> </span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">space</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span></span>\n<span class=\"line\"><span class=\"tab\">&#9;</span><span class=\"tab\">&#9;</span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">tab</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span style=\"--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;\"> </span></span>\n<span class=\"line\"><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .tab,\npre.shiki .space {\n  position: relative;\n}\n\npre.shiki .tab::before {\n  content: '⇥';\n  position: absolute;\n  opacity: 0.3;\n}\n\npre.shiki .space::before {\n  content: '·';\n  position: absolute;\n  opacity: 0.3;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderIndentGuides`\n\nRender indentations as individual spans, with class `indent`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CB7676\">function</span><span style=\"color:#80A665\"> func</span><span style=\"color:#666666\">()</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">1</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\" style=\"--indent-offset: 0ch;\"></span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#4D9375\">for</span><span style=\"color:#666666\"> (</span><span style=\"color:#CB7676\">const </span><span style=\"color:#BD976A\">i</span><span style=\"color:#CB7676\"> of</span><span style=\"color:#666666\"> [])</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">2</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#666666\">}</span></span>\n<span class=\"line\"><span style=\"color:#666666\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .indent {\n  display: inline-block;\n  position: relative;\n  left: var(--indent-offset);\n}\n\npre.shiki .indent:empty {\n  height: 1lh;\n  vertical-align: bottom;\n}\n\npre.shiki .indent::before {\n  content: '';\n  position: absolute;\n  opacity: 0.15;\n  width: 1px;\n  height: 100%;\n  background-color: currentColor;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderLineNumber`\n\nRender line numbers as individual spans, with class `line-number`.\n\n```ts\nimport { transformerRenderLineNumber } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  transformers: [\n    transformerRenderLineNumber(),\n  ],\n})\n```\n\nOptions:\n\n- `start`: Start number. Default `1`.\n- `classLineNumber`: Class for line number. Default `'line-number'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n```css\npre.shiki .line-number {\n  user-select: none;\n  opacity: 0.5;\n  margin-right: 1em;\n}\n```\n\n---\n\n### `transformerMetaHighlight`\n\nHighlight lines based on the [meta string](/guide/transformers#meta) provided on the code snippet.\n\n````md\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n````\n\nRenders (with custom CSS rules):\n\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n\n- Outputs: `<span class=\"line highlighted\">` for included lines.\n\n### `transformerMetaWordHighlight`\n\nHighlight words based on the meta string provided on the code snippet.\n\n````md\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg)\nconsole.log(msg) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\n---\n\n### `transformerCompactLineOptions`\n\nSupport for `shiki`'s `lineOptions` that is removed in `shiki`.\n\n---\n\n### `transformerRemoveLineBreak`\n\nRemove line breaks between `<span class=\"line\">`. Useful when you set `display: block` to `.line` in CSS.\n\n---\n\n### `transformerRemoveNotationEscape`\n\nTransform `// [\\!code ...]` to `// [!code ...]`.\nAvoid rendering the escaped notation syntax as it is.\n\n---\n\n### `transformerStyleToClass`\n\nConvert Shiki's inline styles to unique classes.\n\nClass names are generated based on the hash value of the style object with the prefix/suffix you provide. You can put this transformer in multiple highlights passes and then get the CSS at the end to reuse the exact same styles. As Shiki doesn't handle CSS, it's on your integration to decide how to extract and apply/bundle the CSS.\n\nFor example:\n\n```ts\nimport { transformerStyleToClass } from '@shikijs/transformers'\nimport { codeToHtml } from 'shiki'\n\nconst toClass = transformerStyleToClass({ // [!code highlight:3]\n  classPrefix: '__shiki_',\n})\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  themes: {\n    dark: 'vitesse-dark',\n    light: 'vitesse-light',\n  },\n  defaultColor: false,\n  transformers: [toClass], // [!code highlight]\n})\n\n// The transformer instance exposes some methods to get the CSS\nconst css = toClass.getCSS() // [!code highlight]\n\n// use `html` and `css` in your app\n```\n\nHTML output:\n\n```html\n<pre class=\"shiki shiki-themes vitesse-dark vitesse-light __shiki_9knfln\" tabindex=\"0\"><code><span class=\"line\">\n  <span class=\"__shiki_14cn0u\">console</span>\n  <span class=\"__shiki_ps5uht\">.</span>\n  <span class=\"__shiki_1zrdwt\">log</span>\n  <span class=\"__shiki_ps5uht\">(</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_1g4r39\">hello</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_ps5uht\">)</span>\n</span></code></pre>\n```\n\nCSS output:\n\n```css\n.__shiki_14cn0u {\n  --shiki-dark: #bd976a;\n  --shiki-light: #b07d48;\n}\n.__shiki_ps5uht {\n  --shiki-dark: #666666;\n  --shiki-light: #999999;\n}\n.__shiki_1zrdwt {\n  --shiki-dark: #80a665;\n  --shiki-light: #59873a;\n}\n.__shiki_236mh3 {\n  --shiki-dark: #c98a7d77;\n  --shiki-light: #b5695977;\n}\n.__shiki_1g4r39 {\n  --shiki-dark: #c98a7d;\n  --shiki-light: #b56959;\n}\n.__shiki_9knfln {\n  --shiki-dark: #dbd7caee;\n  --shiki-light: #393a34;\n  --shiki-dark-bg: #121212;\n  --shiki-light-bg: #ffffff;\n}\n```\n\n### `transformerRemoveComments`\n\nRemove comments from the code. It works by checking the internal grammar token metadata to determine if the token is a comment.\n\nThis transformer requires `includeExplanation: true` to work.\n\n```ts\nimport { transformerRemoveComments } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  includeExplanation: true, // [!code highlight]\n  transformers: [\n    transformerRemoveComments(), // [!code highlight]\n  ],\n})\n```\n\nOptions:\n\n- `removeEmptyLines`: Remove lines that become empty after removing comments. Default `true`.\n\nFor example:\n\n````md\n```js\n// This is a comment\nconst x = 1 // Inline comment\n/* Block comment */\nconst y = 2\n\n// Another comment\n```\n````\n\nWill renders:\n\n```js\nconst x = 1\nconst y = 2\n```\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":5921,"sizeBytes":17997},{"name":"twoslash.md","path":"docs/packages/twoslash.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/twoslash.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# @shikijs/twoslash\n\n<Badges name=\"@shikijs/twoslash\" />\n\nA Shiki transformer for [Twoslash](https://github.com/twoslashes/twoslash), provide inline type hover inside code blocks.\n\n[TwoSlash Notation Reference](https://twoslash.netlify.app/refs/notations).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm install -D @shikijs/twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/twoslash\n```\n\n:::\n\nThis package is **a transformer addon** to Shiki. This means that for every integration that supports passing Shiki transformers, you can use this package.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"b436269721bc02aa6e2b87b8db32bd8f1713dc97017fd91b867735e43ccd0ba0\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQARk2qVhgwabRcrYBOKlXSaZgN6lSB+yy9PI4wXC2qEXw1ippyRAAmAC+FHQ2DeBGIZDyNHoTDYnB4TRMyRE0BgaggAAk0MpWBZGKjYBYVqRJtMKLxDPM4BYAMJojGYrhoTzUgA8ACFhFA9lAADJyaaCZhXClc1y8tT4GCqAB8fAAvLLeAAFUgQZTsOAwNkksmy2LxRLrJGwRk41jLC4bADsAAZdvtDsdNg7qGsrjdCeisRbnpM3gAWD5fWRiKEA4GgnB4QgkcjnOhe5G8fAW4kyMlWtYbV3BkB7A5HJD5i6e2N+3YBpA2kPfcN/ABsUeoYNjkIT1CTcI4XD43vNuIJaIzpIOFKp3hpvHpZqxzNZU853N5AoOwtFvHFPJgUClMpg8osao1Wp1eoOBriCSSpp92Nx2fWSG2tYLTuLWzdZeueAHvsfKtXhrOsw1+F8ThbTAYxKOMoUTWESkYLB1RwdYMD4XQDgsaJqDgXCn1zQMznfItjlLD1fxKLDpn9YDEAADlAn4IyBEFWxgiF42hbskJQwwyEwPhZxgRcTD8Mk9n3VRlwlXdpMPBYjgPCwFIAJRgaYtRkNpvAAQTAaoAB8ukzA4+XYX42AAVTiSRZJ3PdpVUCkL2mWVCJfRsAGZHTIpAAFZzkom5lNUOi3hIz563AyN2Og8E4M7GEbmQ1DBIwyw7kiMgxMWHSbBy0gzH8QIQjCQr0mQABdXgTO5GB+ADKA8gKIo8AqtIojgIZSGkaUujK3osHYHAXhgJYqBWHMXwYpjSOdF9/mCy4qNufoioQIC3ldZiGyQNjo0SjseMQkAWF7RECq6h5HByAwvBMcwso29JMju/AXDcPKeFKnpOvuGJr2NZJrsB96xlawpijKH4qhqUR5gaJoWjaGAOkGno+kqwZbBGR4cgmKZNLmKdJpAabnwBO15sLRbThW8sSjBoqIaebaXx2EBorAiNA0BaqPjRPAjVvYBYl4bGboyUY9AoWJAQEdVlF4AByAABHIegAKzgAB6NBZZyVXDRvE1xakO9B1YeWwEV/hlbVrWQhNsBYlReRkjTXFeAVDoNGYSyrYA1hGAAAw9uAID2BZWAgaZGG4MOKQtyWaIsVW0DgVXbclsKYAzohLPgbUAFooDWIIc4lqXAenZAa7z7K3qN/RuApPW9d4NlS9L1MyBgRveE73gFjHmvBYV7g8lUVYkFAJN9jgbw8CzkBAUBIA=\"}\nimport {\n  transformerTwoslash,\n} from '@shikijs/twoslash'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst html = await codeToHtml(`console.log()`, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [\n    transformerTwoslash(), // <-- here\n    // ...\n  ],\n})\n```\n\nThe default output is unstyled. You need to add some extra CSS to make them look good.\n\nIf you want to run Twoslash on browsers or workers, reference to the [CDN Usage](#cdn-usage) section.\n\n## Renderers\n\nThanks to the flexibility of [`hast`](https://github.com/syntax-tree/hast), this transformer allows customizing how each piece of information is rendered in the output HTML with ASTs.\n\nWe provide two renderers built-in, and you can also create your own:\n\n---\n\n### `rendererRich`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-rich.ts)\n\n::: tip\nThis is the default renderer since v0.10.0.\n:::\n\nThis renderer provides a more explicit class name is prefixed with `twoslash-` for better scoping.\nIn addition, it runs syntax highlighting on the hover information.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"9bafe2d835b3a768cc39f5a28647084c02c621d41bbebd6324dead19238c244e\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAErsR+RhCzjJcAPyJei2fLLLVAeU0SwPfQBUA7hDisu+Q3LJkAOmHYBbLAhSNGkjTyUVfEoQKAgRBEQQAEEpNhpSMGZxElCPBV40fCzeLFJidnk4XgAjGDR0kpl+dloYKF4RFzgqzL94Ch97dkLeOAwwNGZaXnx2AHN8DgWQ/iCC/BhedjBVgro0ADpouEngpABOKlZZOcKkAEYAJipTubq8GTyTSOiOMFxEAAGKiqZikZhiMgXAC+FHQ2ABBGIUJe+yYbE4PAEwjEVgK4Osq1IfVIDicXTUGi01j0vFsBLgRJJZOcrgAkh5aBZqTZeABlWYAa3Y9OYhKCJJ8/kCwXxYsZErILIp0Vi8TwADEIWgghhsaJqQUIB0ZFlNsx+UL2HLxcSyAI1mhHKy4PgthMYHNwTyjlQTmCGIhHgBmK43O6Ie6Xahgt6B6gMplK50qq7bAHAkCg8GQ8hB4Ow+E4PCEEjkVH0dEcLh8NCJxWklOudSWbS00W25lN10c2Bc1vWbj6AXsYUdhV20hSgJBEJ1+VJxvk1yquIJEBasS6/W4yRGk0wM28C0j4U2ickh2kArdt3bGherJWOC+kD+s6IADs9zDYFuUUjaNXneRJ507ZNl1dX50yQZ4syKHN0iQQFC2oBES2RctqDRRJGFKDQyEwPhx0XZVXG5Z8Dk+YxSHbW93Bo3gAB9eGEWBmn+KBV3VRIAGFBBOCA/FyGiqh1XhYBECpNkIexeEPVR3V2V0IEEVh2lqETPC4v1TkDc4AFZf3/JAAA4XljECQGo8JoP+JBQ3gsFtShINUMwYtElLFFsMrXCMRrLSFFMSkB10fQGPCEKKO0Ic6XosIFGnGUQhs4KfioNV1xSY9WHSTJsk2NL7UKYp8KIaTSCqWp6ntUoYGaVp2k6LgemYPo4AGMAhhGMYJimGZ5kWIaVkdDYlONGh6Ffd9A3uQEjJAa4/wjJ4LNIOMPkS75VDsgFHOzFy8yeaEAF0QWgRFpVnXhgCCnb8Aoc9SNvXhoQEMphIAcgAAVdUd2AAKzgAB6J1IPwL6fB8MCLwgl01GAHxeHu0h9GKiJVEYPgQZB3gAB4AFpCZ8aFuGiPpJiQUB9lkOArDwNAEGhaEgA\"}\nimport { rendererRich, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererRich() // <--\n})\n```\n\nHere are a few examples with the built-in [`style-rich.css`](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-rich.css):\n\n<!-- eslint-skip -->\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"43c9a2581bdd8d8c26b6a00be668c361b400ca9c2034e576e137e282e9ec30ed\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808BLMG0gMwEMBjGAAgBVoESiDhoOpBogCMABioAbGGADmafEgAsVcaRUwpIQVGGLmuRPJBd8E7qyRyAvhXTYLBYmRE16eABRYpBA4khgAlAJCAHRojGhKiLxipMwqImISUtIAnIrKahqIAKw6EvqGcQm4ZmAW0lQ2dlwOiABMLm44eIQk5Dp0hlwQYGK8aEJJAEowHCZgChgAPMYQAHwZulKabfmq6lplegZ4EyYiCuaH1rak9t6IAGyd1O49Xv3Ug6fuvDNzI0WKzWvAAvLxgLxSLN5oteMgAAq8Zi8ADWMAwEDYAgAukl+IicQBuXhOEQmLgIRAgACyHHRvA4CgUvCCITIcXgyLAAihMMBGE2WS0AA49oUkGLqOUTtT/rDBbULNobs1WtIOq5Xt1qb1vAM/NTmKxODwoucqJlJEhigB2cUHRAq3QVPCrC5XJ2NW73cjtaQvTA6zx9HzfamBYKhTCRKqJZJoVKqIXWp55EBKfZFUrS46VeJKD11G3etUPTVdDwARwArmRFV9DSBI+ywrGCzAkik0impI905mJSUjq7qXGahnPTmmncWuXA29dR8w03/ABbAyEKCRADKibSsQgAFUsKEAMIcOAwfzhLv75NUClUkBnkZ9NBwRnM8b4PhMrC2AARgYjBcLwM6+p+KIcAmSYqOMEC8DWp5kFwl4wNEvaOLIViDo60gNLmo7UMeKGkBeV5FhY04+nOfoAMz0QuwZ6p8vhDCMYxnBA0z8gsyyrBslpbI40hSnhRTOjKlRCFRkqlrOrSyMxHhkMEnxWtkbT0Q62aNNAFhtMUmhWGwjCZhwG5MGAsC0LECBUIwUB4GpAC0Rkma50iaLarnFCuhgXmAkBoIycBwIwKg8hMvAAOTjrFvDAWhNZXsioWMJ+MHQnMrkCqyUYchgmH5CQCguaQ6lyYgUoQXRNoqe8oYGoYLbRhE4wdkkHBgA2mmONpuklkRsrUB21W1bRrTFI1S7NY2hhEBIvAAHI1muwGkEka0bWQr6jImNYtBAnxPngACCPIQIBABWMAtD+HChdCQTwMoH6MrwYDrZtvBYoyvVoswUDRLw53fgAUhwS07lwqRYKF327aQWXQrwjyaK5gHxLwbAKBAT1pK5WAQMaX0/WQcAlaIIkyCZQ1PCOo07Zt1VyApvpIMpWpBh4rEBQEG7qNAkQs3tnGHcdpDRFgEhXgAkiw/jdqod5wRQUJzIwtAAPxJEjm23uTyPkhAlJ4Pt76fudsFpAhAPcjQ+jSz4HAqFSyDICAst3GumxwWDtuqPbwxgO+juITBBtkJhOIUF7PuWSIdxQNrgdLQodZJQYADuMDKLwbQA1AvD0Y8j2hXAOBcIwZlcuofCAehf3Yg3xu/SiAAGKsqJ30QADpgPLrf4JljJ6Ot73Ip+IXJMhWCXDAUAaz3n45/E+Cfa9Zm0C3cWyLQiUSHwocRbA0Il7+tBzPdjBrkyA9gODLIQA3pBB+748n5xTlkEvvCwBrvfBQsc4402FHTe0GYCiOilC6UaPsFYsDZlYOqrRbSzWsBANcC8QIjCwnTcSMCiioOwbguInEkCoHAJZDwiCYAADF8ZPREKiYGeAhZblYcDGk0Ba6MEpngQBChj4ZBOmgfg4YQAERAC8MAtC8D0MVgwKgbCbIcM3NAbhNleGpzrijIR90RHQjEZISRTYZFyIUdSNkExebaOcjYwqYQHG6P4YI6kwjRGWnEeYwwliwHDBwUoChowETQh3oolBHN6o1ScIEgy1kTTcD4KsCEg9eCdWqGrNIg8nCD0HqfUK3FeIAn4isIQIJwTAAyVk+MsUAAiMAQl8GYPYRgJAkJXhRrFQ8J5zzoRvBQPJBSWAxHHGCOKAAJZp+NYqjLFtLJRStYoanorFDWchwijMybsvZ+zeAAHpDm1IOWc45IghYcCQKAQYygIr4LHAgJwTggA=\"}\n// @errors: 2540\ninterface Todo {\n  title: string\n}\n\nconst todo: Readonly<Todo> = {\n  title: 'Delete inactive users'.toUpperCase(),\n//  ^?\n}\n\ntodo.title = 'Hello'\n\nNumber.parseInt('123', 10)\n//      ^|\n\n               //\n               //\n```\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c6f2791b81c2170bb12e4d54f17b345c35c290fb6b3e803987a0875ad1778705\",\"data\":\"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\"}\nimport { createHighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nconst highlighter = await createHighlighterCore({\n  engine: createJavaScriptRegexEngine()\n})\n\n// @log: Custom log message\nconst a = 1\n// @error: Custom error message\nconst b = 1\n// @warn: Custom warning message\nconst c = 1\n// @annotate: Custom annotation message\n```\n\n---\n\n### `rendererClassic`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-classic.ts)\n\nThis renderer aligns with the output of legacy [`shiki-twoslash`](https://github.com/shikijs/twoslash).\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"be50298f5ea6976d501abea603d4b03abe8280f3bf0a7b10df97e47172449e7c\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAMKsucdiMbdEvACoB3CHBVx8AJVnyyAHTDsAtlgik00i2TLLV6yiCgQRCIggOvgwvLD8zIKsLjJy7qS8bOwA5rZgKbx67Gj4vLlhTqnsYGy8AAYAAibsANbsAFZwAPRoBkZc+OW8EIJoWH0AdD5waMzOSACcVKyyKblIAIwArFRjpCkwDEFxlkrGaiI+HGC4iAAMVCL448xiZFMAvhTo2GcExA9rdNsgLBxcPhCUTiST5UjMMBwfhOOxkfSGYz4RgQLCgqEAfm0OghUJhpDhpARHRMAEl4rQAPJoiRQrS8ADK+Dq7BxkOhsOstgcThcaFxHIJ8PaSJ8fgCeAAYnc0E4MAJhGJafkILwRDJmDQkozmfVwez8YSBE58iLOrwSjQUhD0XBhlRRuNtgAmABsMzmC0Qi2m1HGm1+/INnKJZpMxxKZ0uIGut3u5EQbuerxweEIJHI33oTGSgP1eJDxKRKJpkjgWN0AsNwsRnXJsCppbp2iZLLZBaFpBs9kcznzgsJRc6Yv8gRA0rEcoVIOVsrVGq1zB1LP71cS+NNtZMFrAVpttLtI3W2wA7AAWD0ZL0+tb+rZ4IMdwdh/AR05IZ1XG4Q+NIc7J6g3jTT5M2oH4mCwUhUTITA+HbAcaxJfBqVtQZdgSCshxMcx4gUXgAB9eGECJIygEcJSCRRBFGCA7FcXCyDgFVwhgER2FgXhCD0XgYDuPIShhXgTF6VgoF4AAjMJ0JkMiHWPKYAA5L3mV9ECUv0NnvHY3AUN8zgAZi/OMaATZ0AMwVMgnTL4wOzIJ/k4Hh6L2Tw4EOTRsRfHC9m7Hk+2kjwDm8KhxTHEIwgiKIYmchIkg4NISkybJcnyUIelIYpSlYCpql1RoWjaLcuh6PoBjQe0QEdCZvXOdTZivVSVlvTTfgC/YvCOGZIyQQyY2/GUHm9MyAF0rmgd4e15XhgBihRXMOChV0LF9eEeAQoLogByXKWSaVoX02mwbEfBDQyKxhgBsXhZrIbQ2vm9RNF4Zpml4AAeABaD6bEebgfDhMYkFAH5ZDUSQHwQR5HiAA=\"}\nimport { rendererClassic, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererClassic() // <--\n})\n```\n\nYou might need to reference `shiki-twoslash`'s CSS to make it look good. [Here](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-classic.css) we also copied the CSS from `shiki-twoslash` but it might need some cleanup.\n\n### `rendererFloatingVue`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/vitepress-twoslash/src/renderer-floating-vue.ts)\n\nThis renderer outputs Vue template syntax that using [Floating Vue](https://floating-vue.starpad.dev/) as the popup component (to render it outside the containers). This renderer is **NOT** directly usable but an internal renderer for the [VitePress integration](/packages/vitepress#twoslash). Listing it here for reference if you want to create your own renderer.\n\n## Options\n\n### Explicit Trigger\n\nWhen integrating with `@shikijs/markdown-it` or `rehype-shiki`, we may not want Twoslash to run on every code block. In this case, we can set `explicitTrigger` to `true` to only run on code blocks with `twoslash` presented in the codeframe.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c33fc7b243f56e1595f93ca6e9e052fed95abb58a9edc5376b448c62984626f1\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQATipWGDBptFzEAEZt6jXpmA3qVIH7LL08jjBcRAAGKhF8NYqaci2AL4UdDYV4EYhkPI0ehMNicHh9GyRe6OHIGLwmcyWW7IjKjZyuOieeY8fyBEJhJHpWLxRLrRFpKKZVG5KgFIp4cqVUjVISieYNJotNowDpdcm9GT9XFDUgjB45CZTGCzNreOBLKgrNYbACsAHYdnsDkdTlRVqRLtcpVSmfick9Jq8AEyfb6yMSQ95AkE4PCEEjkc10a6MLCkQxkTB8SmMlFjYnqhZ0LAcETsNBWdjTS6kLEAIwgEF2cl4AB9eAAlFUAUVoWHLvGEsH4TqgeXZxRA1YAjoJ2C04LwAAZoe34YeC/Oi8PwPY0KBK6T4UUiaCi/OsQpBXiqVaC5hYVPVQ7sIc2uNB87TYrIZD5GD8ZiCVgMKhP1hwXAAXW/WotGwABzHEa+yHEgxy6uaFxXHgKZphmWY5pCOxOkgADMbo/J6/zOgCf4gGusB4LSSS8MADJ3HiCrjACAgRsovAAOQAAI5D0ABWcAAPRjjRTGxLEF5UcyYyMMAsS8Lw8HsOmmakNmuYWDIgiitx3G8AAPAAtNpsQAtweR7swSCgCGexwN4eBoAgAIAkAA=\"}\nimport { transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  explicitTrigger: true // <--\n})\n```\n\n````md\nIn markdown, you can use the following syntax to trigger Twoslash:\n\n```ts\n// this is a normal code block\n```\n\n```ts twoslash\n// this will run Twoslash\n```\n````\n\n## Integrations\n\nWhile you can set up Twoslash with Shiki on your own with the instructions above, you can also find high-level integrations with frameworks and tools here:\n\n- [VitePress](/packages/vitepress#twoslash) - A plugin to enable Twoslash support in VitePress.\n- [Nuxt](/packages/nuxt#twoslash-integration) - A module to enable Twoslash for Nuxt Content.\n- [Vocs](https://vocs.dev/docs/guides/twoslash) - Vocs has TwoSlash support built-in.\n- [Slidev](https://sli.dev/features/twoslash#twoslash-integration) - Slidev has TwoSlash support built-in.\n\n## Recipes\n\n### CDN Usage\n\nBy default [`twoslash`](https://github.com/twoslashes/twoslash/tree/main/packages/twoslash) runs on Node.js and relies on your local system to resolve TypeScript and types for the imports. Import it directly in non-Node.js environments would not work.\n\nLuckily, Twoslash implemented a virtual file system, which allow you to provide your own files for TypeScript to resolve in memory. However, loading these files in the browser is still a challenge. Thanks to the work on the [TypeScript WebSite](https://github.com/microsoft/TypeScript-Website), the TypeScript team has provided some utilities to fetch types on demand through CDN, they call it [Automatic Type Acquisition (ATA)](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ata).\n\nWe make tiny wrappers around the building blocks and provide an easy-to-use API in [`twoslash-cdn`](https://twoslash.netlify.app/packages/cdn). For example:\n\n```js\n// FIXME: Replace with explicit versions in production\nimport { createTransformerFactory, rendererRich } from 'https://esm.sh/@shikijs/twoslash@latest/core'\nimport { codeToHtml } from 'https://esm.sh/shiki@latest'\nimport { createTwoslashFromCDN } from 'https://esm.sh/twoslash-cdn@latest'\nimport { createStorage } from 'https://esm.sh/unstorage@latest'\nimport indexedDbDriver from 'https://esm.sh/unstorage@latest/drivers/indexedb'\n\n// ============= Initialization =============\n\n// An example using unstorage with IndexedDB to cache the virtual file system\nconst storage = createStorage({\n  driver: indexedDbDriver({ base: 'twoslash-cdn' }),\n})\n\nconst twoslash = createTwoslashFromCDN({\n  storage,\n  compilerOptions: {\n    lib: ['esnext', 'dom'],\n  },\n})\n\nconst transformerTwoslash = createTransformerFactory(twoslash.runSync)({\n  renderer: rendererRich(),\n})\n\n// ============= Execution =============\n\nconst app = document.getElementById('app')\n\nconst source = `\nimport { ref } from 'vue'\n\nconsole.log(\"Hi! Shiki + Twoslash on CDN :)\")\n\nconst count = ref(0)\n//     ^?\n`.trim()\n\n// Before rendering, we need to prepare the types, so that the rendering can happen synchronously\nawait twoslash.prepareTypes(source)\n\n// Then we can render the code\napp.innerHTML = await codeToHtml(source, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [transformerTwoslash],\n})\n```\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":8755,"sizeBytes":17260},{"name":"vitepress.md","path":"docs/packages/vitepress.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/packages/vitepress.md","title":"Packages Skill","category":"anthropic-skill","format":"markdown","content":"---\noutline: deep\n---\n\n# VitePress Integration\n\n[VitePress](https://vitepress.dev/) uses Shiki under the hood, so you don't need explicit integration.\n\nVitePress provides [a few options for customizing Shiki](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts#L66-L112). Learn more about them in the [VitePress documentation](https://vitepress.dev/reference/site-config#markdown).\n\n## Twoslash\n\nTo enable [TypeScript Twoslash](/packages/twoslash) (type hover on code snippets) in VitePress, we provide a VitePress plugin for easy setup. Pre-styled, with [Floating Vue](https://floating-vue.starpad.dev/) to display the type information out side of the code container.\n\n<Badges name=\"@shikijs/vitepress-twoslash\" />\n\n### Setup\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/vitepress-twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/vitepress-twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/vitepress-twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/vitepress-twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/vitepress-twoslash\n```\n\n:::\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash() // [!code hl]\n    ],\n    // [!code hl:2]\n    // Explicitly load these languages for types highlighting\n    languages: ['js', 'jsx', 'ts', 'tsx']\n  }\n})\n```\n\nAnd then in your [`.vitepress/theme/index.ts`](https://vitepress.dev/guide/custom-theme), install the Vue plugin and import the css with `@shikijs/vitepress-twoslash/styles.css`.\n\n```ts twoslash [.vitepress/theme/index.ts]\n// @twoslash-cache: {\"v\":1,\"hash\":\"2a5df659524ba4854bc92abbfbd15feefdb74ba936c5a020d6bdc7d308b959b2\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAJ2wNUgDNmAYxi8AomHzMwEgIJYsAYQiC6aADph2AWywRSaabPlKV6zfUog4aZiaQBGACxVWMMAHM0+VwB2KkdSHxgGRBAZOQUYZTUNGltPAVxEAAYqMTlScSFXNwBfCnRsdIJiMjtkyJAWDi4+MQ0HXgAVAHcIOFYufAAxVghmNAEfADUAVxhEXmBdXiX+MAc2VjmWFTmEil4ILDHWgH45oZGx32mYa2F2Hz4AXgA+XiIIdigAbl0i3QMjCYOt1ev1zqNxtc7FAIGIEFFrrwsKwpj4BLw0BAVmtWKxeODLpMZrxOux/LwHBgvHAAHS6XQASUMxlM/nYcF4wimCiOYBWvAABjSiGSYFhSPA4AB6fwwfQwKUCWC0GloOAC3jyKC8KZwSQC5gqGm6mCMLo9PpwQbDCFXGbcDUCOCfSSywXeWKWLAawgQADWNLsa2ciAArAAOTzePwBRAuACcISc4Tq5tBVoJkJmdg4YHSLmyuXy1UQgRKZRweEIJHIIS0TDYnB4vBaq1M7Xwctm80WywAMswMBApmg5gARGB3PPqZl5wQ/PnLD0WeLbXiMMRoWhzGIrhLWWpPV7vT4Lv56ZlAjtdoOhSLuAsgLy+fxIUNJsIRPDX+U5tJIAAmQsnGLchS3LahyirKpa2oesokYcUDjITA+C0bwoDgOYFkXJYByHEdx0nNIZyMOc0AXZZeGXOIEk2TdtzMT1V0SGw0CPN4Pm+X5bycSIANDICn2jV9Sw/FM8HQsBML/PMkGCEAchAzcSwAiDMErKJq2qOtbAQxsmhbVp207eVsN7PDB2HUdeAnKcbggWdvAoizqPMWi1w3Lcd3cr0Dy0DiT24sBzwBFkOlM3AqGDfiADZH2fGM33Er8oh/KKn3/MTFKLFSwJcFx1KgrSYJqeD6nlfxoDQ3yWMYYBNRUXgih85j9ySAK5iC3iQwAwIsmEl9YxcAbQgkqIaK9WT0kjHLlIKRA1NKSDNMqGsyr0+osBAyqyD4Q0sB2FQAB55AwZ4ev48MAGYoyGpBbuoZNUpAA7pqQWalLyPLXFDIrVu02DagbRpmwEIRRAkJi9ysDr6H+S9TF3DzWOB6K70A+MBsS0SXAUsaXuRvy4YYVI5MQT7coWgClorCpAY2upEJ2iI9saw7eASU6wHOy6Hpcd9BqSxBHoJuo3rJ9JEzm76FuKZaNPp0rdKZyrCCgPgubO55jT1Y7kAOXk4FOTUeYAXWeRCUTRMA5gABWtgR9cN9gTjmM6zb2A3Dld1YTY9549hpYOXdaOYADkIAZMBhDIZ2fbd02MAt7gjqwbnzvXABqFx9hrG0Nb5kWEzu4XReeuoTXexBpa+0CPv+pX1pVkGm2aYzgQtMEbUJa5zNw7FHFxTYDrTvZQ79s4e6zByY/uQKuLPBHAXbEFLWtC4Z+hWF4RARFkVRdFMUH9Z8Wnu1JFJclKWpOkwEZRGMXwdlOW5Tdff5IURRocVJRlSLFTSToKqdUpttQmkFAdXWpo0zr0zBfB02IXRP31JNFiPoID+kDOjPiD0AKPRxsNaWYtvxr27pvC+1da5UxLC4NSntFLQAqGFIEit5jQxRv5egzVOSkEcrwAA5N/MUEo4BwAEcvcKsDyG2iJJIYQfD9CCIAAJWnYH6dgAAraUwjf5iIALRoDIVaKUYgODOQEbwKUUpeDIAAIQtFgLwfArAzaSKvJFXh/ChGij0dKWU8oJH3wvCvFRaiNHaKlLo0RcBDHGPwFKG+MAaRwnEVYmx9jHGSBcW44JdBQmwFEFMVgpgcJLCkphOY6UKC9jQQkeq7NmqtRhqjAKPYB5QJNGaeJ8C5F8GsbYhxTDnGuN7CUHiVBKrMCQKAKSzoNB4DVCAIoRQgA=\"}\n// @noErrors: true\nimport type { EnhanceAppContext } from 'vitepress'\nimport TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' // [!code hl]\nimport Theme from 'vitepress/theme'\n\nimport '@shikijs/vitepress-twoslash/style.css' // [!code hl]\n\nexport default {\n  extends: Theme,\n  enhanceApp({ app }: EnhanceAppContext) {\n    app.use(TwoslashFloatingVue) // [!code hl]\n  },\n}\n```\n\n::: details About style.css\n\nFor easier setup, `@shikijs/vitepress-twoslash/styles.css` bundles the styles from `floating-vue` and `@shikijs/twoslash/style-rich.css` so you only need a single entry. If you are using a custom `floating-vue` style or want to have more control of the styles, you can expand them as:\n\n```ts\nimport '@shikijs/vitepress-twoslash/style.css'\n\n// Equivalent to:\nimport '@shikijs/twoslash/style-rich.css'\nimport 'floating-vue/dist/style.css'\nimport '@shikijs/vitepress-twoslash/style-core.css'\n```\n\n:::\n\nThat's it, you can now use `ts twoslash` in your markdown files to enable the beautiful type hover.\n\n````md\n```ts twoslash\nconsole.log('hello')\n//      ^?\n```\n````\n\nIt will be rendered as:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"258fd8e6b019224fc5515598774b6ccef0d85eefda3a3ba0992cbaa911ba9952\",\"data\":\"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\"}\nconsole.log('hello')\n//      ^?\n```\n\n<div class=\"h-100\" /> <!-- leaving some space for the query above -->\n\n### Vue Single File Component\n\nIn addition, this plugin also integrated [`twoslash-vue`](https://twoslash.netlify.app/packages/vue) for you, so that you can also highlight Vue SFC blocks with `vue twoslash`:\n\n```vue twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"e44d27459becb1dd99d3f24e24e643e1cd8fe190f90d461e4713e08207fe0a39\",\"data\":\"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\"}\n<script setup>\nimport { onMounted, ref } from 'vue'\n\n// reactive state\nconst count = ref(0)\n//             ^?\n\n// functions that mutate state and trigger updates\nfunction increment() {\n  count.value++\n}\n\n// lifecycle hooks\nonMounted(() => {\n  console.log(`The initial count is ${count.value}.`)\n})\n</script>\n\n<template>\n  <button @click=\"increment\">\n    Count is: {{ count }}\n  </button>\n</template>\n```\n\n### File System Cache\n\nTo speed up the build process, you can enable the file system cache for the generated types, that shares across multiple builds. By default the cache is stored in the `.vitepress/cache/twoslash` along with other VitePress caches.\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash'\nimport { createFileSystemTypesCache } from '@shikijs/vitepress-twoslash/cache-fs' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash({\n        typesCache: createFileSystemTypesCache() // [!code hl]\n      })\n    ]\n  }\n})\n```\n\n### Inline Cache (experimental)\n\nYou can enable inline caching for the generated types. The `@twoslash-cache: ...` will auto insert into your fenced code block during development and build time.\n\n````md [./your-file.md]{2}\n```ts twoslash\n// @twoslash-cache: [auto generated]\nconst a: string = 'foo'\n```\n````\n\nTo enable the inline cache in your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config), please use the config wrapper created by `createTwoslashWithInlineCache`.\n\n```ts [.vitepress/config.ts]\nimport { createTwoslashWithInlineCache } from '@shikijs/vitepress-twoslash/cache-inline' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nconst withTwoslashInlineCache = createTwoslashWithInlineCache({ // [!code hl]\n  // ... config of transformerTwoslash // [!code hl]\n}) // [!code hl]\n\nexport default withTwoslashInlineCache( // [!code hl]\n  defineConfig({\n    markdown: {\n      codeTransformers: [\n        // move config to the `createTwoslashWithInlineCache()` // [!code error]\n        // transformerTwoslash({ ... }) // [!code error]\n      ]\n    }\n  })\n) // [!code hl]\n```\n\n#### Force re-generate inline cache\n\nTo force re-generate the inline cache and ignore the existing cache, you can use the `TWOSLASH_INLINE_CACHE_IGNORE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress build\n```\n\n#### Remove inline cache\n\nTo remove all inline cache, you can use the `TWOSLASH_INLINE_CACHE_REMOVE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress build\n```\n","frontmatter":{"outline":"deep"},"isInternal":false,"tokens":8957,"sizeBytes":16608},{"name":"engine-js-compat.md","path":"docs/references/engine-js-compat.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/references/engine-js-compat.md","title":"References Skill","category":"anthropic-skill","format":"markdown","content":"# JavaScript RegExp Engine Compatibility References\n\nCompatibility reference of all built-in grammars with the [JavaScript RegExp engine](/guide/regex-engines#javascript-regexp-engine).\n\n> Generated on Friday, September 11, 2026\n>\n> Version `4.4.3`\n>\n> Runtime: Node.js v24.16.0\n\n## Report Summary\n\n|                 |                       Count |\n| :-------------- | --------------------------: |\n| Total Languages |                         238 |\n| Supported       | [237](#supported-languages) |\n| Mismatched      |  [0](#mismatched-languages) |\n| Unsupported     | [1](#unsupported-languages) |\n\n## Supported Languages\n\nLanguages that work with the JavaScript RegExp engine, and will produce the same result as the WASM engine (with the [sample snippets in the registry](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples)).\nIn some edge cases, it's not guaranteed that the highlighting will be 100% the same. If that happens, please create an issue with the sample snippet.\n\n| Language           | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| ------------------ | :-------------- | ----------------: | --------------: | ---: |\n| abap               | ✅ OK           |                52 |               - |      |\n| actionscript-3     | ✅ OK           |                59 |               - |      |\n| ada                | ✅ OK           |               200 |               - |      |\n| ahk                | ✅ OK           |               125 |               - |      |\n| angular-html       | ✅ OK           |               669 |               - |      |\n| angular-ts         | ✅ OK           |               776 |               - |      |\n| apache             | ✅ OK           |                60 |               - |      |\n| apex               | ✅ OK           |               197 |               - |      |\n| apl                | ✅ OK           |               912 |               - |      |\n| applescript        | ✅ OK           |               152 |               - |      |\n| ara                | ✅ OK           |                54 |               - |      |\n| asciidoc           | ✅ OK           |               319 |               - |      |\n| asm                | ✅ OK           |               298 |               - |      |\n| astro              | ✅ OK           |               610 |               - |      |\n| awk                | ✅ OK           |                36 |               - |      |\n| ballerina          | ✅ OK           |               224 |               - |      |\n| bat                | ✅ OK           |                58 |               - |      |\n| beancount          | ✅ OK           |                42 |               - |      |\n| berry              | ✅ OK           |                21 |               - |      |\n| bibtex             | ✅ OK           |                19 |               - |      |\n| bicep              | ✅ OK           |                31 |               - |      |\n| bird2              | ✅ OK           |               146 |               - |      |\n| blade              | ✅ OK           |              1122 |               - |      |\n| bsl                | ✅ OK           |                97 |               - |      |\n| c                  | ✅ OK           |               176 |               - |      |\n| c3                 | ✅ OK           |               125 |               - |      |\n| cadence            | ✅ OK           |               128 |               - |      |\n| cairo              | ✅ OK           |               236 |               - |      |\n| chapel             | ✅ OK           |               214 |               - |      |\n| clarity            | ✅ OK           |                42 |               - |      |\n| clojure            | ✅ OK           |                38 |               - |      |\n| cmake              | ✅ OK           |                23 |               - |      |\n| cobol              | ✅ OK           |               858 |               - |      |\n| codeowners         | ✅ OK           |                 4 |               - |      |\n| codeql             | ✅ OK           |               147 |               - |      |\n| coffee             | ✅ OK           |               466 |               - |      |\n| common-lisp        | ✅ OK           |                60 |               - |      |\n| coq                | ✅ OK           |                28 |               - |      |\n| cpp                | ✅ OK           |               468 |               - |      |\n| crystal            | ✅ OK           |              1054 |               - |      |\n| csharp             | ✅ OK           |               315 |               - |      |\n| css                | ✅ OK           |               141 |               - |      |\n| csv                | ✅ OK           |                 1 |               - |      |\n| cue                | ✅ OK           |                85 |               - |      |\n| cypher             | ✅ OK           |                39 |               - |      |\n| d                  | ✅ OK           |               272 |               - |      |\n| dart               | ✅ OK           |                79 |               - |      |\n| dax                | ✅ OK           |                23 |               - |      |\n| desktop            | ✅ OK           |                16 |               - |      |\n| diff               | ✅ OK           |                16 |               - |      |\n| docker             | ✅ OK           |                 7 |               - |      |\n| dotenv             | ✅ OK           |                 9 |               - |      |\n| dream-maker        | ✅ OK           |                56 |               - |      |\n| edge               | ✅ OK           |               629 |               - |      |\n| elixir             | ✅ OK           |               704 |               - |      |\n| elm                | ✅ OK           |               241 |               - |      |\n| emacs-lisp         | ✅ OK           |               155 |               - |   22 |\n| erb                | ✅ OK           |              1816 |               - |      |\n| erlang             | ✅ OK           |               270 |               - |      |\n| fennel             | ✅ OK           |                31 |               - |      |\n| fish               | ✅ OK           |                34 |               - |      |\n| fluent             | ✅ OK           |                23 |               - |      |\n| fortran-fixed-form | ✅ OK           |               346 |               - |      |\n| fortran-free-form  | ✅ OK           |               339 |               - |      |\n| fsharp             | ✅ OK           |               242 |               - |      |\n| gdresource         | ✅ OK           |               157 |               - |      |\n| gdscript           | ✅ OK           |                94 |               - |      |\n| gdshader           | ✅ OK           |                39 |               - |      |\n| genie              | ✅ OK           |                20 |               - |      |\n| gherkin            | ✅ OK           |                19 |               - |      |\n| gleam              | ✅ OK           |                26 |               - |      |\n| glimmer-js         | ✅ OK           |               673 |               - |      |\n| glimmer-ts         | ✅ OK           |               673 |               - |      |\n| glsl               | ✅ OK           |               185 |               - |      |\n| gn                 | ✅ OK           |                19 |               - |      |\n| gnuplot            | ✅ OK           |                82 |               - |      |\n| go                 | ✅ OK           |               126 |               - |      |\n| graphql            | ✅ OK           |               445 |               - |      |\n| groovy             | ✅ OK           |               130 |               - |      |\n| hack               | ✅ OK           |               946 |               - |      |\n| haml               | ✅ OK           |               559 |               - |      |\n| handlebars         | ✅ OK           |               696 |               - |      |\n| haskell            | ✅ OK           |               157 |               - |      |\n| haxe               | ✅ OK           |               173 |               - |      |\n| hcl                | ✅ OK           |                67 |               - |      |\n| hjson              | ✅ OK           |                57 |               - |      |\n| hlsl               | ✅ OK           |                52 |               - |      |\n| html               | ✅ OK           |               608 |               - |      |\n| http               | ✅ OK           |               746 |               - |      |\n| hurl               | ✅ OK           |               611 |               - |      |\n| hxml               | ✅ OK           |               182 |               - |      |\n| hy                 | ✅ OK           |                12 |               - |      |\n| imba               | ✅ OK           |               239 |               - |      |\n| ini                | ✅ OK           |                11 |               - |      |\n| java               | ✅ OK           |               141 |               - |      |\n| javascript         | ✅ OK           |               375 |               - |      |\n| jinja              | ✅ OK           |               639 |               - |      |\n| jison              | ✅ OK           |               431 |               - |      |\n| json               | ✅ OK           |                19 |               - |      |\n| json5              | ✅ OK           |                23 |               - |      |\n| jsonc              | ✅ OK           |                19 |               - |      |\n| jsonl              | ✅ OK           |                19 |               - |      |\n| jsonnet            | ✅ OK           |                33 |               - |      |\n| jssm               | ✅ OK           |                30 |               - |      |\n| jsx                | ✅ OK           |               375 |               - |      |\n| julia              | ✅ OK           |              1177 |               - |      |\n| just               | ✅ OK           |              2148 |               - |      |\n| kdl                | ✅ OK           |                30 |               - |      |\n| kotlin             | ✅ OK           |                58 |               - |      |\n| kusto              | ✅ OK           |                60 |               - |      |\n| latex              | ✅ OK           |               312 |               - |      |\n| lean               | ✅ OK           |                31 |               - |      |\n| less               | ✅ OK           |               279 |               - |      |\n| liquid             | ✅ OK           |               689 |               - |      |\n| llvm               | ✅ OK           |                25 |               - |      |\n| log                | ✅ OK           |                31 |               - |      |\n| logo               | ✅ OK           |                 9 |               - |      |\n| lua                | ✅ OK           |               279 |               - |      |\n| luau               | ✅ OK           |                95 |               - |      |\n| make               | ✅ OK           |                51 |               - |      |\n| markdown           | ✅ OK           |               123 |               - |      |\n| marko              | ✅ OK           |               929 |               - |      |\n| matlab             | ✅ OK           |                88 |               - |      |\n| mdc                | ✅ OK           |               786 |               - |      |\n| mdx                | ✅ OK           |               197 |               - |      |\n| mermaid            | ✅ OK           |               175 |               - |      |\n| mipsasm            | ✅ OK           |                17 |               - |      |\n| mojo               | ✅ OK           |               215 |               - |      |\n| moonbit            | ✅ OK           |               101 |               - |      |\n| move               | ✅ OK           |               113 |               - |      |\n| narrat             | ✅ OK           |                34 |               - |      |\n| nextflow           | ✅ OK           |               107 |               - |      |\n| nginx              | ✅ OK           |               378 |               - |      |\n| nim                | ✅ OK           |              1122 |               - |      |\n| nix                | ✅ OK           |                83 |               - |      |\n| nsis               | ✅ OK           |                38 |               - |      |\n| nushell            | ✅ OK           |                85 |               - |      |\n| objective-c        | ✅ OK           |               222 |               - |      |\n| objective-cpp      | ✅ OK           |               306 |               - |      |\n| ocaml              | ✅ OK           |               178 |               - |      |\n| odin               | ✅ OK           |                98 |               - |      |\n| openscad           | ✅ OK           |                24 |               - |      |\n| org                | ✅ OK           |              4715 |               - |      |\n| pascal             | ✅ OK           |                23 |               - |      |\n| perl               | ✅ OK           |               937 |               - |      |\n| php                | ✅ OK           |              1125 |               - |      |\n| pkl                | ✅ OK           |                67 |               - |      |\n| plsql              | ✅ OK           |                45 |               - |      |\n| po                 | ✅ OK           |                23 |               - |      |\n| polar              | ✅ OK           |                31 |               - |      |\n| postcss            | ✅ OK           |                49 |               - |      |\n| powerquery         | ✅ OK           |                30 |               - |      |\n| powershell         | ✅ OK           |                88 |               - |      |\n| prisma             | ✅ OK           |                31 |               - |      |\n| prolog             | ✅ OK           |                26 |               - |      |\n| proto              | ✅ OK           |                33 |               - |      |\n| pug                | ✅ OK           |               683 |               - |      |\n| puppet             | ✅ OK           |                60 |               - |      |\n| purescript         | ✅ OK           |                87 |               - |      |\n| python             | ✅ OK           |               218 |               - |      |\n| qml                | ✅ OK           |               407 |               - |      |\n| qmldir             | ✅ OK           |                 7 |               - |      |\n| qss                | ✅ OK           |                31 |               - |      |\n| r                  | ✅ OK           |                66 |               - |      |\n| racket             | ✅ OK           |                69 |               - |      |\n| raku               | ✅ OK           |                52 |               - |      |\n| razor              | ✅ OK           |               960 |               - |      |\n| rbs                | ✅ OK           |                33 |               - |      |\n| reg                | ✅ OK           |                 9 |               - |      |\n| regexp             | ✅ OK           |                34 |               - |      |\n| rel                | ✅ OK           |                17 |               - |      |\n| riscv              | ✅ OK           |                36 |               - |      |\n| ron                | ✅ OK           |                35 |               - |      |\n| rosmsg             | ✅ OK           |                31 |               - |      |\n| rst                | ✅ OK           |              2057 |               - |      |\n| ruby               | ✅ OK           |              1808 |               - |      |\n| rust               | ✅ OK           |                89 |               - |      |\n| sas                | ✅ OK           |               100 |               - |      |\n| sass               | ✅ OK           |                69 |               - |      |\n| scala              | ✅ OK           |               116 |               - |      |\n| scheme             | ✅ OK           |                34 |               - |      |\n| scss               | ✅ OK           |               233 |               - |      |\n| sdbl               | ✅ OK           |                23 |               - |      |\n| shaderlab          | ✅ OK           |                87 |               - |      |\n| shellscript        | ✅ OK           |               147 |               - |      |\n| shellsession       | ✅ OK           |               149 |               - |      |\n| smalltalk          | ✅ OK           |                64 |               - |      |\n| smithy             | ✅ OK           |                42 |               - |      |\n| solidity           | ✅ OK           |               105 |               - |      |\n| soy                | ✅ OK           |               646 |               - |      |\n| sparql             | ✅ OK           |                19 |               - |      |\n| splunk             | ✅ OK           |                17 |               - |      |\n| sql                | ✅ OK           |                68 |               - |      |\n| ssh-config         | ✅ OK           |                12 |               - |      |\n| stata              | ✅ OK           |               254 |               - |      |\n| stylus             | ✅ OK           |               106 |               - |      |\n| surrealql          | ✅ OK           |               467 |               - |      |\n| svelte             | ✅ OK           |               646 |               - |      |\n| swift              | ✅ OK           |               340 |               - |      |\n| system-verilog     | ✅ OK           |               102 |               - |      |\n| systemd            | ✅ OK           |                32 |               - |      |\n| talonscript        | ✅ OK           |                46 |               - |      |\n| tasl               | ✅ OK           |                23 |               - |      |\n| tcl                | ✅ OK           |                34 |               - |      |\n| templ              | ✅ OK           |               674 |               - |      |\n| terraform          | ✅ OK           |                68 |               - |      |\n| tex                | ✅ OK           |               103 |               - |      |\n| toml               | ✅ OK           |                44 |               - |      |\n| ts-tags            | ✅ OK           |               997 |               - |      |\n| tsv                | ✅ OK           |                 1 |               - |      |\n| tsx                | ✅ OK           |               375 |               - |      |\n| turtle             | ✅ OK           |                15 |               - |      |\n| twig               | ✅ OK           |              2445 |               - |      |\n| typescript         | ✅ OK           |               362 |               - |      |\n| typespec           | ✅ OK           |                73 |               - |      |\n| typst              | ✅ OK           |              5699 |               - |      |\n| v                  | ✅ OK           |                77 |               - |      |\n| vala               | ✅ OK           |                20 |               - |      |\n| vb                 | ✅ OK           |                34 |               - |      |\n| verilog            | ✅ OK           |                34 |               - |      |\n| vhdl               | ✅ OK           |                82 |               - |      |\n| viml               | ✅ OK           |                72 |               - |      |\n| vue                | ✅ OK           |               705 |               - |      |\n| vue-html           | ✅ OK           |               404 |               - |      |\n| vue-vine           | ✅ OK           |              1032 |               - |      |\n| vyper              | ✅ OK           |               238 |               - |      |\n| wasm               | ✅ OK           |                78 |               - |      |\n| wenyan             | ✅ OK           |                18 |               - |      |\n| wgsl               | ✅ OK           |                44 |               - |      |\n| wikitext           | ✅ OK           |               105 |               - |      |\n| wit                | ✅ OK           |                81 |               - |      |\n| wolfram            | ✅ OK           |               501 |               - |      |\n| xml                | ✅ OK           |               168 |               - |      |\n| xsl                | ✅ OK           |               170 |               - |      |\n| yaml               | ✅ OK           |                48 |               - |      |\n| zenscript          | ✅ OK           |                21 |               - |      |\n| zig                | ✅ OK           |                51 |               - |      |\n\n###### Table Field Explanations\n\n- **Highlight Match**: Whether the highlighting results matched with the WASM engine for the [sample snippet](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples).\n- **Patterns Parsable**: Number of regex patterns that can be parsed by the JavaScript RegExp engine.\n- **Patterns Failed**: Number of regex patterns that can't be parsed by the JavaScript RegExp engine (throws error).\n- **Diff**: Length of characters that are different between the highlighting results of the two engines.\n\n## Mismatched Languages\n\nLanguages that do not throw with the JavaScript RegExp engine, but will produce different results than the WASM engine.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n\n## Unsupported Languages\n\nLanguages that throw with the JavaScript RegExp engine, either because they contain syntax we can't polyfill yet or because the grammar contains an invalid Oniguruma regex (that would also fail when using the WASM engine, but silently). You can try these languages with the `forgiving` option to skip errors.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n| ahk2     | ❌ Error        |               188 |               1 |   16 |\n","isInternal":false,"tokens":4997,"sizeBytes":23195},{"name":"api.md","path":"docs/api.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/docs/api.md","title":"docs - API Interface Contract & Specifications","category":"project-spec","format":"markdown","content":"# API References\n\n## `codeToHast`\n\nYou can also get the intermediate `hast` to do custom rendering without serializing them into HTML with `codeToHast`. You can also further integrate the AST with the [unified](https://github.com/unifiedjs) ecosystem.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"aa0ea59b9742ed721640f4d1233696e3e09408080ce58a4fde6a5efd7f40382b\",\"data\":\"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=\"}\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord', 'min-light'],\n  langs: ['javascript'],\n})\n// ---cut---\nconst root = highlighter.codeToHast(\n  'const a = 1',\n  { lang: 'javascript', theme: 'nord' }\n)\n\nconsole.log(root)\n```\n\n<!-- eslint-skip -->\n\n```ts\n{\n  type: 'root',\n  children: [\n    {\n      type: 'element',\n      tagName: 'pre',\n      properties: {\n        class: 'shiki vitesse-light',\n        style: 'background-color:#ffffff;color:#393a34',\n        tabindex: '0'\n      },\n      children: [\n        {\n          type: 'element',\n          tagName: 'code',\n          properties: {},\n          children: [\n            {\n              type: 'element',\n              tagName: 'span',\n              properties: { class: 'line' },\n              children: [\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#AB5959' },\n                  children: [ { type: 'text', value: 'const' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#B07D48' },\n                  children: [ { type: 'text', value: ' a' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#999999' },\n                  children: [ { type: 'text', value: ' =' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#2F798A' },\n                  children: [ { type: 'text', value: ' 1' } ]\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}\n```\n","isInternal":false,"tokens":3051,"sizeBytes":5743},{"name":"README.md","path":"packages/cli/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/cli/README.md","title":"cli Documentation","category":"plugin-manifest","format":"markdown","content":"# shiki-cli\n\nShiki in the command line.\n\n[Documentation](https://shiki.style/packages/cli)\n\n## License\n\nMIT\n","isInternal":false,"tokens":28,"sizeBytes":108},{"name":"README.md","path":"packages/codegen/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/codegen/README.md","title":"codegen Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/codegen\n\nCodegen for fine-grained Shiki bundles.\n\n[Documentation](https://shiki.style/packages/codegen)\n\n## License\n\nMIT\n","isInternal":false,"tokens":35,"sizeBytes":132},{"name":"README.md","path":"packages/colorized-brackets/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/colorized-brackets/README.md","title":"colorized-brackets Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/colorized-brackets\n\nVSCode-style colorized brackets transformer for [Shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/colorized-brackets)\n\n## License\n\nMIT\n","isInternal":false,"tokens":51,"sizeBytes":205},{"name":"README.md","path":"packages/core/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/core/README.md","title":"core Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/core\n\nThe core functionality of [Shiki](https://github.com/shikijs/shiki), without any grammar of themes bundled.\n\nIt's the same as importing `shiki/core`.\n","isInternal":false,"tokens":43,"sizeBytes":167},{"name":"README.md","path":"packages/engine-javascript/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/engine-javascript/README.md","title":"engine-javascript Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/engine-javascript\n\nEngine for Shiki using JavaScript's native RegExp. Uses [Oniguruma-To-ES](https://github.com/slevithan/oniguruma-to-es) to transpile regex syntax and behavior.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n","isInternal":false,"tokens":72,"sizeBytes":265},{"name":"README.md","path":"packages/engine-oniguruma/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/engine-oniguruma/README.md","title":"engine-oniguruma Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/engine-oniguruma\n\nEngine for Shiki using Oniguruma RegExp engine in WebAssembly.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n","isInternal":false,"tokens":46,"sizeBytes":167},{"name":"README.md","path":"packages/langs-precompiled/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/langs-precompiled/README.md","title":"langs-precompiled Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/langs-precompiled\n\nPrecompiled languages for Shiki that can runs in pure JavaScript environment.\n\nRequires ES2024+ environment.\n\n> **Experimental**\n\n## Unsupported Languages\n\n<!-- TODOs -->\n\n## License\n\nMIT\n","isInternal":false,"tokens":48,"sizeBytes":218},{"name":"README.md","path":"packages/langs/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/langs/README.md","title":"langs Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/langs\n\nTextMate grammars for Shiki.\n\n## License\n\nMIT\n","isInternal":false,"tokens":21,"sizeBytes":64},{"name":"README.md","path":"packages/magic-move/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/magic-move/README.md","title":"magic-move Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/magic-move\n\nSmoothly animated code blocks with [shiki](https://github.com/shikijs/shiki). Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n[Documentation](https://shiki.style/packages/magic-move)\n\n## License\n\nMIT\n","isInternal":false,"tokens":82,"sizeBytes":301},{"name":"README.md","path":"packages/markdown-exit/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/markdown-exit/README.md","title":"markdown-exit Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/markdown-exit\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-exit)\n\n## License\n\nMIT\n","isInternal":false,"tokens":63,"sizeBytes":216},{"name":"README.md","path":"packages/markdown-it/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/markdown-it/README.md","title":"markdown-it Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/markdown-it\n\n[markdown-it](https://markdown-it.github.io/) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-it)\n\n## License\n\nMIT\n","isInternal":false,"tokens":54,"sizeBytes":199},{"name":"README.md","path":"packages/monaco/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/monaco/README.md","title":"monaco Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/monaco\n\nUse [shiki](https://github.com/shikijs/shiki) to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\n[Documentation](https://shiki.style/packages/monaco)\n\n## License\n\nMIT\n","isInternal":false,"tokens":61,"sizeBytes":210},{"name":"README.md","path":"packages/rehype/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/rehype/README.md","title":"rehype Documentation","category":"plugin-manifest","format":"markdown","content":"# rehype-shiki\n\n[rehype](https://github.com/rehypejs/rehype) plugin for [shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/rehype)\n\n## License\n\nMIT\n","isInternal":false,"tokens":57,"sizeBytes":186},{"name":"README.md","path":"packages/shiki/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/shiki/README.md","title":"shiki Documentation","category":"plugin-manifest","format":"markdown","content":"<img src=\"https://raw.githubusercontent.com/shikijs/shiki/main/docs/public/logo.svg\" width=\"150\" alt=\"Shiki Logo\" />\n\n# Shiki 式\n\n[![NPM version](https://img.shields.io/npm/v/shiki?color=32A9C3&labelColor=1B3C4A&label=npm)](https://www.npmjs.com/package/shiki)\n[![NPM downloads](https://img.shields.io/npm/dm/shiki?color=32A9C3&labelColor=1B3C4A&label=downloads)](https://www.npmjs.com/package/shiki)\n[![Codecov](https://img.shields.io/codecov/c/github/shikijs/shiki?token=B85J0E2I7I&style=flat&labelColor=1B3C4A&color=32A9C3&precision=1)](https://app.codecov.io/gh/shikijs/shiki)\n\nA beautiful syntax highlighter based on TextMate grammars, accurate and powerful.\n\n[📚 **Documentation**](https://shiki.style)\n\n## License\n\n[MIT](./LICENSE)\n","isInternal":false,"tokens":252,"sizeBytes":742},{"name":"README.md","path":"packages/stream/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/stream/README.md","title":"stream Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/stream\n\nStreaming colorization for [shiki](https://github.com/shikijs/shiki). Useful for highlighting text streams like LLM outputs.\n\n[Documentation](https://shiki.style/packages/stream)\n\n## License\n\nMIT\n","isInternal":false,"tokens":51,"sizeBytes":215},{"name":"README.md","path":"packages/themes/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/themes/README.md","title":"themes Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/themes\n\nTextMate themes for Shiki.\n\n## License\n\nMIT\n","isInternal":false,"tokens":19,"sizeBytes":63},{"name":"README.md","path":"packages/transformers/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/transformers/README.md","title":"transformers Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/transformers\n\nCommon transformers for [shiki](https://github.com/shikijs/shiki), inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n[Documentation](https://shiki.style/packages/transformers)\n\n## License\n\nMIT\n","isInternal":false,"tokens":66,"sizeBytes":246},{"name":"README.md","path":"packages/twoslash/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/twoslash/README.md","title":"twoslash Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/twoslash\n\nA [shiki](https://github.com/shikijs/shiki) transformer for [TypeScript Twoslash](https://www.typescriptlang.org/dev/twoslash/).\n\n[Documentations](https://shiki.style/packages/twoslash)\n\n## License\n\nMIT\n","isInternal":false,"tokens":68,"sizeBytes":224},{"name":"README.md","path":"packages/types/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/types/README.md","title":"types Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/types\n\nTypes for Shiki.\n\n## License\n\nMIT\n","isInternal":false,"tokens":17,"sizeBytes":52},{"name":"README.md","path":"packages/vitepress-twoslash/README.md","rawUrl":"https://raw.githubusercontent.com/shikijs/shiki/HEAD/packages/vitepress-twoslash/README.md","title":"vitepress-twoslash Documentation","category":"plugin-manifest","format":"markdown","content":"# @shikijs/vitepress-twoslash\n\nEnable Twoslash support in VitePress.\n\n[Documentation](https://shiki.style/packages/vitepress#twoslash)\n\n## License\n\nMIT\n","isInternal":false,"tokens":44,"sizeBytes":152}],"systemPromptSnippet":"<yakaai_skills repo=\"shikijs/shiki\">\n<!-- File: docs/packages/astro.md (Tokens: ~58 | Category: anthropic-skill) -->\n# Astro Integration\n\nYou don't need explicit integration in [Astro](https://astro.build/) as Astro already uses Shiki under the hood.\n\nLearn more about the configurations in the [Astro documentation](https://docs.astro.build/en/guides/syntax-highlighting/).\n\n<!-- File: docs/packages/cli.md (Tokens: ~737 | Category: anthropic-skill) -->\n# @shikijs/cli\n\n<Badges name=\"@shikijs/cli\" />\n\nShiki in the command line.\n\n## Usage\n\nThe Shiki CLI works like `cat` command, but with syntax highlighting.\nIt also supports remote files.\n\n```bash\nnpx @shikijs/cli README.md\n```\n\n```bash\nnpx @shikijs/cli \\\n  'https://github.com/shikijs/shiki/blob/main/taze.config.ts?raw=true'\n```\n\n## Install\n\nYou can also install it globally. Command aliases `@shikijs/cli`, `shiki`, `skat` are registered.\n\n::: code-group\n\n```sh [npm]\nnpm i -g @shikijs/cli\n```\n\n```sh [yarn]\nyarn global add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add -g @shikijs/cli\n```\n\n```sh [bun]\nbun add -g @shikijs/cli\n```\n\n```sh [deno]\ndeno install -gREn skat npm:@shikijs/cli\n```\n\n:::\n\n```sh\nskat src/index.ts\n```\n\n## Options\n\n### `--theme`\n\nSpecify the theme to use. Defaults to `vitesse-dark`.\n\n```bash\nnpx @shikijs/cli README.md --theme=nord\n```\n\n### `--lang`\n\nLanguage is auto-inferred from the file extension. You can override it with `--lang`.\n\n```bash\nnpx @shikijs/cli src/index.js --lang=ts\n```\n\n### `--format`\n\nSpecify the output format. Defaults to `ansi`.\nSupported values: `ansi`, `html`.\n\n```bash\nnpx @shikijs/cli README.md --format=html\n```\n\n## Node.js API\n\nThe `@shikijs/cli` package also provides a Node.js API.\n\n::: code-group\n\n```sh [npm]\nnpm i @shikijs/cli\n```\n\n```sh [yarn]\nyarn add @shikijs/cli\n```\n\n```sh [pnpm]\npnpm add @shikijs/cli\n```\n\n```sh [bun]\nbun add @shikijs/cli\n```\n\n```sh [deno]\ndeno add npm:@shikijs/cli\n```\n\n:::\n\n### `codeToANSI`\n\nThe asynchronous `codeToANSI` function allows you to convert code to ANSI escape codes for terminal output.\nThis is useful for rendering syntax-highlighted code in the terminal.\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord')\n\nconsole.log(highlighted)\n```\n\n`codeToANSI` takes three required parameters:\n\n1. `code: string`\n2. `lang: BundledLanguage`\n3. `theme: BundledTheme`\n\nand one optional parameter:\n\n4. `options?: CodeToANSIOptions`\n\nThe color level of the emitted escape codes is explicit instead of being inferred from the environment, and defaults to `3` (truecolor). Use `options.colorLevel` to target a different level — pass the level reported by `ansis` to follow the current terminal, or `0` to get plain text:\n\n```ts\nimport { codeToANSI } from '@shikijs/cli'\nimport ansis from 'ansis'\n\nconst highlighted = await codeToANSI(source, 'typescript', 'nord', {\n  colorLevel: ansis.level,\n})\n```\n\n<!-- File: docs/packages/codegen.md (Tokens: ~245 | Category: anthropic-skill) -->\n# shiki-codegen\n\n<Badges name=\"shiki-codegen\" />\n\nCodegen for Shiki to create optimized bundles dedicated for your usage.\n\n## Usage\n\n### CLI\n\n```bash\nnpx shiki-codegen \\\n  --langs typescript,javascript,vue \\\n  --themes light-plus,dark-plus \\\n  --engine javascript \\\n  ./shiki.bundle.ts\n```\n\nFile `shiki.bundle.ts` will be created with the code that you can use in your project.\n\nThen you can use it in your project:\n\n```ts\nimport { codeToHtml } from './shiki.bundle'\n\nconst html = await codeToHtml(code, { lang: 'typescript', theme: 'light-plus' })\n```\n\n### Programmatic\n\nYou can also use `shiki-codegen` programmatically, and write the generated code to a file:\n\n```ts\nimport { codegen } from 'shiki-codegen'\n\nconst { code } = await codegen({\n  langs: ['typescript', 'javascript', 'vue'],\n  themes: ['light-plus', 'dark-plus'],\n  engine: 'javascript',\n  typescript: true\n})\n\n// Write the code to a file\n```\n\n<!-- File: docs/packages/colorized-brackets.md (Tokens: ~820 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# @shikijs/colorized-brackets\n\n<Badges name=\"@shikijs/colorized-brackets\" />\n\nVSCode-style colorized brackets transformer for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/colorized-brackets\n```\n\n```sh [yarn]\nyarn add -D @shikijs/colorized-brackets\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/colorized-brackets\n```\n\n```sh [bun]\nbun add -D @shikijs/colorized-brackets\n```\n\n```sh [deno]\ndeno add npm:@shikijs/colorized-brackets\n```\n\n:::\n\n## Usage\n\nAdd to your Shiki transformers:\n\n```ts colorize-brackets\nimport { transformerColorizedBrackets } from '@shikijs/colorized-brackets'\nimport { codeToHtml } from 'shiki'\n\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: 'dark-plus',\n  transformers: [transformerColorizedBrackets()],\n})\n```\n\n### Colors\n\nBrackets are automatically colored according to your Shiki theme (or themes if using [dual themes](https://shiki.style/guide/dual-themes)), with support for all of Shiki's built-in themes. However, you can customize colors if you've added custom themes to Shiki, or if you want to override the colors of a built-in theme:\n\n```ts colorize-brackets\nconst html = await codeToHtml('let values: number[] = [];', {\n  lang: 'ts',\n  theme: myCustomTheme,\n  transformers: [transformerColorizedBrackets({\n    themes: {\n      'my-custom-theme': ['goldenrod', 'blueviolet', 'dodgerblue', 'crimson'],\n    },\n  })],\n})\n```\n\nThe final color is the mismatched bracket color. The other colors are for each \"level\" of bracket pair. Any valid CSS color can be used.\n\nIf no bracket colors are found for a theme, it falls back to the default `dark-plus` theme.\n\n### Brackets\n\nYou can customize the bracket pairs:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  bracketPairs: [{ opener: '{', closer: '}' }],\n})\n```\n\nThe above would only colorize `{}` curly brackets. The default config colorizes `[]` square brackets, `{}` curly brackets, `()` parentheses, and `<>` angle brackets (only in TS type annotations).\n\nFor advanced usage, you can specify which TextMate scopes a bracket pair is allowed or denied in, using `scopesAllowList` and `scopesDenyList`. For example, the default config for `<>` angle brackets is:\n\n```ts colorize-brackets\nconst bracketPair = {\n  opener: '<',\n  closer: '>',\n  scopesAllowList: [\n    'punctuation.definition.typeparameters.begin.ts',\n    'punctuation.definition.typeparameters.end.ts',\n  ],\n}\n```\n\n### Language-specific Overrides\n\nAll settings can be overridden for specific languages using the `langs` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  langs: { ts: myCustomTypescriptConfig },\n})\n```\n\n### Explicit Trigger\n\nIf you do not want colorized brackets for all code blocks, you can enable the `explicitTrigger` option:\n\n```ts colorize-brackets\nconst transformer = transformerColorizedBrackets({\n  explicitTrigger: true,\n})\n```\n\nThen, only code blocks with the `colorize-brackets` [meta string](/guide/transformers#meta) will have bracket colorizing enabled.\n\n````md\n```ts\n// no bracket colorizing\n```\n\n```ts colorize-brackets\n// brackets will be colorized\n```\n````\n\n<!-- File: docs/packages/magic-move.md (Tokens: ~1857 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# @shikijs/magic-move\n\n<Badges name=\"@shikijs/magic-move\" />\n\nSmoothly animated code blocks with Shiki. Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n`@shikijs/magic-move` is a low-level library: at its core is a framework-agnostic [diff/animation machine](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/core.ts) and [renderer](https://github.com/shikijs/shiki/blob/main/packages/magic-move/src/renderer.ts), with thin wrappers for Vue, React, Solid, Svelte, and a Web Component.\n\nEach framework wrapper provides three components:\n\n- **`ShikiMagicMove`** — the main component; wraps a code block and animates whenever `code` changes\n- **`ShikiMagicMovePrecompiled`** — animations for compiled tokens, without the Shiki dependency at runtime\n- **`ShikiMagicMoveRenderer`** — the low-level renderer component\n\n`ShikiMagicMove` needs a Shiki highlighter instance plus the bundled stylesheet (`@shikijs/magic-move/style.css`). Whenever `code` changes, the component animates the diff.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/magic-move shiki\n```\n\n```sh [yarn]\nyarn add -D @shikijs/magic-move shiki\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/magic-move shiki\n```\n\n```sh [bun]\nbun add -D @shikijs/magic-move shiki\n```\n\n```sh [deno]\ndeno add npm:@shikijs/magic-move npm:shiki\n```\n\n:::\n\n## Usage\n\n### Vue\n\nImport `@shikijs/magic-move/vue` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```vue\n<script setup>\nimport { ShikiMagicMove } from '@shikijs/magic-move/vue'\nimport { createHighlighter } from 'shiki'\nimport { ref } from 'vue'\n\nimport '@shikijs/magic-move/style.css'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst code = ref(`const hello = 'world'`)\n\nfunction animate() {\n  code.value = `let hi = 'hello'`\n}\n</script>\n\n<template>\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    :options=\"{ duration: 800, stagger: 0.3, lineNumbers: true }\"\n  />\n  <button @click=\"animate\">\n    Animate\n  </button>\n</template>\n```\n\n### React\n\nImport `@shikijs/magic-move/react` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport type { HighlighterCore } from 'shiki'\nimport { ShikiMagicMove } from '@shikijs/magic-move/react'\nimport { useEffect, useState } from 'react'\nimport { createHighlighter } from 'shiki'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = useState(`const hello = 'world'`)\n  const [highlighter, setHighlighter] = useState<HighlighterCore>()\n\n  useEffect(() => {\n    async function initializeHighlighter() {\n      const h = await createHighlighter({\n        themes: ['nord'],\n        langs: ['javascript', 'typescript'],\n      })\n      setHighlighter(h)\n    }\n    initializeHighlighter()\n  }, [])\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      {highlighter && (\n        <>\n          <ShikiMagicMove\n            lang=\"ts\"\n            theme=\"nord\"\n            highlighter={highlighter}\n            code={code}\n            options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n          />\n          <button onClick={animate}>Animate</button>\n        </>\n      )}\n    </div>\n  )\n}\n```\n\n### Solid\n\nImport `@shikijs/magic-move/solid` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```tsx\nimport { ShikiMagicMove } from '@shikijs/magic-move/solid'\nimport { bundledLanguages, bundledThemes, createHighlighter } from 'shiki'\nimport { createResource, createSignal, Show } from 'solid-js'\n\nimport '@shikijs/magic-move/style.css'\n\nfunction App() {\n  const [code, setCode] = createSignal(`const hello = 'world'`)\n\n  const [highlighter] = createResource(async () => {\n    return await createHighlighter({\n      themes: Object.keys(bundledThemes),\n      langs: Object.keys(bundledLanguages),\n    })\n  })\n\n  function animate() {\n    setCode(`let hi = 'hello'`)\n  }\n\n  return (\n    <div>\n      <Show when={highlighter()}>\n        {h => (\n          <>\n            <ShikiMagicMove\n              lang=\"ts\"\n              theme=\"nord\"\n              highlighter={h()}\n              code={code()}\n              options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n            />\n            <button onClick={animate}>Animate</button>\n          </>\n        )}\n      </Show>\n    </div>\n  )\n}\n```\n\n### Svelte\n\nImport `@shikijs/magic-move/svelte` and pass the highlighter instance to the `ShikiMagicMove` component.\n\n```svelte\n<script lang=\"ts\">\n  import { ShikiMagicMove } from '@shikijs/magic-move/svelte'\n  import { createHighlighter } from 'shiki'\n\n  import '@shikijs/magic-move/style.css'\n\n  const highlighter = createHighlighter({\n    themes: ['nord'],\n    langs: ['javascript', 'typescript'],\n  })\n\n  let code = $state(`const hello = 'world'`)\n\n  function animate() {\n    code = `let hi = 'hello'`\n  }\n</script>\n\n{#await highlighter then highlighter}\n  <ShikiMagicMove\n    lang=\"ts\"\n    theme=\"nord\"\n    {highlighter}\n    {code}\n    options={{ duration: 800, stagger: 0.3, lineNumbers: true }}\n  />\n  <button onclick={animate}>Animate</button>\n{/await}\n```\n\n## `ShikiMagicMovePrecompiled`\n\n`ShikiMagicMovePrecompiled` is a lighter variant of `ShikiMagicMove` that doesn't need Shiki at runtime — useful when you want to ship pre-tokenized step data (e.g. produced at build time) and animate between steps in the browser.\n\n```vue\n<script setup>\nimport { ShikiMagicMovePrecompiled } from '@shikijs/magic-move/vue'\nimport { ref } from 'vue'\n\nconst step = ref(1)\nconst compiledSteps = [/* Compiled token steps */]\n</script>\n\n<template>\n  <ShikiMagicMovePrecompiled\n    :steps=\"compiledSteps\"\n    :step=\"step\"\n  />\n  <button @click=\"step++\">\n    Next\n  </button>\n</template>\n```\n\nTo produce the compiled tokens, run this somewhere with access to Shiki (build script, server, etc.) and serialize the result:\n\n```ts\nimport { codeToKeyedTokens, createMagicMoveMachine } from '@shikijs/magic-move/core'\nimport { createHighlighter } from 'shiki'\n\nconst shiki = await createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript', 'typescript'],\n})\n\nconst codeSteps = [\n  `const hello = 'world'`,\n  `let hi = 'hello'`,\n]\n\nconst machine = createMagicMoveMachine(\n  code => codeToKeyedTokens(shiki, code, {\n    lang: 'ts',\n    theme: 'nord',\n  }),\n  {\n    // options\n  },\n)\n\nconst compiledSteps = codeSteps.map(code => machine.commit(code).current)\n\n// Pass `compiledSteps` to the precompiled component.\n// Since these are plain serialisable objects, you can stringify them at build time\n// and rehydrate them in the browser without needing Shiki.\n```\n\n## How it works\n\nFor a deep dive into the algorithm behind the animations, see Anthony's article [**The Magic In Shiki Magic Move**](https://antfu.me/posts/shiki-magic-move).\n\n<!-- File: docs/packages/markdown-exit.md (Tokens: ~868 | Category: anthropic-skill) -->\n# @shikijs/markdown-exit\n\n<Badges name=\"@shikijs/markdown-exit\" />\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for Shiki.\n\n`markdown-exit` is a modern TypeScript rewrite of `markdown-it` with native async rendering support — no extra library needed for async highlighting.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-exit\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-exit\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-exit\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-exit\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-exit\n```\n\n:::\n\n## Usage\n\nThe default export uses Shiki's [shorthands](/guide/shorthands) for on-demand loading of themes and languages. Since highlighting is async, use `md.renderAsync()` to render:\n\n````ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts\nimport Shiki from '@shikijs/markdown-exit'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport { createMarkdownExit } from 'markdown-exit'\n\nconst md = createMarkdownExit()\n\nmd.use(Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n\nconst html = await md.renderAsync(md_string)\n```\n\n## Custom `codeToHtml`\n\nIf you have a custom `codeToHtml` function (e.g., from a fine-grained shorthand bundle), use `fromAsyncCodeToHtml`:\n\n````ts\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-exit'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\nconst md = createMarkdownExit()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-exit/core` and pass your own highlighter:\n\n```ts\nimport { fromHighlighter } from '@shikijs/markdown-exit/core'\nimport { createMarkdownExit } from 'markdown-exit'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = createMarkdownExit()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n\n<!-- File: docs/packages/markdown-it.md (Tokens: ~14060 | Category: anthropic-skill) -->\n# @shikijs/markdown-it\n\n<Badges name=\"@shikijs/markdown-it\" />\n\n[markdown-it](https://markdown-it.github.io/) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/markdown-it\n```\n\n```sh [yarn]\nyarn add -D @shikijs/markdown-it\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/markdown-it\n```\n\n```sh [bun]\nbun add -D @shikijs/markdown-it\n```\n\n```sh [deno]\ndeno add npm:@shikijs/markdown-it\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"959709c97c288ea5ed5a231f28e5eebf48f1676e9c76559e68208cb76e2b6711\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  }\n}))\n```\n\n## Transformers\n\nYou can pass [transformers](/guide/transformers) to the plugin options to customize the highlighted code.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"7251d42df549db899085560c6ca05a99dc9f338642b7849507ef0ead24fa6dba\",\"data\":\"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\"}\nimport Shiki from '@shikijs/markdown-it'\nimport { transformerNotationDiff } from '@shikijs/transformers'\nimport MarkdownIt from 'markdown-it'\n\nconst md = MarkdownIt()\n\nmd.use(await Shiki({\n  themes: {\n    light: 'vitesse-light',\n    dark: 'vitesse-dark',\n  },\n  transformers: [\n    transformerNotationDiff(),\n  ],\n}))\n```\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import from `@shikijs/markdown-it/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4cce3b72c2224ceff07c637806719480ab0b5bcdb0fafc8ad599ec8c8ad5d255\",\"data\":\"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\"}\n// @noErrors: true\nimport { fromHighlighter } from '@shikijs/markdown-it/core'\nimport MarkdownIt from 'markdown-it'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst md = MarkdownIt()\n\nmd.use(fromHighlighter(highlighter, { /* options */ }))\n```\n\n## With Shorthands\n\nShiki's [shorthands](/guide/shorthands) provides on-demand loading of themes and languages, but also makes the highlighting process asynchronous. Unfortunately, `markdown-it` itself [does NOT support async highlighting](https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#i-need-async-rule-how-to-do-it) out of the box.\n\nTo workaround this, you can use [`markdown-it-async`](https://github.com/antfu/markdown-it-async) by [Anthony Fu](https://github.com/antfu). Where Shiki also provides an integration with it, you can import `fromAsyncCodeToHtml` from `@shikijs/markdown-it/async`.\n\n````ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"4d4fcf8100ee107a1813af12192e944bfcf04449a77daa41fca68ea887412763\",\"data\":\"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\"}\nimport { fromAsyncCodeToHtml } from '@shikijs/markdown-it/async'\nimport MarkdownItAsync from 'markdown-it-async'\nimport { codeToHtml } from 'shiki' // Or your custom shorthand bundle\n\n// Initialize MarkdownIt instance with markdown-it-async\nconst md = MarkdownItAsync()\n\nmd.use(\n  fromAsyncCodeToHtml(\n    // Pass the codeToHtml function\n    codeToHtml,\n    {\n      themes: {\n        light: 'vitesse-light',\n        dark: 'vitesse-dark',\n      }\n    }\n  )\n)\n\n// Use `md.renderAsync` instead of `md.render`\nconst html = await md.renderAsync('# Title\\n```ts\\nconsole.log(\"Hello, World!\")\\n```')\n````\n\n## Transformer Caveats\n\n`markdown-it` defaults to enforcing `<pre><code>` as the outermost wrappers of code block html. If you use a custom Shiki [transformer](/guide/transformers), this behavior may be undesirable. For example, if the transformer produces\n\n```html\n<div class=\"fenced-code-block\">\n  <pre>\n    <code>\n      …\n    </code>\n  </pre>\n</div>\n```\n\nthe result after `markdown-it` processing will be\n\n```html\n<pre>\n  <code>\n    <div class=\"fenced-code-block\">\n      <pre>\n        <code>\n          …\n        </code>\n      </pre>\n    </div>\n  </code>\n</pre>\n```\n\nWork around this by adding [olets/markdown-it-wrapperless-fence-rule](https://github.com/olets/markdown-it-wrapperless-fence-rule) to your `markdown-it` configuration, or by writing your own `markdown-it` fence rule (see [markdown-it#269](https://github.com/markdown-it/markdown-it/issues/269)).\n\n<!-- File: docs/packages/monaco.md (Tokens: ~932 | Category: anthropic-skill) -->\n# Monaco Editor Integration\n\nShiki uses the same TextMate grammar and themes as VS Code, so it can be used to highlight Monaco Editor. Shiki provides an official integration for Monaco Editor. You can also use [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration.\n\n## @shikijs/monaco\n\n<Badges name=\"@shikijs/monaco\" />\n\nUse Shiki to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\nMonaco's built-in highlighter does not use the full TextMate grammar, which in some cases is not accurate enough. This package allows you to use Shiki's syntax highlighting engine to highlight Monaco, with shared grammars and themes from Shiki.\n\nHeavily inspired by [`monaco-editor-textmate`](https://github.com/zikaari/monaco-editor-textmate).\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/monaco\n```\n\n```sh [yarn]\nyarn add -D @shikijs/monaco\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/monaco\n```\n\n```sh [bun]\nbun add -D @shikijs/monaco\n```\n\n```sh [deno]\ndeno add npm:@shikijs/monaco\n```\n\n:::\n\n### Usage\n\n```ts\nimport { shikiToMonaco } from '@shikijs/monaco'\nimport * as monaco from 'monaco-editor-core'\nimport { createHighlighter } from 'shiki'\n\n// Create the highlighter, it can be reused\nconst highlighter = await createHighlighter({\n  themes: [\n    'vitesse-dark',\n    'vitesse-light',\n  ],\n  langs: [\n    'javascript',\n    'typescript',\n    'vue'\n  ],\n})\n\n// Register the languageIds first. Only registered languages will be highlighted.\nmonaco.languages.register({ id: 'vue' })\nmonaco.languages.register({ id: 'typescript' })\nmonaco.languages.register({ id: 'javascript' })\n\n// Register the themes from Shiki, and provide syntax highlighting for Monaco. // [!code highlight:2]\nshikiToMonaco(highlighter, monaco)\n\n// Create the editor\nconst editor = monaco.editor.create(document.getElementById('container'), {\n  value: 'const a = 1',\n  language: 'javascript',\n  theme: 'vitesse-dark',\n})\n\n// ...As you use the editor normally\n```\n\n## modern-monaco\n\n<Badges name=\"modern-monaco\" />\n\nWe highly recommend using [modern-monaco](https://github.com/esm-dev/modern-monaco) that includes built-in Shiki integration. It provides a more convenient API for building Monaco Editor.\n\n### Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D modern-monaco\n```\n\n```sh [yarn]\nyarn add -D modern-monaco\n```\n\n```sh [pnpm]\npnpm add -D modern-monaco\n```\n\n```sh [bun]\nbun add -D modern-monaco\n```\n\n```sh [deno]\ndeno add npm:modern-monaco\n```\n\n:::\n\nOr import it from [esm.sh](https://esm.sh) CDN in the browser without a build step:\n\n```js\nimport * as monaco from 'https://esm.sh/modern-monaco'\n```\n\n### Usage\n\n```html\n<!-- index.html -->\n<monaco-editor theme=\"vitesse-dark\"></monaco-editor>\n<script src=\"app.js\" type=\"module\"></script>\n```\n\n```js\n// app.js\nimport { lazy, Workspace } from 'modern-monaco'\n\n// create a workspace with initial files\nconst workspace = new Workspace({\n  initialFiles: {\n    'index.html': `<html><body>...</body></html>`,\n    'main.js': `console.log('Hello, world!')`,\n  },\n  entryFile: 'index.html',\n})\n\n// initialize the editor lazily\nawait lazy({ workspace })\n\n// write a file and open it in the editor\nworkspace.fs.writeFile('util.js', 'export function add(a, b) { return a + b; }')\nworkspace.openTextDocument('util.js')\n```\n\nMore usage please see the [modern-monaco](https://github.com/esm-dev/modern-monaco) repository.\n\n<!-- File: docs/packages/next.md (Tokens: ~1228 | Category: anthropic-skill) -->\n# Next.js\n\nShiki does not provide an official integration for [Next.js](https://nextjs.org), but it is rather straightforward to use Shiki in Next.js applications.\n\n::: info\nUsing Shiki on Edge Runtime might cause unintended problems, Shiki relies on lazy imports to load languages and themes.\n\nServerless Runtime is recommended.\n:::\n\n## React Server Component\n\nSince Server Components are server-only, you can use the bundled highlighter without worrying the bundle size.\n\n```tsx\nimport type { BundledLanguage } from 'shiki'\nimport { codeToHtml } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHtml(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return <div dangerouslySetInnerHTML={{ __html: out }} />\n}\n```\n\n### Custom Components\n\nYou can also call `codeToHast` to get the HTML abstract syntax tree, and render it using [`hast-util-to-jsx-runtime`](https://github.com/syntax-tree/hast-util-to-jsx-runtime). With this method, you can render your own `pre` and `code` components.\n\n```tsx\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki'\n\nexport default function Page() {\n  return (\n    <main>\n      <CodeBlock lang=\"ts\">\n        {[\n          'console.log(\"Hello\")',\n          'console.log(\"World\")',\n        ].join('\\n')}\n      </CodeBlock>\n    </main>\n  )\n}\n\ninterface Props {\n  children: string\n  lang: BundledLanguage\n}\n\nasync function CodeBlock(props: Props) {\n  const out = await codeToHast(props.children, {\n    lang: props.lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n    components: {\n      // your custom `pre` element\n      pre: props => <pre data-custom-codeblock {...props} />\n    },\n  }) as JSX.Element\n}\n```\n\n## React Client Component\n\nFor client components, they are pre-rendered on server and hydrated/rendered on client.\nWe can start by creating a client `CodeBlock` component.\n\nCreate a `shared.ts` for highlighter:\n\n```ts\nimport type { JSX } from 'react'\nimport type { BundledLanguage } from 'shiki/bundle/web'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { codeToHast } from 'shiki/bundle/web'\n\nexport async function highlight(code: string, lang: BundledLanguage) {\n  const out = await codeToHast(code, {\n    lang,\n    theme: 'github-dark'\n  })\n\n  return toJsxRuntime(out, {\n    Fragment,\n    jsx,\n    jsxs,\n  }) as JSX.Element\n}\n```\n\nIn your `codeblock.tsx`:\n\n```tsx\n'use client'\nimport { JSX, useLayoutEffect, useState } from 'react'\nimport { highlight } from './shared'\n\nexport function CodeBlock({ initial }: { initial?: JSX.Element }) {\n  const [nodes, setNodes] = useState(initial)\n\n  useLayoutEffect(() => {\n    void highlight('console.log(\"Rendered on client\")', 'ts').then(setNodes)\n  }, [])\n\n  return nodes ?? <p>Loading...</p>\n}\n```\n\nThe `initial` prop can be passed from a server component to pre-render the code block on server.\n\nIn your `page.tsx`:\n\n```tsx\nimport { CodeBlock } from './codeblock'\nimport { highlight } from './shared'\n\nexport default async function Page() {\n  // `initial` is optional.\n  return (\n    <main>\n      <CodeBlock initial={await highlight('console.log(\"Rendered on server\")', 'ts')} />\n    </main>\n  )\n}\n```\n\n::: info\nThe above example uses the `shiki/bundle/web` bundle. You can change it to [Fine-grained Bundle](/guide/bundles#fine-grained-bundle) to fully control the bundled languages/themes.\n:::\n\n### Performance\n\nShiki lazy loads the requested languages and themes, the Next.js bundler can handle lazy imports automatically.\nImporting `shiki` or its web bundle is efficient enough for most Next.js applications, Fine-grained Bundle won't significantly impact the bundle size.\n\nIn addition, you can use the `createHighlighter` API to preload specific languages and themes.\nPlease refer to [Highlighter Usage](/guide/install#highlighter-usage) for further details.\n\n### Highlighter Instance\n\nIf you define a highlighter (without `await`) as a global variable, you can reference it directly from server and client components.\n\n```ts\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = createHighlighter({\n  themes: ['nord'],\n  langs: ['javascript'],\n})\n\n// Inside an async server component, or client side `useEffect`\nconst html = (await highlighter).codeToHtml('const a = 1', {\n  lang: 'javascript',\n  theme: 'nord'\n})\n```\n\n<!-- File: docs/packages/nuxt.md (Tokens: ~277 | Category: anthropic-skill) -->\n# Nuxt\n\n[Nuxt](https://nuxt.com) is a general-purpose meta-framework that gives you full control over your application. You can install Shiki along with integrations like ([markdown-it](/packages/markdown-it), [rehype](/packages/rehype)) or import manually as you needed.\n\nOn top of that, Nuxt also provide some module integrations for Shiki allowing you use it easier:\n\n- [`nuxt-shiki`](https://github.com/pi0/nuxt-shiki) - Shiki integration for client and server sides, with component usage.\n- [`@nuxt/content`](https://github.com/nuxt/content) - Nuxt Content has Shiki built-in for markdown files. [You can enable it with the `highlight` option](https://content.nuxt.com/docs/getting-started/configuration#highlight).\n  - [`@nuxtjs/mdc`](https://github.com/nuxt-modules/mdc) - The underlying module of `@nuxt/content` that provides Markdown Component (MDC) syntax as well as Shiki for syntax highlighting.\n\n## TwoSlash Integration\n\n- [`nuxt-content-twoslash`](https://github.com/antfu/nuxt-content-twoslash) - A Nuxt module that adds Twoslash support to Nuxt Content. Twoslash information are evaluated at build time.\n\n<!-- File: docs/packages/rehype.md (Tokens: ~28922 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# @shikijs/rehype\n\n<Badges name=\"@shikijs/rehype\" />\n\n[rehype](https://github.com/rehypejs/rehype) plugin for Shiki.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/rehype\n```\n\n```sh [yarn]\nyarn add -D @shikijs/rehype\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/rehype\n```\n\n```sh [bun]\nbun add -D @shikijs/rehype\n```\n\n```sh [deno]\ndeno add npm:@shikijs/rehype\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"f652dc1d308709739c1be11a9172b77ef0b59d02c30ad9b2f5dc7195fad4cd45\",\"data\":\"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=\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThe default export of `@shikijs/rehype` uses a shared instance of `shiki` from `getSingletonHighlighter`, which will persist across processes. If you want full control over the highlighter lifecycle, use [Fine-grained Bundle `@shikijs/rehype/core`](#fine-grained-bundle) instead.\n\n## Fine-grained Bundle\n\nBy default, the full bundle of `shiki` will be imported. If you are using a [fine-grained bundle](/guide/bundles#fine-grained-bundle), you can import `rehypeShikiFromHighlighter` from `@shikijs/rehype/core` and pass your own highlighter:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"141199456275121b3ddecb36bbeedc3ec800ba9c5d4c78ec0a3f651e44ac22ee\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShikiFromHighlighter from '@shikijs/rehype/core'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { createHighlighterCore } from 'shiki/core'\nimport { createOnigurumaEngine } from 'shiki/engine/oniguruma'\n\nimport { unified } from 'unified'\n\nconst highlighter = await createHighlighterCore({\n  themes: [\n    import('@shikijs/themes/vitesse-light')\n  ],\n  langs: [\n    import('@shikijs/langs/javascript'),\n  ],\n  engine: createOnigurumaEngine(() => import('shiki/wasm'))\n})\n\nconst raw = await fs.readFile('./input.md')\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShikiFromHighlighter, highlighter, {\n    // or `theme` for a single theme\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    }\n  })\n  .use(rehypeStringify)\n  .processSync(raw) // it's also possible to process synchronously\n```\n\n## Features\n\n### Inline Code\n\nYou can also highlight inline codes with the `inline` option.\n\n| Option                  | Example          | Description                                                 |\n| ----------------------- | ---------------- | ----------------------------------------------------------- |\n| `false`                 | -                | Disable inline code highlighting (default)                  |\n| `'tailing-curly-colon'` | `let a = 1{:js}` | Highlight with a `{:language}` marker inside the code block |\n\nEnable `inline` on the Rehype plugin:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"549ef2ad84b55c413cb40bcedc19dcf805008cf25a703dd1f3614dff89dbdd93\",\"data\":\"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\"}\n// @noErrors: true\nimport rehypeShiki from '@shikijs/rehype'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport { unified } from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    inline: 'tailing-curly-colon', // or other options\n    // ...\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\nThen you can use inline code in markdown:\n\n```md\nThis code `console.log(\"Hello World\"){:js}` will be highlighted.\n```\n\n## Postprocess Transformers\n\n::: info\nThe `postprocess` transformer hook is only invoked when producing HTML strings (i.e., when using `codeToHtml`). Since `@shikijs/rehype` operates on HAST (Hypertext Abstract Syntax Tree) rather than HTML strings, postprocess transformers will not be executed.\n:::\n\nThis design is intentional: running `postprocess` hooks in rehype would require converting HAST → HTML → running postprocess → parsing back to HAST, which changes the semantics and could surprise users expecting HAST-only transformers.\n\n### Workaround for HTML-based Postprocessing\n\nIf you need to run HTML-based postprocessing with rehype, you can apply a `root` transformer that:\n\n1. Converts the HAST fragment to HTML using `hast-util-to-html`\n2. Runs your HTML transformers\n3. Converts back to HAST using `hast-util-from-html`\n\nExample:\n\n```ts\nimport { fromHtml } from 'hast-util-from-html'\nimport { toHtml } from 'hast-util-to-html'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkRehype)\n  .use(rehypeShiki, {\n    themes: {\n      light: 'vitesse-light',\n      dark: 'vitesse-dark',\n    },\n    transformers: [\n      {\n        name: 'custom-html-postprocessor',\n        root(node) {\n          // Convert HAST to HTML\n          const html = toHtml(node)\n\n          // Apply your HTML transformations\n          const processedHtml = myCustomPostprocess(html)\n\n          // Parse back to HAST\n          const newNode = fromHtml(processedHtml, { fragment: true })\n\n          // Replace the node\n          return newNode\n        }\n      }\n    ]\n  })\n  .use(rehypeStringify)\n  .process(await fs.readFile('./input.md'))\n```\n\n<!-- File: docs/packages/stream.md (Tokens: ~1120 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# @shikijs/stream\n\n<Badges name=\"@shikijs/stream\" />\n\nStreaming colorization for Shiki. Useful for highlighting text streams like LLM outputs, where code arrives incrementally and you want each chunk highlighted as it lands without re-tokenizing the whole document.\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/stream\n```\n\n```sh [yarn]\nyarn add -D @shikijs/stream\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/stream\n```\n\n```sh [bun]\nbun add -D @shikijs/stream\n```\n\n```sh [deno]\ndeno add npm:@shikijs/stream\n```\n\n:::\n\n## Usage\n\nCreate a transform stream with `CodeToTokenTransformStream` and `.pipeThrough` your text stream:\n\n```ts\nimport { CodeToTokenTransformStream } from '@shikijs/stream'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\n\n// Initialize the Shiki highlighter somewhere in your app\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\n// The ReadableStream<string> you want to highlight\nconst textStream = getTextStreamFromSomewhere()\n\n// Pipe the text stream through the token stream\nconst tokensStream = textStream\n  .pipeThrough(new CodeToTokenTransformStream({\n    highlighter,\n    lang: 'javascript',\n    theme: 'nord',\n    allowRecalls: true, // see explanation below\n  }))\n```\n\n### `allowRecalls`\n\nDue to the fact that highlighting may change based on the context of the code, themed tokens can be re-evaluated as the stream progresses. Because streams are one-directional, `@shikijs/stream` emits a special **recall** token that tells the receiver to discard the last N tokens that changed.\n\nBy default, `CodeToTokenTransformStream` only emits **stable** tokens — no recalls. The trade-off is coarser granularity, usually one line at a time.\n\nFor stream consumers that can handle recalls (e.g. the bundled Vue, React, Solid, and Svelte components), set `allowRecalls: true` to get finer-grained tokens.\n\nTypically recalls should be handled like:\n\n```ts\nimport type { RecallToken } from '@shikijs/stream'\nimport type { ThemedToken } from 'shiki'\n\nconst receivedTokens: ThemedToken[] = []\n\ntokensStream.pipeTo(new WritableStream<ThemedToken | RecallToken>({\n  async write(token) {\n    if ('recall' in token) {\n      // discard the last `token.recall` tokens\n      receivedTokens.length -= token.recall\n    }\n    else {\n      receivedTokens.push(token)\n    }\n  },\n}))\n```\n\n## Consume the Token Stream\n\n### Manually\n\n```ts\ntokensStream.pipeTo(new WritableStream({\n  async write(token) {\n    console.log(token)\n  },\n}))\n```\n\nOr in Node.js:\n\n```ts\nfor await (const token of tokensStream) {\n  console.log(token)\n}\n```\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/vue'\n\n// get the token stream\n</script>\n\n<template>\n  <ShikiStreamRenderer :stream=\"tokensStream\" />\n</template>\n```\n\n### React\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/react'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Solid\n\n```tsx\nimport { ShikiStreamRenderer } from '@shikijs/stream/solid'\n\nexport function MyComponent() {\n  // get the token stream\n  return <ShikiStreamRenderer stream={tokensStream} />\n}\n```\n\n### Svelte\n\n```svelte\n<script lang=\"ts\">\nimport { ShikiStreamRenderer } from '@shikijs/stream/svelte'\n\n// get the token stream\n</script>\n\n<ShikiStreamRenderer stream={tokensStream} />\n```\n\n## Cached Renderer\n\n`@shikijs/stream` also ships a simplified renderer for the common case of an incrementally-updated code string (rather than a token stream).\n\n::: warning Experimental\nThis API is experimental and may change.\n:::\n\n### Vue\n\n```vue\n<script setup lang=\"ts\">\nimport { ShikiCachedRenderer } from '@shikijs/stream/vue'\nimport { createHighlighter, createJavaScriptRegexEngine } from 'shiki'\nimport { onMounted, ref } from 'vue'\n\nconst highlighter = await createHighlighter({\n  langs: [/* ... */],\n  themes: [/* ... */],\n  engine: createJavaScriptRegexEngine(),\n})\n\nconst code = ref('') // code should only be updated incrementally\n\n// for demo purposes\nonMounted(() => {\n  setInterval(() => {\n    code.value += '\\nconsole.log(\"Hello, world!\");'\n  }, 1000)\n})\n</script>\n\n<template>\n  <ShikiCachedRenderer\n    :highlighter=\"highlighter\"\n    :code=\"code\"\n    lang=\"js\"\n    theme=\"vitesse-light\"\n  />\n</template>\n```\n\n<!-- File: docs/packages/transformers.md (Tokens: ~5921 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# @shikijs/transformers\n\n<Badges name=\"@shikijs/transformers\" />\n\nCommon transformers for Shiki, inspired by [shiki-processor](https://github.com/innocenzi/shiki-processor).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/transformers\n```\n\n```sh [yarn]\nyarn add -D @shikijs/transformers\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/transformers\n```\n\n```sh [bun]\nbun add -D @shikijs/transformers\n```\n\n```sh [deno]\ndeno add npm:@shikijs/transformers\n```\n\n:::\n\n## Usage\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"8efec5d385627b3d23e03e4c9bdf13f9a3c80178f3105cfb878cd54cef1eacb9\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZAHIQ0zcZIAi7fv0YQsO+QH5EvACqz5iles3aJYfYYDyp1zysBlfHYAa3ZbOQUlVVIAHTB2ZSwlNGk7CMdSDS0zd35KECgIEQREEABVOBheAANkAEIRaEqAaiaAXSreOShquobYXgBaAfbpCF5lZlIgzqhYbq7eUhhlYhhujjB4ADo8uC1SBkQAZgAWKlYYMABzNHwkACYjqn2rmEPqVIcozJc9A1zzuxNg8qCJ8JNmGIyA8AL4UdDYXAlQgkcjPOjvFgcLh8BryZJ9GDWCAACTQylYVkYhKse1IQKuFF4JjMcCsAGFGsSSVw0F5WQAeABCwigFygABk5FdBMxXkyRWAxWtrPhljAAHx8AC8Gt4AAVSBBlOwKgK6QyNbF4okDrxCdzyaxdvtDgBGN0ABnOlxud0QXuek1e7wdpKdeQ2SIAbKDwbIoeREPc4QicHgUdD0fQ8Hi9vbGlZoiA8xALltWBArowAORq1iVmvcYsuybuk5nEAXa63JCdl5vXONSNApEATjjEMTSGjqeoiIzqzR1AxQ/xvHwTtpMgZrYOSDdAA5vV3fb3EP3g4PkRHAcCAyewVOaEnZ/D5+nkUu8jQcyUsZwPAFrAjoUtSha8Ba1xMiyPgclypK8vyPjCqK4pStcsryrwirKlAqrqlqViGsapowOaO7XFacQJEkwFEuGFJ7u6Y5PKePb+oG1BXqGCFkkxd5IlxT4Ji+B5jnOmCfgQ37Zrx640rwxaluWlbVnWMANhATYtlQextg8nqdt2fp9kGpAhkOsAjvewnxpCYnHJ6kkLl+qI/qu/5YEaOAHBgfCsNKRbUHAukgPp+7Jm6xlnv6l4WdeXbSjZQlupOonQsmLnSZmy6/pi3kmGQmB8JysDIZIcB+AyFwEaoqFKuKdWalstzqlYzUAEowFcpoyL8YAAIJgBgvAAD68H4lFXBK7AvmwpRxJIDV4c1TJQVcGrMQ89yHj6HFIAArOZlklG1qgpQe9zpQ5mUpu+UlIjJ7lyUwhW+SVNifJEZAVfIrXfekcCWJNgQhGE9g/aQyCtONvCijA/CjlAeQFEUeAQ2kURwAISjSGqoPBOwvBYOwOBRjsemug8JzHexpkBtd3EJe8/WQ0Dl0BmxIm3Um91pk9uUeX+IAATiKThF8ThZK4OTGN4lUg5jUsZM42T/H9viE+DgNRNatF2mzWPSwNOSo4UxRlBUPT1I0vAtCMCw1Lb/RDCMaBjBMUwzHMnRKosyyrOso5wJT4XU8m0Z0yZ56PCdiVGyrPzq4YnPRTd04XjCrSgsOJQAPT57wvR24EVz4Bw5doIgh2tPrtrJMAsS8BL7PfGrsv/BQze8IXvBbAPsQwgIRrKLwNYAAJwGD7AAFZwPnidQ3ANb13RTdSPRoGsN3YDD/wo/j9PROr2AsR5gSdvatUKkwBWVa1vWjbcFU5+Vckm4Urw1/MAA7swc0t6MVYOBWATIN4t0CtcKwNY0Ar13i3c6MAYGQFIFAGsCDW7G1IGyYuPdEG6xNinIw3AmR9xLv0MuFd2BVzrpvFufcB5bB7jnIe3A8iqC0EgUAGJLhwFcHgOBIAYQwiAA===\"}\n// [!code highlight:5]\nimport {\n  transformerNotationDiff,\n  // ...\n} from '@shikijs/transformers'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff(), // [!code highlight]\n    // ...\n  ],\n})\n```\n\n## Unstyled\n\nTransformers only applies classes and does not come with styles; you can provide your own CSS rules to style them properly.\n\n## Matching Algorithm\n\nWe found that the algorithm for matching comments in v1 is sometime conterintuitive, where we are trying to fix it in a progressive way. Since v1.29.0, we introduced a new `matchAlgorithm` option to most of the transformer for you to toggle between different matching algorithms. Right now, the default is `v1` which is the old algorithm, and `v3` is the new algorithm. When Shiki v3 is landed, the default will be `v3`.\n\n```ts\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  theme: 'nord',\n  transformers: [\n    transformerNotationDiff({\n      matchAlgorithm: 'v3', // [!code hl]\n    }),\n  ],\n})\n```\n\n### `matchAlgorithm: 'v1'`\n\nThe matching algorithm mostly affects the single-line comment matching, in `v1`, it will count the comment line as the first line, while in `v3`, it will count start from the comment line:\n\n```ts\n// [\\!code highlight:3]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n### `matchAlgorithm: 'v3'`\n\nIn `v3`, the matching algorithm will start counting from the line below the comment:\n\n```ts\n// [\\!code highlight:2]\nconsole.log('highlighted') // [!code hl]\nconsole.log('highlighted') // [!code hl]\nconsole.log('not highlighted')\n```\n\n## Transformers\n\n### `transformerNotationDiff`\n\nUse `[!code ++]` and `[!code --]` to mark added and removed lines.\n\n````md\n```ts\nconsole.log('hewwo') // [\\!code --]\nconsole.log('hello') // [\\!code ++]\nconsole.log('goodbye')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('hewwo') // [!code --]\nconsole.log('hello') // [!code ++]\nconsole.log('goodbye')\n```\n\n- `// [!code ++]` outputs: `<span class=\"line diff add\">`\n- `// [!code --]` outputs: `<span class=\"line diff remove\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-diff\">`\n\n::: details HTML Output\n\n```html\n<!-- Output (stripped of `style` attributes for clarity) -->\n<pre class=\"shiki has-diff\"> <!-- Notice `has-diff` -->\n  <code>\n    <span class=\"line\"></span>\n    <span class=\"line\"><span>function</span><span>()</span><span></span><span>{</span></span>\n    <span class=\"line diff remove\">  <!-- Notice `diff` and `remove` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hewwo</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line diff add\">  <!-- Notice `diff` and `add` -->\n      <span></span><span>console</span><span>.</span><span>log</span><span>(</span><span>&#39;</span><span>hello</span><span>&#39;</span><span>) </span>\n    </span>\n    <span class=\"line\"><span></span><span>}</span></span>\n    <span class=\"line\"><span></span></span>\n  </code>\n</pre>\n```\n\n:::\n\n---\n\n### `transformerNotationHighlight`\n\nUse `[!code highlight]` to highlight a line.\n\n````md\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [\\!code highlight]\nconsole.log('Not highlighted')\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not highlighted')\nconsole.log('Highlighted') // [!code highlight]\nconsole.log('Not highlighted')\n```\n\n- `// [!code highlight]` outputs: `<span class=\"line highlighted\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nYou can also highlight multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [\\!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n````\n\nRenders:\n\n```ts\n// [!code highlight:3]\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n```ts\nconsole.log('Not highlighted')\n// [!code highlight:1]\nconsole.log('Highlighted')\nconsole.log('Not highlighted')\n```\n\n---\n\n### `transformerNotationWordHighlight`\n\nUse `[!code word:Hello]` to highlight the word `Hello` in any subsequent code.\n\n````md\n```ts\n// [\\!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\n// [!code word:Hello]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\nYou can also specify the number of lines to highlight words on, e.g. `[!code word:Hello:1]` will only highlight occurrences of `Hello` on the next line.\n\n````md\n```ts\n// [\\!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n````\n\nRenders:\n\n```ts\n// [!code word:Hello:1]\nconst message = 'Hello World'\nconsole.log(message) // prints Hello World\n```\n\n---\n\n### `transformerNotationFocus`\n\nUse `[!code focus]` to focus a line.\n\n````md\n```ts\nconsole.log('Not focused');\nconsole.log('Focused') // [\\!code focus]\nconsole.log('Not focused');\n```\n````\n\nRenders (with custom CSS rules):\n\n```ts\nconsole.log('Not focused')\nconsole.log('Focused') // [!code focus]\nconsole.log('Not focused')\n```\n\n- Outputs: `<span class=\"line focused\">`\n- The outer `<pre>` tag is modified: `<pre class=\"has-focused\">`\n\nYou can also focus multiple lines with a single comment:\n\n````md\n```ts\n// [\\!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n````\n\nRenders:\n\n```ts\n// [!code focus:3]\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Focused')\nconsole.log('Not focused')\n```\n\n---\n\n### `transformerNotationErrorLevel`\n\nUse `[!code error]`, `[!code warning]`, and `[!code info]` to mark a line with an error, warning, or info levels.\n\n````md\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [\\!code error]\nconsole.warn('Warning') // [\\!code warning]\nconsole.log('Info') // [\\!code info]\n```\n````\n\n- Outputs: `<span class=\"line highlighted error\">` for errors\n- Outputs: `<span class=\"line highlighted warning\">` for warnings\n- Outputs: `<span class=\"line highlighted info\">` for info\n- The outer `<pre>` tag is modified: `<pre class=\"has-highlighted\">`\n\nWith some additional CSS rules, you can make it look like this:\n\n```ts\nconsole.log('No errors or warnings')\nconsole.error('Error') // [!code error]\nconsole.warn('Warning') // [!code warning]\nconsole.log('Info') // [!code info]\n```\n\n---\n\n### `transformerRenderWhitespace`\n\nRender whitespaces (tabs and spaces) as individual spans, with classes `tab` and `space`.\n\nOptions:\n\n- `position`: `'all' | 'boundary' | 'trailing' | 'leading'`. Default `'all'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"--shiki-light:#AB5959;--shiki-dark:#CB7676;\">function</span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">block</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">{</span></span>\n<span class=\"line\"><span class=\"space\"> </span><span class=\"space\"> </span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">space</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span></span>\n<span class=\"line\"><span class=\"tab\">&#9;</span><span class=\"tab\">&#9;</span><span style=\"--shiki-light:#59873A;--shiki-dark:#80A665;\">tab</span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">(</span><span class=\"space\"> </span><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">)</span><span style=\"--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;\"> </span></span>\n<span class=\"line\"><span style=\"--shiki-light:#999999;--shiki-dark:#666666;\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .tab,\npre.shiki .space {\n  position: relative;\n}\n\npre.shiki .tab::before {\n  content: '⇥';\n  position: absolute;\n  opacity: 0.3;\n}\n\npre.shiki .space::before {\n  content: '·';\n  position: absolute;\n  opacity: 0.3;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderIndentGuides`\n\nRender indentations as individual spans, with class `indent`.\n\nWith some additional CSS rules, you can make it look like this:\n\n<div class=\"language-js vp-adaptive-theme\"><button title=\"Copy Code\" class=\"copy\"></button><span class=\"lang\">js</span><pre v-pre class=\"shiki shiki-themes vitesse-light vitesse-dark\" style=\"--shiki-light:#393a34;--shiki-dark:#dbd7caee;--shiki-light-bg:#ffffff;--shiki-dark-bg:#121212;\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CB7676\">function</span><span style=\"color:#80A665\"> func</span><span style=\"color:#666666\">()</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">1</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\" style=\"--indent-offset: 0ch;\"></span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#4D9375\">for</span><span style=\"color:#666666\"> (</span><span style=\"color:#CB7676\">const </span><span style=\"color:#BD976A\">i</span><span style=\"color:#CB7676\"> of</span><span style=\"color:#666666\"> [])</span><span style=\"color:#666666\"> {</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span class=\"indent\">  </span><span style=\"color:#BD976A\">console</span><span style=\"color:#666666\">.</span><span style=\"color:#80A665\">log</span><span style=\"color:#666666\">(</span><span style=\"color:#4C9A91\">2</span><span style=\"color:#666666\">);</span></span>\n<span class=\"line\"><span class=\"indent\">  </span><span style=\"color:#666666\">}</span></span>\n<span class=\"line\"><span style=\"color:#666666\">}</span></span></code></pre></div>\n\n::: details Example CSS\n\n```css\npre.shiki .indent {\n  display: inline-block;\n  position: relative;\n  left: var(--indent-offset);\n}\n\npre.shiki .indent:empty {\n  height: 1lh;\n  vertical-align: bottom;\n}\n\npre.shiki .indent::before {\n  content: '';\n  position: absolute;\n  opacity: 0.15;\n  width: 1px;\n  height: 100%;\n  background-color: currentColor;\n}\n```\n\n:::\n\n---\n\n### `transformerRenderLineNumber`\n\nRender line numbers as individual spans, with class `line-number`.\n\n```ts\nimport { transformerRenderLineNumber } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  transformers: [\n    transformerRenderLineNumber(),\n  ],\n})\n```\n\nOptions:\n\n- `start`: Start number. Default `1`.\n- `classLineNumber`: Class for line number. Default `'line-number'`.\n\nWith some additional CSS rules, you can make it look like this:\n\n```css\npre.shiki .line-number {\n  user-select: none;\n  opacity: 0.5;\n  margin-right: 1em;\n}\n```\n\n---\n\n### `transformerMetaHighlight`\n\nHighlight lines based on the [meta string](/guide/transformers#meta) provided on the code snippet.\n\n````md\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n````\n\nRenders (with custom CSS rules):\n\n```js {1,3-4}\nconsole.log('1')\nconsole.log('2')\nconsole.log('3')\nconsole.log('4')\n```\n\n- Outputs: `<span class=\"line highlighted\">` for included lines.\n\n### `transformerMetaWordHighlight`\n\nHighlight words based on the meta string provided on the code snippet.\n\n````md\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg)\nconsole.log(msg) // prints Hello World\n```\n````\n\nRenders (with custom CSS rules):\n\n```js /Hello/\nconst msg = 'Hello World'\nconsole.log(msg) // prints Hello World\n```\n\nOutputs: `<span class=\"highlighted-word\">Hello</span>` for matched words.\n\n---\n\n### `transformerCompactLineOptions`\n\nSupport for `shiki`'s `lineOptions` that is removed in `shiki`.\n\n---\n\n### `transformerRemoveLineBreak`\n\nRemove line breaks between `<span class=\"line\">`. Useful when you set `display: block` to `.line` in CSS.\n\n---\n\n### `transformerRemoveNotationEscape`\n\nTransform `// [\\!code ...]` to `// [!code ...]`.\nAvoid rendering the escaped notation syntax as it is.\n\n---\n\n### `transformerStyleToClass`\n\nConvert Shiki's inline styles to unique classes.\n\nClass names are generated based on the hash value of the style object with the prefix/suffix you provide. You can put this transformer in multiple highlights passes and then get the CSS at the end to reuse the exact same styles. As Shiki doesn't handle CSS, it's on your integration to decide how to extract and apply/bundle the CSS.\n\nFor example:\n\n```ts\nimport { transformerStyleToClass } from '@shikijs/transformers'\nimport { codeToHtml } from 'shiki'\n\nconst toClass = transformerStyleToClass({ // [!code highlight:3]\n  classPrefix: '__shiki_',\n})\n\nconst code = `console.log('hello')`\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  themes: {\n    dark: 'vitesse-dark',\n    light: 'vitesse-light',\n  },\n  defaultColor: false,\n  transformers: [toClass], // [!code highlight]\n})\n\n// The transformer instance exposes some methods to get the CSS\nconst css = toClass.getCSS() // [!code highlight]\n\n// use `html` and `css` in your app\n```\n\nHTML output:\n\n```html\n<pre class=\"shiki shiki-themes vitesse-dark vitesse-light __shiki_9knfln\" tabindex=\"0\"><code><span class=\"line\">\n  <span class=\"__shiki_14cn0u\">console</span>\n  <span class=\"__shiki_ps5uht\">.</span>\n  <span class=\"__shiki_1zrdwt\">log</span>\n  <span class=\"__shiki_ps5uht\">(</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_1g4r39\">hello</span>\n  <span class=\"__shiki_236mh3\">'</span>\n  <span class=\"__shiki_ps5uht\">)</span>\n</span></code></pre>\n```\n\nCSS output:\n\n```css\n.__shiki_14cn0u {\n  --shiki-dark: #bd976a;\n  --shiki-light: #b07d48;\n}\n.__shiki_ps5uht {\n  --shiki-dark: #666666;\n  --shiki-light: #999999;\n}\n.__shiki_1zrdwt {\n  --shiki-dark: #80a665;\n  --shiki-light: #59873a;\n}\n.__shiki_236mh3 {\n  --shiki-dark: #c98a7d77;\n  --shiki-light: #b5695977;\n}\n.__shiki_1g4r39 {\n  --shiki-dark: #c98a7d;\n  --shiki-light: #b56959;\n}\n.__shiki_9knfln {\n  --shiki-dark: #dbd7caee;\n  --shiki-light: #393a34;\n  --shiki-dark-bg: #121212;\n  --shiki-light-bg: #ffffff;\n}\n```\n\n### `transformerRemoveComments`\n\nRemove comments from the code. It works by checking the internal grammar token metadata to determine if the token is a comment.\n\nThis transformer requires `includeExplanation: true` to work.\n\n```ts\nimport { transformerRemoveComments } from '@shikijs/transformers'\n\nconst html = await codeToHtml(code, {\n  lang: 'ts',\n  includeExplanation: true, // [!code highlight]\n  transformers: [\n    transformerRemoveComments(), // [!code highlight]\n  ],\n})\n```\n\nOptions:\n\n- `removeEmptyLines`: Remove lines that become empty after removing comments. Default `true`.\n\nFor example:\n\n````md\n```js\n// This is a comment\nconst x = 1 // Inline comment\n/* Block comment */\nconst y = 2\n\n// Another comment\n```\n````\n\nWill renders:\n\n```js\nconst x = 1\nconst y = 2\n```\n\n<!-- File: docs/packages/twoslash.md (Tokens: ~8755 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# @shikijs/twoslash\n\n<Badges name=\"@shikijs/twoslash\" />\n\nA Shiki transformer for [Twoslash](https://github.com/twoslashes/twoslash), provide inline type hover inside code blocks.\n\n[TwoSlash Notation Reference](https://twoslash.netlify.app/refs/notations).\n\n## Install\n\n::: code-group\n\n```sh [npm]\nnpm install -D @shikijs/twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/twoslash\n```\n\n:::\n\nThis package is **a transformer addon** to Shiki. This means that for every integration that supports passing Shiki transformers, you can use this package.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"b436269721bc02aa6e2b87b8db32bd8f1713dc97017fd91b867735e43ccd0ba0\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQARk2qVhgwabRcrYBOKlXSaZgN6lSB+yy9PI4wXC2qEXw1ippyRAAmAC+FHQ2DeBGIZDyNHoTDYnB4TRMyRE0BgaggAAk0MpWBZGKjYBYVqRJtMKLxDPM4BYAMJojGYrhoTzUgA8ACFhFA9lAADJyaaCZhXClc1y8tT4GCqAB8fAAvLLeAAFUgQZTsOAwNkksmy2LxRLrJGwRk41jLC4bADsAAZdvtDsdNg7qGsrjdCeisRbnpM3gAWD5fWRiKEA4GgnB4QgkcjnOhe5G8fAW4kyMlWtYbV3BkB7A5HJD5i6e2N+3YBpA2kPfcN/ABsUeoYNjkIT1CTcI4XD43vNuIJaIzpIOFKp3hpvHpZqxzNZU853N5AoOwtFvHFPJgUClMpg8osao1Wp1eoOBriCSSpp92Nx2fWSG2tYLTuLWzdZeueAHvsfKtXhrOsw1+F8ThbTAYxKOMoUTWESkYLB1RwdYMD4XQDgsaJqDgXCn1zQMznfItjlLD1fxKLDpn9YDEAADlAn4IyBEFWxgiF42hbskJQwwyEwPhZxgRcTD8Mk9n3VRlwlXdpMPBYjgPCwFIAJRgaYtRkNpvAAQTAaoAB8ukzA4+XYX42AAVTiSRZJ3PdpVUCkL2mWVCJfRsAGZHTIpAAFZzkom5lNUOi3hIz563AyN2Og8E4M7GEbmQ1DBIwyw7kiMgxMWHSbBy0gzH8QIQjCQr0mQABdXgTO5GB+ADKA8gKIo8AqtIojgIZSGkaUujK3osHYHAXhgJYqBWHMXwYpjSOdF9/mCy4qNufoioQIC3ldZiGyQNjo0SjseMQkAWF7RECq6h5HByAwvBMcwso29JMju/AXDcPKeFKnpOvuGJr2NZJrsB96xlawpijKH4qhqUR5gaJoWjaGAOkGno+kqwZbBGR4cgmKZNLmKdJpAabnwBO15sLRbThW8sSjBoqIaebaXx2EBorAiNA0BaqPjRPAjVvYBYl4bGboyUY9AoWJAQEdVlF4AByAABHIegAKzgAB6NBZZyVXDRvE1xakO9B1YeWwEV/hlbVrWQhNsBYlReRkjTXFeAVDoNGYSyrYA1hGAAAw9uAID2BZWAgaZGG4MOKQtyWaIsVW0DgVXbclsKYAzohLPgbUAFooDWIIc4lqXAenZAa7z7K3qN/RuApPW9d4NlS9L1MyBgRveE73gFjHmvBYV7g8lUVYkFAJN9jgbw8CzkBAUBIA=\"}\nimport {\n  transformerTwoslash,\n} from '@shikijs/twoslash'\nimport {\n  codeToHtml,\n} from 'shiki'\n\nconst html = await codeToHtml(`console.log()`, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [\n    transformerTwoslash(), // <-- here\n    // ...\n  ],\n})\n```\n\nThe default output is unstyled. You need to add some extra CSS to make them look good.\n\nIf you want to run Twoslash on browsers or workers, reference to the [CDN Usage](#cdn-usage) section.\n\n## Renderers\n\nThanks to the flexibility of [`hast`](https://github.com/syntax-tree/hast), this transformer allows customizing how each piece of information is rendered in the output HTML with ASTs.\n\nWe provide two renderers built-in, and you can also create your own:\n\n---\n\n### `rendererRich`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-rich.ts)\n\n::: tip\nThis is the default renderer since v0.10.0.\n:::\n\nThis renderer provides a more explicit class name is prefixed with `twoslash-` for better scoping.\nIn addition, it runs syntax highlighting on the hover information.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"9bafe2d835b3a768cc39f5a28647084c02c621d41bbebd6324dead19238c244e\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAErsR+RhCzjJcAPyJei2fLLLVAeU0SwPfQBUA7hDisu+Q3LJkAOmHYBbLAhSNGkjTyUVfEoQKAgRBEQQAEEpNhpSMGZxElCPBV40fCzeLFJidnk4XgAjGDR0kpl+dloYKF4RFzgqzL94Ch97dkLeOAwwNGZaXnx2AHN8DgWQ/iCC/BhedjBVgro0ADpouEngpABOKlZZOcKkAEYAJipTubq8GTyTSOiOMFxEAAGKiqZikZhiMgXAC+FHQ2ABBGIUJe+yYbE4PAEwjEVgK4Osq1IfVIDicXTUGi01j0vFsBLgRJJZOcrgAkh5aBZqTZeABlWYAa3Y9OYhKCJJ8/kCwXxYsZErILIp0Vi8TwADEIWgghhsaJqQUIB0ZFlNsx+UL2HLxcSyAI1mhHKy4PgthMYHNwTyjlQTmCGIhHgBmK43O6Ie6Xahgt6B6gMplK50qq7bAHAkCg8GQ8hB4Ow+E4PCEEjkVH0dEcLh8NCJxWklOudSWbS00W25lN10c2Bc1vWbj6AXsYUdhV20hSgJBEJ1+VJxvk1yquIJEBasS6/W4yRGk0wM28C0j4U2ickh2kArdt3bGherJWOC+kD+s6IADs9zDYFuUUjaNXneRJ507ZNl1dX50yQZ4syKHN0iQQFC2oBES2RctqDRRJGFKDQyEwPhx0XZVXG5Z8Dk+YxSHbW93Bo3gAB9eGEWBmn+KBV3VRIAGFBBOCA/FyGiqh1XhYBECpNkIexeEPVR3V2V0IEEVh2lqETPC4v1TkDc4AFZf3/JAAA4XljECQGo8JoP+JBQ3gsFtShINUMwYtElLFFsMrXCMRrLSFFMSkB10fQGPCEKKO0Ic6XosIFGnGUQhs4KfioNV1xSY9WHSTJsk2NL7UKYp8KIaTSCqWp6ntUoYGaVp2k6LgemYPo4AGMAhhGMYJimGZ5kWIaVkdDYlONGh6Ffd9A3uQEjJAa4/wjJ4LNIOMPkS75VDsgFHOzFy8yeaEAF0QWgRFpVnXhgCCnb8Aoc9SNvXhoQEMphIAcgAAVdUd2AAKzgAB6J1IPwL6fB8MCLwgl01GAHxeHu0h9GKiJVEYPgQZB3gAB4AFpCZ8aFuGiPpJiQUB9lkOArDwNAEGhaEgA\"}\nimport { rendererRich, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererRich() // <--\n})\n```\n\nHere are a few examples with the built-in [`style-rich.css`](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-rich.css):\n\n<!-- eslint-skip -->\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"43c9a2581bdd8d8c26b6a00be668c361b400ca9c2034e576e137e282e9ec30ed\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808BLMG0gMwEMBjGAAgBVoESiDhoOpBogCMABioAbGGADmafEgAsVcaRUwpIQVGGLmuRPJBd8E7qyRyAvhXTYLBYmRE16eABRYpBA4khgAlAJCAHRojGhKiLxipMwqImISUtIAnIrKahqIAKw6EvqGcQm4ZmAW0lQ2dlwOiABMLm44eIQk5Dp0hlwQYGK8aEJJAEowHCZgChgAPMYQAHwZulKabfmq6lplegZ4EyYiCuaH1rak9t6IAGyd1O49Xv3Ug6fuvDNzI0WKzWvAAvLxgLxSLN5oteMgAAq8Zi8ADWMAwEDYAgAukl+IicQBuXhOEQmLgIRAgACyHHRvA4CgUvCCITIcXgyLAAihMMBGE2WS0AA49oUkGLqOUTtT/rDBbULNobs1WtIOq5Xt1qb1vAM/NTmKxODwoucqJlJEhigB2cUHRAq3QVPCrC5XJ2NW73cjtaQvTA6zx9HzfamBYKhTCRKqJZJoVKqIXWp55EBKfZFUrS46VeJKD11G3etUPTVdDwARwArmRFV9DSBI+ywrGCzAkik0impI905mJSUjq7qXGahnPTmmncWuXA29dR8w03/ABbAyEKCRADKibSsQgAFUsKEAMIcOAwfzhLv75NUClUkBnkZ9NBwRnM8b4PhMrC2AARgYjBcLwM6+p+KIcAmSYqOMEC8DWp5kFwl4wNEvaOLIViDo60gNLmo7UMeKGkBeV5FhY04+nOfoAMz0QuwZ6p8vhDCMYxnBA0z8gsyyrBslpbI40hSnhRTOjKlRCFRkqlrOrSyMxHhkMEnxWtkbT0Q62aNNAFhtMUmhWGwjCZhwG5MGAsC0LECBUIwUB4GpAC0Rkma50iaLarnFCuhgXmAkBoIycBwIwKg8hMvAAOTjrFvDAWhNZXsioWMJ+MHQnMrkCqyUYchgmH5CQCguaQ6lyYgUoQXRNoqe8oYGoYLbRhE4wdkkHBgA2mmONpuklkRsrUB21W1bRrTFI1S7NY2hhEBIvAAHI1muwGkEka0bWQr6jImNYtBAnxPngACCPIQIBABWMAtD+HChdCQTwMoH6MrwYDrZtvBYoyvVoswUDRLw53fgAUhwS07lwqRYKF327aQWXQrwjyaK5gHxLwbAKBAT1pK5WAQMaX0/WQcAlaIIkyCZQ1PCOo07Zt1VyApvpIMpWpBh4rEBQEG7qNAkQs3tnGHcdpDRFgEhXgAkiw/jdqod5wRQUJzIwtAAPxJEjm23uTyPkhAlJ4Pt76fudsFpAhAPcjQ+jSz4HAqFSyDICAst3GumxwWDtuqPbwxgO+juITBBtkJhOIUF7PuWSIdxQNrgdLQodZJQYADuMDKLwbQA1AvD0Y8j2hXAOBcIwZlcuofCAehf3Yg3xu/SiAAGKsqJ30QADpgPLrf4JljJ6Ot73Ip+IXJMhWCXDAUAaz3n45/E+Cfa9Zm0C3cWyLQiUSHwocRbA0Il7+tBzPdjBrkyA9gODLIQA3pBB+748n5xTlkEvvCwBrvfBQsc4402FHTe0GYCiOilC6UaPsFYsDZlYOqrRbSzWsBANcC8QIjCwnTcSMCiioOwbguInEkCoHAJZDwiCYAADF8ZPREKiYGeAhZblYcDGk0Ba6MEpngQBChj4ZBOmgfg4YQAERAC8MAtC8D0MVgwKgbCbIcM3NAbhNleGpzrijIR90RHQjEZISRTYZFyIUdSNkExebaOcjYwqYQHG6P4YI6kwjRGWnEeYwwliwHDBwUoChowETQh3oolBHN6o1ScIEgy1kTTcD4KsCEg9eCdWqGrNIg8nCD0HqfUK3FeIAn4isIQIJwTAAyVk+MsUAAiMAQl8GYPYRgJAkJXhRrFQ8J5zzoRvBQPJBSWAxHHGCOKAAJZp+NYqjLFtLJRStYoanorFDWchwijMybsvZ+zeAAHpDm1IOWc45IghYcCQKAQYygIr4LHAgJwTggA=\"}\n// @errors: 2540\ninterface Todo {\n  title: string\n}\n\nconst todo: Readonly<Todo> = {\n  title: 'Delete inactive users'.toUpperCase(),\n//  ^?\n}\n\ntodo.title = 'Hello'\n\nNumber.parseInt('123', 10)\n//      ^|\n\n               //\n               //\n```\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c6f2791b81c2170bb12e4d54f17b345c35c290fb6b3e803987a0875ad1778705\",\"data\":\"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\"}\nimport { createHighlighterCore } from 'shiki/core'\nimport { createJavaScriptRegexEngine } from 'shiki/engine/javascript'\n\nconst highlighter = await createHighlighterCore({\n  engine: createJavaScriptRegexEngine()\n})\n\n// @log: Custom log message\nconst a = 1\n// @error: Custom error message\nconst b = 1\n// @warn: Custom warning message\nconst c = 1\n// @annotate: Custom annotation message\n```\n\n---\n\n### `rendererClassic`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/twoslash/src/renderer-classic.ts)\n\nThis renderer aligns with the output of legacy [`shiki-twoslash`](https://github.com/shikijs/twoslash).\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"be50298f5ea6976d501abea603d4b03abe8280f3bf0a7b10df97e47172449e7c\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvUjDCwZpAMKsucdiMbdEvACoB3CHBVx8AJVnyyAHTDsAtlgik00i2TLLV6yiCgQRCIggOvgwvLD8zIKsLjJy7qS8bOwA5rZgKbx67Gj4vLlhTqnsYGy8AAYAAibsANbsAFZwAPRoBkZc+OW8EIJoWH0AdD5waMzOSACcVKyyKblIAIwArFRjpCkwDEFxlkrGaiI+HGC4iAAMVCL448xiZFMAvhTo2GcExA9rdNsgLBxcPhCUTiST5UjMMBwfhOOxkfSGYz4RgQLCgqEAfm0OghUJhpDhpARHRMAEl4rQAPJoiRQrS8ADK+Dq7BxkOhsOstgcThcaFxHIJ8PaSJ8fgCeAAYnc0E4MAJhGJafkILwRDJmDQkozmfVwez8YSBE58iLOrwSjQUhD0XBhlRRuNtgAmABsMzmC0Qi2m1HGm1+/INnKJZpMxxKZ0uIGut3u5EQbuerxweEIJHI33oTGSgP1eJDxKRKJpkjgWN0AsNwsRnXJsCppbp2iZLLZBaFpBs9kcznzgsJRc6Yv8gRA0rEcoVIOVsrVGq1zB1LP71cS+NNtZMFrAVpttLtI3W2wA7AAWD0ZL0+tb+rZ4IMdwdh/AR05IZ1XG4Q+NIc7J6g3jTT5M2oH4mCwUhUTITA+HbAcaxJfBqVtQZdgSCshxMcx4gUXgAB9eGECJIygEcJSCRRBFGCA7FcXCyDgFVwhgER2FgXhCD0XgYDuPIShhXgTF6VgoF4AAjMJ0JkMiHWPKYAA5L3mV9ECUv0NnvHY3AUN8zgAZi/OMaATZ0AMwVMgnTL4wOzIJ/k4Hh6L2Tw4EOTRsRfHC9m7Hk+2kjwDm8KhxTHEIwgiKIYmchIkg4NISkybJcnyUIelIYpSlYCpql1RoWjaLcuh6PoBjQe0QEdCZvXOdTZivVSVlvTTfgC/YvCOGZIyQQyY2/GUHm9MyAF0rmgd4e15XhgBihRXMOChV0LF9eEeAQoLogByXKWSaVoX02mwbEfBDQyKxhgBsXhZrIbQ2vm9RNF4Zpml4AAeABaD6bEebgfDhMYkFAH5ZDUSQHwQR5HiAA=\"}\nimport { rendererClassic, transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  renderer: rendererClassic() // <--\n})\n```\n\nYou might need to reference `shiki-twoslash`'s CSS to make it look good. [Here](https://github.com/shikijs/shiki/blob/main/packages/twoslash/style-classic.css) we also copied the CSS from `shiki-twoslash` but it might need some cleanup.\n\n### `rendererFloatingVue`\n\n[Source code](https://github.com/shikijs/shiki/blob/main/packages/vitepress-twoslash/src/renderer-floating-vue.ts)\n\nThis renderer outputs Vue template syntax that using [Floating Vue](https://floating-vue.starpad.dev/) as the popup component (to render it outside the containers). This renderer is **NOT** directly usable but an internal renderer for the [VitePress integration](/packages/vitepress#twoslash). Listing it here for reference if you want to create your own renderer.\n\n## Options\n\n### Explicit Trigger\n\nWhen integrating with `@shikijs/markdown-it` or `rehype-shiki`, we may not want Twoslash to run on every code block. In this case, we can set `explicitTrigger` to `true` to only run on code blocks with `twoslash` presented in the codeframe.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"c33fc7b243f56e1595f93ca6e9e052fed95abb58a9edc5376b448c62984626f1\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAIAzAK5gAxmnYQwvNKWZg4/CKQC2ZACoB3CHFZd8jCFnGS4AfkS81s+YpXqtOvQEkwsWgHkjE+dwsBlfHYAa3YrOQUlVVIAHTB2ZSwlNGlrCLtSTW1dOHxKECgIEQREEAAxZjElDAFhMW9pCF4RUhhmGl5mXgDg9hTw2yiBJWkHbPxedjAaAHNZY3kAOjy4NGZSBkQATipWGDBptFzEAEZt6jXpmA3qVIH7LL08jjBcRAAGKhF8NYqaci2AL4UdDYV4EYhkPI0ehMNicHh9GyRe6OHIGLwmcyWW7IjKjZyuOieeY8fyBEJhJHpWLxRLrRFpKKZVG5KgFIp4cqVUjVISieYNJotNowDpdcm9GT9XFDUgjB45CZTGCzNreOBLKgrNYbACsAHYdnsDkdTlRVqRLtcpVSmfick9Jq8AEyfb6yMSQ95AkE4PCEEjkc10a6MLCkQxkTB8SmMlFjYnqhZ0LAcETsNBWdjTS6kLEAIwgEF2cl4AB9eAAlFUAUVoWHLvGEsH4TqgeXZxRA1YAjoJ2C04LwAAZoe34YeC/Oi8PwPY0KBK6T4UUiaCi/OsQpBXiqVaC5hYVPVQ7sIc2uNB87TYrIZD5GD8ZiCVgMKhP1hwXAAXW/WotGwABzHEa+yHEgxy6uaFxXHgKZphmWY5pCOxOkgADMbo/J6/zOgCf4gGusB4LSSS8MADJ3HiCrjACAgRsovAAOQAAI5D0ABWcAAPRjjRTGxLEF5UcyYyMMAsS8Lw8HsOmmakNmuYWDIgiitx3G8AAPAAtNpsQAtweR7swSCgCGexwN4eBoAgAIAkAA=\"}\nimport { transformerTwoslash } from '@shikijs/twoslash'\n\ntransformerTwoslash({\n  explicitTrigger: true // <--\n})\n```\n\n````md\nIn markdown, you can use the following syntax to trigger Twoslash:\n\n```ts\n// this is a normal code block\n```\n\n```ts twoslash\n// this will run Twoslash\n```\n````\n\n## Integrations\n\nWhile you can set up Twoslash with Shiki on your own with the instructions above, you can also find high-level integrations with frameworks and tools here:\n\n- [VitePress](/packages/vitepress#twoslash) - A plugin to enable Twoslash support in VitePress.\n- [Nuxt](/packages/nuxt#twoslash-integration) - A module to enable Twoslash for Nuxt Content.\n- [Vocs](https://vocs.dev/docs/guides/twoslash) - Vocs has TwoSlash support built-in.\n- [Slidev](https://sli.dev/features/twoslash#twoslash-integration) - Slidev has TwoSlash support built-in.\n\n## Recipes\n\n### CDN Usage\n\nBy default [`twoslash`](https://github.com/twoslashes/twoslash/tree/main/packages/twoslash) runs on Node.js and relies on your local system to resolve TypeScript and types for the imports. Import it directly in non-Node.js environments would not work.\n\nLuckily, Twoslash implemented a virtual file system, which allow you to provide your own files for TypeScript to resolve in memory. However, loading these files in the browser is still a challenge. Thanks to the work on the [TypeScript WebSite](https://github.com/microsoft/TypeScript-Website), the TypeScript team has provided some utilities to fetch types on demand through CDN, they call it [Automatic Type Acquisition (ATA)](https://github.com/microsoft/TypeScript-Website/tree/v2/packages/ata).\n\nWe make tiny wrappers around the building blocks and provide an easy-to-use API in [`twoslash-cdn`](https://twoslash.netlify.app/packages/cdn). For example:\n\n```js\n// FIXME: Replace with explicit versions in production\nimport { createTransformerFactory, rendererRich } from 'https://esm.sh/@shikijs/twoslash@latest/core'\nimport { codeToHtml } from 'https://esm.sh/shiki@latest'\nimport { createTwoslashFromCDN } from 'https://esm.sh/twoslash-cdn@latest'\nimport { createStorage } from 'https://esm.sh/unstorage@latest'\nimport indexedDbDriver from 'https://esm.sh/unstorage@latest/drivers/indexedb'\n\n// ============= Initialization =============\n\n// An example using unstorage with IndexedDB to cache the virtual file system\nconst storage = createStorage({\n  driver: indexedDbDriver({ base: 'twoslash-cdn' }),\n})\n\nconst twoslash = createTwoslashFromCDN({\n  storage,\n  compilerOptions: {\n    lib: ['esnext', 'dom'],\n  },\n})\n\nconst transformerTwoslash = createTransformerFactory(twoslash.runSync)({\n  renderer: rendererRich(),\n})\n\n// ============= Execution =============\n\nconst app = document.getElementById('app')\n\nconst source = `\nimport { ref } from 'vue'\n\nconsole.log(\"Hi! Shiki + Twoslash on CDN :)\")\n\nconst count = ref(0)\n//     ^?\n`.trim()\n\n// Before rendering, we need to prepare the types, so that the rendering can happen synchronously\nawait twoslash.prepareTypes(source)\n\n// Then we can render the code\napp.innerHTML = await codeToHtml(source, {\n  lang: 'ts',\n  theme: 'vitesse-dark',\n  transformers: [transformerTwoslash],\n})\n```\n\n<!-- File: docs/packages/vitepress.md (Tokens: ~8957 | Category: anthropic-skill) -->\n---\noutline: deep\n---\n\n# VitePress Integration\n\n[VitePress](https://vitepress.dev/) uses Shiki under the hood, so you don't need explicit integration.\n\nVitePress provides [a few options for customizing Shiki](https://github.com/vuejs/vitepress/blob/main/src/node/markdown/markdown.ts#L66-L112). Learn more about them in the [VitePress documentation](https://vitepress.dev/reference/site-config#markdown).\n\n## Twoslash\n\nTo enable [TypeScript Twoslash](/packages/twoslash) (type hover on code snippets) in VitePress, we provide a VitePress plugin for easy setup. Pre-styled, with [Floating Vue](https://floating-vue.starpad.dev/) to display the type information out side of the code container.\n\n<Badges name=\"@shikijs/vitepress-twoslash\" />\n\n### Setup\n\n::: code-group\n\n```sh [npm]\nnpm i -D @shikijs/vitepress-twoslash\n```\n\n```sh [yarn]\nyarn add -D @shikijs/vitepress-twoslash\n```\n\n```sh [pnpm]\npnpm add -D @shikijs/vitepress-twoslash\n```\n\n```sh [bun]\nbun add -D @shikijs/vitepress-twoslash\n```\n\n```sh [deno]\ndeno add npm:@shikijs/vitepress-twoslash\n```\n\n:::\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash() // [!code hl]\n    ],\n    // [!code hl:2]\n    // Explicitly load these languages for types highlighting\n    languages: ['js', 'jsx', 'ts', 'tsx']\n  }\n})\n```\n\nAnd then in your [`.vitepress/theme/index.ts`](https://vitepress.dev/guide/custom-theme), install the Vue plugin and import the css with `@shikijs/vitepress-twoslash/styles.css`.\n\n```ts twoslash [.vitepress/theme/index.ts]\n// @twoslash-cache: {\"v\":1,\"hash\":\"2a5df659524ba4854bc92abbfbd15feefdb74ba936c5a020d6bdc7d308b959b2\",\"data\":\"N4Igdg9gJgpgziAXAbVAFwJ4AcZJACwgDcYAnEAGhDRgA808AKAQwBsBLZuASgAJ2wNUgDNmAYxi8AomHzMwEgIJYsAYQiC6aADph2AWywRSaabPlKV6zfUog4aZiaQBGACxVWMMAHM0+VwB2KkdSHxgGRBAZOQUYZTUNGltPAVxEAAYqMTlScSFXNwBfCnRsdIJiMjtkyJAWDi4+MQ0HXgAVAHcIOFYufAAxVghmNAEfADUAVxhEXmBdXiX+MAc2VjmWFTmEil4ILDHWgH45oZGx32mYa2F2Hz4AXgA+XiIIdigAbl0i3QMjCYOt1ev1zqNxtc7FAIGIEFFrrwsKwpj4BLw0BAVmtWKxeODLpMZrxOux/LwHBgvHAAHS6XQASUMxlM/nYcF4wimCiOYBWvAABjSiGSYFhSPA4AB6fwwfQwKUCWC0GloOAC3jyKC8KZwSQC5gqGm6mCMLo9PpwQbDCFXGbcDUCOCfSSywXeWKWLAawgQADWNLsa2ciAArAAOTzePwBRAuACcISc4Tq5tBVoJkJmdg4YHSLmyuXy1UQgRKZRweEIJHIIS0TDYnB4vBaq1M7Xwctm80WywAMswMBApmg5gARGB3PPqZl5wQ/PnLD0WeLbXiMMRoWhzGIrhLWWpPV7vT4Lv56ZlAjtdoOhSLuAsgLy+fxIUNJsIRPDX+U5tJIAAmQsnGLchS3LahyirKpa2oesokYcUDjITA+C0bwoDgOYFkXJYByHEdx0nNIZyMOc0AXZZeGXOIEk2TdtzMT1V0SGw0CPN4Pm+X5bycSIANDICn2jV9Sw/FM8HQsBML/PMkGCEAchAzcSwAiDMErKJq2qOtbAQxsmhbVp207eVsN7PDB2HUdeAnKcbggWdvAoizqPMWi1w3Lcd3cr0Dy0DiT24sBzwBFkOlM3AqGDfiADZH2fGM33Er8oh/KKn3/MTFKLFSwJcFx1KgrSYJqeD6nlfxoDQ3yWMYYBNRUXgih85j9ySAK5iC3iQwAwIsmEl9YxcAbQgkqIaK9WT0kjHLlIKRA1NKSDNMqGsyr0+osBAyqyD4Q0sB2FQAB55AwZ4ev48MAGYoyGpBbuoZNUpAA7pqQWalLyPLXFDIrVu02DagbRpmwEIRRAkJi9ysDr6H+S9TF3DzWOB6K70A+MBsS0SXAUsaXuRvy4YYVI5MQT7coWgClorCpAY2upEJ2iI9saw7eASU6wHOy6Hpcd9BqSxBHoJuo3rJ9JEzm76FuKZaNPp0rdKZyrCCgPgubO55jT1Y7kAOXk4FOTUeYAXWeRCUTRMA5gABWtgR9cN9gTjmM6zb2A3Dld1YTY9549hpYOXdaOYADkIAZMBhDIZ2fbd02MAt7gjqwbnzvXABqFx9hrG0Nb5kWEzu4XReeuoTXexBpa+0CPv+pX1pVkGm2aYzgQtMEbUJa5zNw7FHFxTYDrTvZQ79s4e6zByY/uQKuLPBHAXbEFLWtC4Z+hWF4RARFkVRdFMUH9Z8Wnu1JFJclKWpOkwEZRGMXwdlOW5Tdff5IURRocVJRlSLFTSToKqdUpttQmkFAdXWpo0zr0zBfB02IXRP31JNFiPoID+kDOjPiD0AKPRxsNaWYtvxr27pvC+1da5UxLC4NSntFLQAqGFIEit5jQxRv5egzVOSkEcrwAA5N/MUEo4BwAEcvcKsDyG2iJJIYQfD9CCIAAJWnYH6dgAAraUwjf5iIALRoDIVaKUYgODOQEbwKUUpeDIAAIQtFgLwfArAzaSKvJFXh/ChGij0dKWU8oJH3wvCvFRaiNHaKlLo0RcBDHGPwFKG+MAaRwnEVYmx9jHGSBcW44JdBQmwFEFMVgpgcJLCkphOY6UKC9jQQkeq7NmqtRhqjAKPYB5QJNGaeJ8C5F8GsbYhxTDnGuN7CUHiVBKrMCQKAKSzoNB4DVCAIoRQgA=\"}\n// @noErrors: true\nimport type { EnhanceAppContext } from 'vitepress'\nimport TwoslashFloatingVue from '@shikijs/vitepress-twoslash/client' // [!code hl]\nimport Theme from 'vitepress/theme'\n\nimport '@shikijs/vitepress-twoslash/style.css' // [!code hl]\n\nexport default {\n  extends: Theme,\n  enhanceApp({ app }: EnhanceAppContext) {\n    app.use(TwoslashFloatingVue) // [!code hl]\n  },\n}\n```\n\n::: details About style.css\n\nFor easier setup, `@shikijs/vitepress-twoslash/styles.css` bundles the styles from `floating-vue` and `@shikijs/twoslash/style-rich.css` so you only need a single entry. If you are using a custom `floating-vue` style or want to have more control of the styles, you can expand them as:\n\n```ts\nimport '@shikijs/vitepress-twoslash/style.css'\n\n// Equivalent to:\nimport '@shikijs/twoslash/style-rich.css'\nimport 'floating-vue/dist/style.css'\nimport '@shikijs/vitepress-twoslash/style-core.css'\n```\n\n:::\n\nThat's it, you can now use `ts twoslash` in your markdown files to enable the beautiful type hover.\n\n````md\n```ts twoslash\nconsole.log('hello')\n//      ^?\n```\n````\n\nIt will be rendered as:\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"258fd8e6b019224fc5515598774b6ccef0d85eefda3a3ba0992cbaa911ba9952\",\"data\":\"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\"}\nconsole.log('hello')\n//      ^?\n```\n\n<div class=\"h-100\" /> <!-- leaving some space for the query above -->\n\n### Vue Single File Component\n\nIn addition, this plugin also integrated [`twoslash-vue`](https://twoslash.netlify.app/packages/vue) for you, so that you can also highlight Vue SFC blocks with `vue twoslash`:\n\n```vue twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"e44d27459becb1dd99d3f24e24e643e1cd8fe190f90d461e4713e08207fe0a39\",\"data\":\"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\"}\n<script setup>\nimport { onMounted, ref } from 'vue'\n\n// reactive state\nconst count = ref(0)\n//             ^?\n\n// functions that mutate state and trigger updates\nfunction increment() {\n  count.value++\n}\n\n// lifecycle hooks\nonMounted(() => {\n  console.log(`The initial count is ${count.value}.`)\n})\n</script>\n\n<template>\n  <button @click=\"increment\">\n    Count is: {{ count }}\n  </button>\n</template>\n```\n\n### File System Cache\n\nTo speed up the build process, you can enable the file system cache for the generated types, that shares across multiple builds. By default the cache is stored in the `.vitepress/cache/twoslash` along with other VitePress caches.\n\nIn your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config):\n\n```ts [.vitepress/config.ts]\nimport { transformerTwoslash } from '@shikijs/vitepress-twoslash'\nimport { createFileSystemTypesCache } from '@shikijs/vitepress-twoslash/cache-fs' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nexport default defineConfig({\n  markdown: {\n    codeTransformers: [\n      transformerTwoslash({\n        typesCache: createFileSystemTypesCache() // [!code hl]\n      })\n    ]\n  }\n})\n```\n\n### Inline Cache (experimental)\n\nYou can enable inline caching for the generated types. The `@twoslash-cache: ...` will auto insert into your fenced code block during development and build time.\n\n````md [./your-file.md]{2}\n```ts twoslash\n// @twoslash-cache: [auto generated]\nconst a: string = 'foo'\n```\n````\n\nTo enable the inline cache in your [`.vitepress/config.ts`](https://vitepress.dev/reference/site-config), please use the config wrapper created by `createTwoslashWithInlineCache`.\n\n```ts [.vitepress/config.ts]\nimport { createTwoslashWithInlineCache } from '@shikijs/vitepress-twoslash/cache-inline' // [!code hl]\nimport { defineConfig } from 'vitepress'\n\nconst withTwoslashInlineCache = createTwoslashWithInlineCache({ // [!code hl]\n  // ... config of transformerTwoslash // [!code hl]\n}) // [!code hl]\n\nexport default withTwoslashInlineCache( // [!code hl]\n  defineConfig({\n    markdown: {\n      codeTransformers: [\n        // move config to the `createTwoslashWithInlineCache()` // [!code error]\n        // transformerTwoslash({ ... }) // [!code error]\n      ]\n    }\n  })\n) // [!code hl]\n```\n\n#### Force re-generate inline cache\n\nTo force re-generate the inline cache and ignore the existing cache, you can use the `TWOSLASH_INLINE_CACHE_IGNORE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_IGNORE=1 vitepress build\n```\n\n#### Remove inline cache\n\nTo remove all inline cache, you can use the `TWOSLASH_INLINE_CACHE_REMOVE` environment variable when running the `vitepress` cli.\n\n```bash\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress dev\nTWOSLASH_INLINE_CACHE_REMOVE=1 vitepress build\n```\n\n<!-- File: docs/references/engine-js-compat.md (Tokens: ~4997 | Category: anthropic-skill) -->\n# JavaScript RegExp Engine Compatibility References\n\nCompatibility reference of all built-in grammars with the [JavaScript RegExp engine](/guide/regex-engines#javascript-regexp-engine).\n\n> Generated on Friday, September 11, 2026\n>\n> Version `4.4.3`\n>\n> Runtime: Node.js v24.16.0\n\n## Report Summary\n\n|                 |                       Count |\n| :-------------- | --------------------------: |\n| Total Languages |                         238 |\n| Supported       | [237](#supported-languages) |\n| Mismatched      |  [0](#mismatched-languages) |\n| Unsupported     | [1](#unsupported-languages) |\n\n## Supported Languages\n\nLanguages that work with the JavaScript RegExp engine, and will produce the same result as the WASM engine (with the [sample snippets in the registry](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples)).\nIn some edge cases, it's not guaranteed that the highlighting will be 100% the same. If that happens, please create an issue with the sample snippet.\n\n| Language           | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| ------------------ | :-------------- | ----------------: | --------------: | ---: |\n| abap               | ✅ OK           |                52 |               - |      |\n| actionscript-3     | ✅ OK           |                59 |               - |      |\n| ada                | ✅ OK           |               200 |               - |      |\n| ahk                | ✅ OK           |               125 |               - |      |\n| angular-html       | ✅ OK           |               669 |               - |      |\n| angular-ts         | ✅ OK           |               776 |               - |      |\n| apache             | ✅ OK           |                60 |               - |      |\n| apex               | ✅ OK           |               197 |               - |      |\n| apl                | ✅ OK           |               912 |               - |      |\n| applescript        | ✅ OK           |               152 |               - |      |\n| ara                | ✅ OK           |                54 |               - |      |\n| asciidoc           | ✅ OK           |               319 |               - |      |\n| asm                | ✅ OK           |               298 |               - |      |\n| astro              | ✅ OK           |               610 |               - |      |\n| awk                | ✅ OK           |                36 |               - |      |\n| ballerina          | ✅ OK           |               224 |               - |      |\n| bat                | ✅ OK           |                58 |               - |      |\n| beancount          | ✅ OK           |                42 |               - |      |\n| berry              | ✅ OK           |                21 |               - |      |\n| bibtex             | ✅ OK           |                19 |               - |      |\n| bicep              | ✅ OK           |                31 |               - |      |\n| bird2              | ✅ OK           |               146 |               - |      |\n| blade              | ✅ OK           |              1122 |               - |      |\n| bsl                | ✅ OK           |                97 |               - |      |\n| c                  | ✅ OK           |               176 |               - |      |\n| c3                 | ✅ OK           |               125 |               - |      |\n| cadence            | ✅ OK           |               128 |               - |      |\n| cairo              | ✅ OK           |               236 |               - |      |\n| chapel             | ✅ OK           |               214 |               - |      |\n| clarity            | ✅ OK           |                42 |               - |      |\n| clojure            | ✅ OK           |                38 |               - |      |\n| cmake              | ✅ OK           |                23 |               - |      |\n| cobol              | ✅ OK           |               858 |               - |      |\n| codeowners         | ✅ OK           |                 4 |               - |      |\n| codeql             | ✅ OK           |               147 |               - |      |\n| coffee             | ✅ OK           |               466 |               - |      |\n| common-lisp        | ✅ OK           |                60 |               - |      |\n| coq                | ✅ OK           |                28 |               - |      |\n| cpp                | ✅ OK           |               468 |               - |      |\n| crystal            | ✅ OK           |              1054 |               - |      |\n| csharp             | ✅ OK           |               315 |               - |      |\n| css                | ✅ OK           |               141 |               - |      |\n| csv                | ✅ OK           |                 1 |               - |      |\n| cue                | ✅ OK           |                85 |               - |      |\n| cypher             | ✅ OK           |                39 |               - |      |\n| d                  | ✅ OK           |               272 |               - |      |\n| dart               | ✅ OK           |                79 |               - |      |\n| dax                | ✅ OK           |                23 |               - |      |\n| desktop            | ✅ OK           |                16 |               - |      |\n| diff               | ✅ OK           |                16 |               - |      |\n| docker             | ✅ OK           |                 7 |               - |      |\n| dotenv             | ✅ OK           |                 9 |               - |      |\n| dream-maker        | ✅ OK           |                56 |               - |      |\n| edge               | ✅ OK           |               629 |               - |      |\n| elixir             | ✅ OK           |               704 |               - |      |\n| elm                | ✅ OK           |               241 |               - |      |\n| emacs-lisp         | ✅ OK           |               155 |               - |   22 |\n| erb                | ✅ OK           |              1816 |               - |      |\n| erlang             | ✅ OK           |               270 |               - |      |\n| fennel             | ✅ OK           |                31 |               - |      |\n| fish               | ✅ OK           |                34 |               - |      |\n| fluent             | ✅ OK           |                23 |               - |      |\n| fortran-fixed-form | ✅ OK           |               346 |               - |      |\n| fortran-free-form  | ✅ OK           |               339 |               - |      |\n| fsharp             | ✅ OK           |               242 |               - |      |\n| gdresource         | ✅ OK           |               157 |               - |      |\n| gdscript           | ✅ OK           |                94 |               - |      |\n| gdshader           | ✅ OK           |                39 |               - |      |\n| genie              | ✅ OK           |                20 |               - |      |\n| gherkin            | ✅ OK           |                19 |               - |      |\n| gleam              | ✅ OK           |                26 |               - |      |\n| glimmer-js         | ✅ OK           |               673 |               - |      |\n| glimmer-ts         | ✅ OK           |               673 |               - |      |\n| glsl               | ✅ OK           |               185 |               - |      |\n| gn                 | ✅ OK           |                19 |               - |      |\n| gnuplot            | ✅ OK           |                82 |               - |      |\n| go                 | ✅ OK           |               126 |               - |      |\n| graphql            | ✅ OK           |               445 |               - |      |\n| groovy             | ✅ OK           |               130 |               - |      |\n| hack               | ✅ OK           |               946 |               - |      |\n| haml               | ✅ OK           |               559 |               - |      |\n| handlebars         | ✅ OK           |               696 |               - |      |\n| haskell            | ✅ OK           |               157 |               - |      |\n| haxe               | ✅ OK           |               173 |               - |      |\n| hcl                | ✅ OK           |                67 |               - |      |\n| hjson              | ✅ OK           |                57 |               - |      |\n| hlsl               | ✅ OK           |                52 |               - |      |\n| html               | ✅ OK           |               608 |               - |      |\n| http               | ✅ OK           |               746 |               - |      |\n| hurl               | ✅ OK           |               611 |               - |      |\n| hxml               | ✅ OK           |               182 |               - |      |\n| hy                 | ✅ OK           |                12 |               - |      |\n| imba               | ✅ OK           |               239 |               - |      |\n| ini                | ✅ OK           |                11 |               - |      |\n| java               | ✅ OK           |               141 |               - |      |\n| javascript         | ✅ OK           |               375 |               - |      |\n| jinja              | ✅ OK           |               639 |               - |      |\n| jison              | ✅ OK           |               431 |               - |      |\n| json               | ✅ OK           |                19 |               - |      |\n| json5              | ✅ OK           |                23 |               - |      |\n| jsonc              | ✅ OK           |                19 |               - |      |\n| jsonl              | ✅ OK           |                19 |               - |      |\n| jsonnet            | ✅ OK           |                33 |               - |      |\n| jssm               | ✅ OK           |                30 |               - |      |\n| jsx                | ✅ OK           |               375 |               - |      |\n| julia              | ✅ OK           |              1177 |               - |      |\n| just               | ✅ OK           |              2148 |               - |      |\n| kdl                | ✅ OK           |                30 |               - |      |\n| kotlin             | ✅ OK           |                58 |               - |      |\n| kusto              | ✅ OK           |                60 |               - |      |\n| latex              | ✅ OK           |               312 |               - |      |\n| lean               | ✅ OK           |                31 |               - |      |\n| less               | ✅ OK           |               279 |               - |      |\n| liquid             | ✅ OK           |               689 |               - |      |\n| llvm               | ✅ OK           |                25 |               - |      |\n| log                | ✅ OK           |                31 |               - |      |\n| logo               | ✅ OK           |                 9 |               - |      |\n| lua                | ✅ OK           |               279 |               - |      |\n| luau               | ✅ OK           |                95 |               - |      |\n| make               | ✅ OK           |                51 |               - |      |\n| markdown           | ✅ OK           |               123 |               - |      |\n| marko              | ✅ OK           |               929 |               - |      |\n| matlab             | ✅ OK           |                88 |               - |      |\n| mdc                | ✅ OK           |               786 |               - |      |\n| mdx                | ✅ OK           |               197 |               - |      |\n| mermaid            | ✅ OK           |               175 |               - |      |\n| mipsasm            | ✅ OK           |                17 |               - |      |\n| mojo               | ✅ OK           |               215 |               - |      |\n| moonbit            | ✅ OK           |               101 |               - |      |\n| move               | ✅ OK           |               113 |               - |      |\n| narrat             | ✅ OK           |                34 |               - |      |\n| nextflow           | ✅ OK           |               107 |               - |      |\n| nginx              | ✅ OK           |               378 |               - |      |\n| nim                | ✅ OK           |              1122 |               - |      |\n| nix                | ✅ OK           |                83 |               - |      |\n| nsis               | ✅ OK           |                38 |               - |      |\n| nushell            | ✅ OK           |                85 |               - |      |\n| objective-c        | ✅ OK           |               222 |               - |      |\n| objective-cpp      | ✅ OK           |               306 |               - |      |\n| ocaml              | ✅ OK           |               178 |               - |      |\n| odin               | ✅ OK           |                98 |               - |      |\n| openscad           | ✅ OK           |                24 |               - |      |\n| org                | ✅ OK           |              4715 |               - |      |\n| pascal             | ✅ OK           |                23 |               - |      |\n| perl               | ✅ OK           |               937 |               - |      |\n| php                | ✅ OK           |              1125 |               - |      |\n| pkl                | ✅ OK           |                67 |               - |      |\n| plsql              | ✅ OK           |                45 |               - |      |\n| po                 | ✅ OK           |                23 |               - |      |\n| polar              | ✅ OK           |                31 |               - |      |\n| postcss            | ✅ OK           |                49 |               - |      |\n| powerquery         | ✅ OK           |                30 |               - |      |\n| powershell         | ✅ OK           |                88 |               - |      |\n| prisma             | ✅ OK           |                31 |               - |      |\n| prolog             | ✅ OK           |                26 |               - |      |\n| proto              | ✅ OK           |                33 |               - |      |\n| pug                | ✅ OK           |               683 |               - |      |\n| puppet             | ✅ OK           |                60 |               - |      |\n| purescript         | ✅ OK           |                87 |               - |      |\n| python             | ✅ OK           |               218 |               - |      |\n| qml                | ✅ OK           |               407 |               - |      |\n| qmldir             | ✅ OK           |                 7 |               - |      |\n| qss                | ✅ OK           |                31 |               - |      |\n| r                  | ✅ OK           |                66 |               - |      |\n| racket             | ✅ OK           |                69 |               - |      |\n| raku               | ✅ OK           |                52 |               - |      |\n| razor              | ✅ OK           |               960 |               - |      |\n| rbs                | ✅ OK           |                33 |               - |      |\n| reg                | ✅ OK           |                 9 |               - |      |\n| regexp             | ✅ OK           |                34 |               - |      |\n| rel                | ✅ OK           |                17 |               - |      |\n| riscv              | ✅ OK           |                36 |               - |      |\n| ron                | ✅ OK           |                35 |               - |      |\n| rosmsg             | ✅ OK           |                31 |               - |      |\n| rst                | ✅ OK           |              2057 |               - |      |\n| ruby               | ✅ OK           |              1808 |               - |      |\n| rust               | ✅ OK           |                89 |               - |      |\n| sas                | ✅ OK           |               100 |               - |      |\n| sass               | ✅ OK           |                69 |               - |      |\n| scala              | ✅ OK           |               116 |               - |      |\n| scheme             | ✅ OK           |                34 |               - |      |\n| scss               | ✅ OK           |               233 |               - |      |\n| sdbl               | ✅ OK           |                23 |               - |      |\n| shaderlab          | ✅ OK           |                87 |               - |      |\n| shellscript        | ✅ OK           |               147 |               - |      |\n| shellsession       | ✅ OK           |               149 |               - |      |\n| smalltalk          | ✅ OK           |                64 |               - |      |\n| smithy             | ✅ OK           |                42 |               - |      |\n| solidity           | ✅ OK           |               105 |               - |      |\n| soy                | ✅ OK           |               646 |               - |      |\n| sparql             | ✅ OK           |                19 |               - |      |\n| splunk             | ✅ OK           |                17 |               - |      |\n| sql                | ✅ OK           |                68 |               - |      |\n| ssh-config         | ✅ OK           |                12 |               - |      |\n| stata              | ✅ OK           |               254 |               - |      |\n| stylus             | ✅ OK           |               106 |               - |      |\n| surrealql          | ✅ OK           |               467 |               - |      |\n| svelte             | ✅ OK           |               646 |               - |      |\n| swift              | ✅ OK           |               340 |               - |      |\n| system-verilog     | ✅ OK           |               102 |               - |      |\n| systemd            | ✅ OK           |                32 |               - |      |\n| talonscript        | ✅ OK           |                46 |               - |      |\n| tasl               | ✅ OK           |                23 |               - |      |\n| tcl                | ✅ OK           |                34 |               - |      |\n| templ              | ✅ OK           |               674 |               - |      |\n| terraform          | ✅ OK           |                68 |               - |      |\n| tex                | ✅ OK           |               103 |               - |      |\n| toml               | ✅ OK           |                44 |               - |      |\n| ts-tags            | ✅ OK           |               997 |               - |      |\n| tsv                | ✅ OK           |                 1 |               - |      |\n| tsx                | ✅ OK           |               375 |               - |      |\n| turtle             | ✅ OK           |                15 |               - |      |\n| twig               | ✅ OK           |              2445 |               - |      |\n| typescript         | ✅ OK           |               362 |               - |      |\n| typespec           | ✅ OK           |                73 |               - |      |\n| typst              | ✅ OK           |              5699 |               - |      |\n| v                  | ✅ OK           |                77 |               - |      |\n| vala               | ✅ OK           |                20 |               - |      |\n| vb                 | ✅ OK           |                34 |               - |      |\n| verilog            | ✅ OK           |                34 |               - |      |\n| vhdl               | ✅ OK           |                82 |               - |      |\n| viml               | ✅ OK           |                72 |               - |      |\n| vue                | ✅ OK           |               705 |               - |      |\n| vue-html           | ✅ OK           |               404 |               - |      |\n| vue-vine           | ✅ OK           |              1032 |               - |      |\n| vyper              | ✅ OK           |               238 |               - |      |\n| wasm               | ✅ OK           |                78 |               - |      |\n| wenyan             | ✅ OK           |                18 |               - |      |\n| wgsl               | ✅ OK           |                44 |               - |      |\n| wikitext           | ✅ OK           |               105 |               - |      |\n| wit                | ✅ OK           |                81 |               - |      |\n| wolfram            | ✅ OK           |               501 |               - |      |\n| xml                | ✅ OK           |               168 |               - |      |\n| xsl                | ✅ OK           |               170 |               - |      |\n| yaml               | ✅ OK           |                48 |               - |      |\n| zenscript          | ✅ OK           |                21 |               - |      |\n| zig                | ✅ OK           |                51 |               - |      |\n\n###### Table Field Explanations\n\n- **Highlight Match**: Whether the highlighting results matched with the WASM engine for the [sample snippet](https://github.com/shikijs/textmate-grammars-themes/tree/main/samples).\n- **Patterns Parsable**: Number of regex patterns that can be parsed by the JavaScript RegExp engine.\n- **Patterns Failed**: Number of regex patterns that can't be parsed by the JavaScript RegExp engine (throws error).\n- **Diff**: Length of characters that are different between the highlighting results of the two engines.\n\n## Mismatched Languages\n\nLanguages that do not throw with the JavaScript RegExp engine, but will produce different results than the WASM engine.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n\n## Unsupported Languages\n\nLanguages that throw with the JavaScript RegExp engine, either because they contain syntax we can't polyfill yet or because the grammar contains an invalid Oniguruma regex (that would also fail when using the WASM engine, but silently). You can try these languages with the `forgiving` option to skip errors.\n\n| Language | Highlight Match | Patterns Parsable | Patterns Failed | Diff |\n| -------- | :-------------- | ----------------: | --------------: | ---: |\n| ahk2     | ❌ Error        |               188 |               1 |   16 |\n\n<!-- File: docs/api.md (Tokens: ~3051 | Category: project-spec) -->\n# API References\n\n## `codeToHast`\n\nYou can also get the intermediate `hast` to do custom rendering without serializing them into HTML with `codeToHast`. You can also further integrate the AST with the [unified](https://github.com/unifiedjs) ecosystem.\n\n```ts twoslash\n// @twoslash-cache: {\"v\":1,\"hash\":\"aa0ea59b9742ed721640f4d1233696e3e09408080ce58a4fde6a5efd7f40382b\",\"data\":\"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=\"}\nimport { createHighlighter } from 'shiki'\n\nconst highlighter = await createHighlighter({\n  themes: ['nord', 'min-light'],\n  langs: ['javascript'],\n})\n// ---cut---\nconst root = highlighter.codeToHast(\n  'const a = 1',\n  { lang: 'javascript', theme: 'nord' }\n)\n\nconsole.log(root)\n```\n\n<!-- eslint-skip -->\n\n```ts\n{\n  type: 'root',\n  children: [\n    {\n      type: 'element',\n      tagName: 'pre',\n      properties: {\n        class: 'shiki vitesse-light',\n        style: 'background-color:#ffffff;color:#393a34',\n        tabindex: '0'\n      },\n      children: [\n        {\n          type: 'element',\n          tagName: 'code',\n          properties: {},\n          children: [\n            {\n              type: 'element',\n              tagName: 'span',\n              properties: { class: 'line' },\n              children: [\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#AB5959' },\n                  children: [ { type: 'text', value: 'const' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#B07D48' },\n                  children: [ { type: 'text', value: ' a' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#999999' },\n                  children: [ { type: 'text', value: ' =' } ]\n                },\n                {\n                  type: 'element',\n                  tagName: 'span',\n                  properties: { style: 'color:#2F798A' },\n                  children: [ { type: 'text', value: ' 1' } ]\n                }\n              ]\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}\n```\n\n<!-- File: packages/cli/README.md (Tokens: ~28 | Category: plugin-manifest) -->\n# shiki-cli\n\nShiki in the command line.\n\n[Documentation](https://shiki.style/packages/cli)\n\n## License\n\nMIT\n\n<!-- File: packages/codegen/README.md (Tokens: ~35 | Category: plugin-manifest) -->\n# @shikijs/codegen\n\nCodegen for fine-grained Shiki bundles.\n\n[Documentation](https://shiki.style/packages/codegen)\n\n## License\n\nMIT\n\n<!-- File: packages/colorized-brackets/README.md (Tokens: ~51 | Category: plugin-manifest) -->\n# @shikijs/colorized-brackets\n\nVSCode-style colorized brackets transformer for [Shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/colorized-brackets)\n\n## License\n\nMIT\n\n<!-- File: packages/core/README.md (Tokens: ~43 | Category: plugin-manifest) -->\n# @shikijs/core\n\nThe core functionality of [Shiki](https://github.com/shikijs/shiki), without any grammar of themes bundled.\n\nIt's the same as importing `shiki/core`.\n\n<!-- File: packages/engine-javascript/README.md (Tokens: ~72 | Category: plugin-manifest) -->\n# @shikijs/engine-javascript\n\nEngine for Shiki using JavaScript's native RegExp. Uses [Oniguruma-To-ES](https://github.com/slevithan/oniguruma-to-es) to transpile regex syntax and behavior.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n\n<!-- File: packages/engine-oniguruma/README.md (Tokens: ~46 | Category: plugin-manifest) -->\n# @shikijs/engine-oniguruma\n\nEngine for Shiki using Oniguruma RegExp engine in WebAssembly.\n\n[Documentation](https://shiki.style/guide/regex-engines)\n\n## License\n\nMIT\n\n<!-- File: packages/langs-precompiled/README.md (Tokens: ~48 | Category: plugin-manifest) -->\n# @shikijs/langs-precompiled\n\nPrecompiled languages for Shiki that can runs in pure JavaScript environment.\n\nRequires ES2024+ environment.\n\n> **Experimental**\n\n## Unsupported Languages\n\n<!-- TODOs -->\n\n## License\n\nMIT\n\n<!-- File: packages/langs/README.md (Tokens: ~21 | Category: plugin-manifest) -->\n# @shikijs/langs\n\nTextMate grammars for Shiki.\n\n## License\n\nMIT\n\n<!-- File: packages/magic-move/README.md (Tokens: ~82 | Category: plugin-manifest) -->\n# @shikijs/magic-move\n\nSmoothly animated code blocks with [shiki](https://github.com/shikijs/shiki). Useful for code-step animations in slide decks (e.g. [Slidev](https://sli.dev/guide/syntax#shiki-magic-move)) and tutorials.\n\n[Documentation](https://shiki.style/packages/magic-move)\n\n## License\n\nMIT\n\n<!-- File: packages/markdown-exit/README.md (Tokens: ~63 | Category: plugin-manifest) -->\n# @shikijs/markdown-exit\n\n[markdown-exit](https://github.com/serkodev/markdown-exit) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-exit)\n\n## License\n\nMIT\n\n<!-- File: packages/markdown-it/README.md (Tokens: ~54 | Category: plugin-manifest) -->\n# @shikijs/markdown-it\n\n[markdown-it](https://markdown-it.github.io/) plugin for [shiki](https://github.com/shikijs/shiki)\n\n[Documentation](https://shiki.style/packages/markdown-it)\n\n## License\n\nMIT\n\n<!-- File: packages/monaco/README.md (Tokens: ~61 | Category: plugin-manifest) -->\n# @shikijs/monaco\n\nUse [shiki](https://github.com/shikijs/shiki) to highlight [Monaco Editor](https://microsoft.github.io/monaco-editor/).\n\n[Documentation](https://shiki.style/packages/monaco)\n\n## License\n\nMIT\n\n<!-- File: packages/rehype/README.md (Tokens: ~57 | Category: plugin-manifest) -->\n# rehype-shiki\n\n[rehype](https://github.com/rehypejs/rehype) plugin for [shiki](https://github.com/shikijs/shiki).\n\n[Documentation](https://shiki.style/packages/rehype)\n\n## License\n\nMIT\n\n<!-- ... +7 more modular skills available via /api/skills/shikijs/shiki?path={path} -->\n</yakaai_skills>"}