WASM and CDN
What ships where
@lumis-sh/lumisships the JS API and embeddedweb-tree-sitterruntime WASM- parser grammars are separate
.wasmfiles loaded at runtime - each parser also has its own npm package such as
@lumis-sh/wasm-rust
Default JavaScript behavior
By default, Lumis resolves parser WASM from jsDelivr using versioned packages.
The default shape is:
https://cdn.jsdelivr.net/npm/@lumis-sh/wasm-<parser-name-without-tree-sitter-prefix>@<tree-sitter-version>/<parser>.wasm
Equivalent URLs also work on other CDNs such as unpkg:
https://unpkg.com/@lumis-sh/wasm-<parser-name-without-tree-sitter-prefix>@<tree-sitter-version>/<parser>.wasm
In Node.js, fetched parser files are cached locally when possible.
If a matching npm parser package is installed, such as @lumis-sh/wasm-elixir, Node can load that package directly before falling back to the resolver URL.
NPM WASM packages
Lumis supports two good npm-based workflows:
- Node: install the parser package and use the normal language import
- non-Node runtimes with bundled assets: import the parser package explicitly and apply it with
withWasm()
For multiple languages, install a bundle package such as @lumis-sh/wasm-bundle-web and pair it with the matching Lumis bundle.
- Node
- Node bundle
- Bundlers
- Bundle
import {createHighlighter} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import elixir from '@lumis-sh/lumis/langs/elixir'
import githubLight from '@lumis-sh/themes/github_light'
import '@lumis-sh/wasm-elixir'
const hl = await createHighlighter({
languages: [elixir],
})
const html = hl.highlight(
'defmodule Demo do\nend',
htmlInline({language: elixir, theme: githubLight})
)
This is the optimized Node DX. Once @lumis-sh/wasm-elixir is installed, Lumis can load it automatically.
import {createHighlighter} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import githubLight from '@lumis-sh/themes/github_light'
import '@lumis-sh/wasm-bundle-web'
const hl = await createHighlighter({
languages: [bundledLanguages],
})
await hl.loadLanguage(bundledLanguages.javascript)
const html = hl.highlight(
'const theme = "github-light"',
htmlInline({language: bundledLanguages.javascript, theme: githubLight})
)
Use this when you want one package in package.json to cover a whole preset. Lumis still imports only @lumis-sh/lumis/bundles/web; Node resolves the installed parser packages automatically.
import {createHighlighter, withWasm} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import elixir from '@lumis-sh/lumis/langs/elixir'
import githubLight from '@lumis-sh/themes/github_light'
import elixirWasm from '@lumis-sh/wasm-elixir'
const elixirFromNpm = withWasm(elixir, elixirWasm)
const hl = await createHighlighter({
languages: [elixirFromNpm],
})
const html = hl.highlight(
'defmodule Demo do\nend',
htmlInline({language: elixirFromNpm, theme: githubLight})
)
Use this when you want bundler-managed parser assets instead of a CDN fetch in browsers or similar non-Node environments.
import {createHighlighter, withWasmBundle} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import {bundledLanguages} from '@lumis-sh/lumis/bundles/web'
import {bundledWasms} from '@lumis-sh/wasm-bundle-web'
import githubLight from '@lumis-sh/themes/github_light'
const languages = withWasmBundle(bundledLanguages, bundledWasms)
const hl = await createHighlighter({
languages: [languages],
})
await hl.loadLanguage(languages.javascript)
const html = hl.highlight(
'const theme = "github-light"',
htmlInline({language: languages.javascript, theme: githubLight})
)
Use this when you want local, bundler-managed parser assets for a whole preset in browsers or similar non-Node environments instead of wiring each language one by one.
Override the resolver
Override configureWasmResolver to use your own CDN, local files, or work offline.
- JavaScript
- CLI
import {configureWasmResolver} from '@lumis-sh/lumis'
configureWasmResolver((_language, wasm) =>
`https://unpkg.com/${wasm.packageName}@${wasm.version}/${wasm.name}.wasm`
)
import {createHighlighter} from '@lumis-sh/lumis'
import rust from '@lumis-sh/lumis/langs/rust'
const hl = await createHighlighter({
languages: [rust],
wasmResolver: (_language, wasm) => `/wasm/${wasm.name}.wasm`,
})
lumis parsers fetch rust javascript elixir
lumis parsers fetch --all
lumis parsers update rust
The CLI does not expose a custom WASM resolver hook. Use the parser cache commands and --data-dir when you need local control over parser files.
Browsers / CDN usage
This works well when your app can fetch parser WASM files from the default CDN. If you need a different host or local assets, set a custom resolver first. If you want bundler-managed parser assets from npm instead, prefer withWasm() for single languages or withWasmBundle() for preset bundles.
<script type="module">
import {highlight} from 'https://esm.sh/@lumis-sh/lumis'
import {htmlInline} from 'https://esm.sh/@lumis-sh/lumis/formatters'
import javascript from 'https://esm.sh/@lumis-sh/lumis/langs/javascript'
import dracula from 'https://esm.sh/@lumis-sh/themes/dracula'
const html = await highlight(
'const x = 1',
htmlInline({language: javascript, theme: dracula})
)
</script>
Related docs
- full language and WASM package list: Languages
- JavaScript runtime overview: JavaScript Runtime
- CLI parser commands: CLI Commands
- runtime and package overview: Runtimes