Skip to main content

WASM and CDN

What ships where

  • @lumis-sh/lumis ships the JS API and embedded web-tree-sitter runtime WASM
  • parser grammars are separate .wasm files 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:

Default resolver pattern
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:

Alternative CDN pattern
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.

Installed package autoload
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.

See packages/javascript/lumis/examples/npm-wasm-node.

Override the resolver

Override configureWasmResolver to use your own CDN, local files, or work offline.

Global resolver
import {configureWasmResolver} from '@lumis-sh/lumis'
configureWasmResolver((_language, wasm) =>
`https://unpkg.com/${wasm.packageName}@${wasm.version}/${wasm.name}.wasm`
)
Per-highlighter resolver
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`,
})

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.

ESM CDN
<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>