Back to Shiki

Load Custom Themes

docs/guide/load-theme.md

4.0.27.8 KB
Original Source

Load Custom Themes

See All Builtin Themes first.

You can load custom themes by passing a Theme object into the themes array.

ts
// @twoslash-cache: {"v":1,"hash":"ecccd0c27d317b9e1025f60636e0e20412224f122cf5409cf9938dab82f3e544","data":"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"}
import { createHighlighter } from 'shiki'

const myTheme = {
  name: 'my-theme',
  settings: [
    {
      scope: ['comment'],
      settings: {
        foreground: '#888'
      }
    },
    // ...
  ]
}

const highlighter = await createHighlighter({
  themes: [myTheme],
  langs: [],
})

const code = `console.log('hello')`
const html = highlighter.codeToHtml(code, {
  lang: 'javascript',
  theme: 'my-theme'
})

You can also load themes after the highlighter has been created.

ts
// @twoslash-cache: {"v":1,"hash":"0fbfdd8ea3db3258422f519f6001c1ca7974cb0a5a8d6f9a1a1c43e20177e786","data":"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="}
// @noErrors
import { createHighlighter } from 'shiki'

// Load the theme object from a file, a network request, or anywhere
const myTheme = JSON.parse(fs.readFileSync('my-theme.json', 'utf8'))

const highlighter = await createHighlighter({
  langs: ['javascript'],
  themes: [],
})

await highlighter.loadTheme(myTheme) // <--

const code = `console.log('hello')`
const html = highlighter.codeToHtml(code, {
  lang: 'javascript',
  theme: 'my-theme'
})

The theme is a TextMate theme in JavaScript object. For example, it should look like this.