Shiki

The @devframes/service-shiki wire service: node-side Shiki syntax highlighting shared over RPC, LRU-cached and dual-theme, so client bundles stop shipping their own grammars and themes.

Server-side Shiki syntax highlighting shared over RPC by every devframe on the host, so client bundles stop shipping their own grammars and themes. Shiki itself loads lazily on first use; results are LRU-cached per (code, lang, themes) and every RPC function is cacheable on the client too.

Package: @devframes/service-shiki · Scope: devframes:service:shiki

Installing

defineDevframe({
  importMetaUrl: import.meta.url,
  services: [
    { package: '@devframes/service-shiki', options: { langs: ['vue', 'ts'] } },
  ],
})

A hub installs a shared instance with initHub({ services: [createShikiService(options)] }).

Options

ShikiServiceOptions — later installer wins on themes (deep-merged per key); langs union-merged.

OptionTypeDescription
themes{ light, dark }Dual light/dark theme pair every request uses unless it carries its own. Defaults to vitesse-light / vitesse-dark.
langsstring[]Languages to eagerly load at setup. Others load on demand per request; unknown ids degrade to plain text instead of throwing.

RPC functions

Registered under devframes:service:shiki:*, all query and cacheable. Each takes { code, lang?, themes? }.

FunctionReturns
highlight{ html } — dual-theme HTML (light values inline, dark via --shiki-dark vars).
code-to-hastA HAST tree, for surfaces that render their own DOM.
code-to-tokensThemed tokens, for line-oriented renderers (e.g. diff views).

Node API

ctx.services.get('@devframes/service-shiki') returns the in-process ShikiServiceApi: highlight, codeToHast, and codeToTokens.

On the RPC client

const rpc = await connectDevframe()

if (rpc.services.has('@devframes/service-shiki')) {
  const shiki = rpc.services.get('@devframes/service-shiki')!
  const { html } = await shiki.rpc.call('highlight', { code, lang: 'ts' })
}

Source

services/shiki