Skip to main content

JavaScript

For one-off highlighting

Use highlight() when you just need one async highlight call and do not need to keep a highlighter instance around.

import {highlight} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import dracula from '@lumis-sh/themes/dracula'
const html = await highlight(
'const x = 1',
htmlInline({language: javascript, theme: dracula})
)

highlight() uses a shared default runtime, so loaded languages and global WASM resolver changes are process-wide.

For reusable highlighters

Use createHighlighter() when you want instance isolation, explicit setup, lazy loading, or repeated synchronous hl.highlight() calls after initialization.

import {createHighlighter} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import dracula from '@lumis-sh/themes/dracula'
const hl = await createHighlighter({languages: [javascript]})
const html = hl.highlight(
'const x = 1',
htmlInline({language: javascript, theme: dracula})
)

This creates an isolated highlighter unless you intentionally rely on the global resolver.

Bundles

Bundles register many languages lazily.

BundlePurpose
@lumis-sh/lumis/bundles/webHTML, CSS, JS, TS, JSON, Markdown, SQL, Svelte, Vue, Astro, and other web-focused languages
@lumis-sh/lumis/bundles/web-extraframework and template languages that complement the web bundle
@lumis-sh/lumis/bundles/systemC, C++, Rust, Go, Zig, LLVM, Make, CMake, and related system languages
@lumis-sh/lumis/bundles/backendpopular backend languages plus common API, config, and infra formats
@lumis-sh/lumis/bundles/fullall supported languages
import {createHighlighter} from '@lumis-sh/lumis'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
const hl = await createHighlighter({languages: [bundledLanguages]})
hl.registeredLanguages // registered, including lazy entries
hl.languages // loaded right now, usually just plaintext at first

Lazy loading

You can register a language now and load it only when needed.

import {createHighlighter} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import dracula from '@lumis-sh/themes/dracula'
const hl = await createHighlighter({languages: [bundledLanguages]})
await hl.loadLanguage(bundledLanguages.javascript)
const html = hl.highlight(
'const x = 1',
htmlInline({language: bundledLanguages.javascript, theme: dracula})
)

createHighlighter({ languages }) accepts:

  • eager Language objects
  • a bundle object
  • dynamic import promises
  • lazy import functions

Repeated highlighting

Preload languages once with createHighlighter(), then call hl.highlight() synchronously for repeated work.

import {createHighlighter} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import javascript from '@lumis-sh/lumis/langs/javascript'
import dracula from '@lumis-sh/themes/dracula'
const hl = await createHighlighter({languages: [javascript]})
const html = hl.highlight(
'const x = 1',
htmlInline({language: javascript, theme: dracula})
)

Language references

These are equivalent at highlight time:

htmlInline({language: json, theme})
htmlInline({language: bundledLanguages.json, theme})
htmlInline({language: 'json', theme})

Auto-detection and plaintext fallback

If you omit language, Lumis tries to detect it and falls back to plaintext when it can't.

Detection methods:

  • file extensions (.rs, .js, .ex)
  • filenames (Makefile, Dockerfile)
  • shebangs (#!/usr/bin/env python)
  • Emacs mode lines
const html = await highlight(source, htmlInline({theme: dracula}))

Useful when rendering user-provided content or pasted snippets.

Injected languages

Lumis can highlight embedded languages such as HTML with CSS and JavaScript inside it.

Important rule: load every participating language, not just the outer one.

const hl = await createHighlighter({languages: [html, css, javascript]})
const htmlOutput = hl.highlight(source, htmlInline({language: html, theme: dracula}))

If nested languages are missing, Lumis cannot fully highlight those embedded regions.

Metadata APIs

Useful for dropdowns, config validation, and docs tooling:

Runtime notes

  • the package uses conditional exports so Node and web-standard runtimes get the right runtime automatically
  • Node caches fetched parser WASM locally when possible
  • Node can also auto-load installed parser packages such as @lumis-sh/wasm-elixir or bundle packages such as @lumis-sh/wasm-bundle-web
  • non-Node usage usually relies on remote parser assets unless you override the resolver, use withWasm() with a single npm parser package such as @lumis-sh/wasm-json, or use withWasmBundle() with a bundle package such as @lumis-sh/wasm-bundle-web
  • Bun and Deno are also supported
Edge is not supported yet

Lumis still uses web-tree-sitter in the JavaScript runtime, but Edge runtimes are not supported yet because of an upstream Tree-sitter limitation: tree-sitter/tree-sitter#2160.

For parser asset details, continue with WASM and CDN.