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.
| Bundle | Purpose |
|---|---|
@lumis-sh/lumis/bundles/web | HTML, CSS, JS, TS, JSON, Markdown, SQL, Svelte, Vue, Astro, and other web-focused languages |
@lumis-sh/lumis/bundles/web-extra | framework and template languages that complement the web bundle |
@lumis-sh/lumis/bundles/system | C, C++, Rust, Go, Zig, LLVM, Make, CMake, and related system languages |
@lumis-sh/lumis/bundles/backend | popular backend languages plus common API, config, and infra formats |
@lumis-sh/lumis/bundles/full | all 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
Languageobjects - 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-elixiror 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 usewithWasmBundle()with a bundle package such as@lumis-sh/wasm-bundle-web - Bun and Deno are also supported
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.