Lumis Docs
Usage

Highlight

Highlight code with one Lumis workflow across CLI, Rust, Elixir, JavaScript / TypeScript, and Java.

This is the core Lumis workflow: choose a language, choose a formatter, then render output.

Simple example

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

Options by runtime

NeedCLIRustElixirJavaScript / TypeScriptJava
Set language--language.language(...)language: "..."language: ...withLang(...)
Set theme--theme.theme(...)theme: "..."theme: ...withTheme(...)
Choose output--formatterbuilder typeformatter: ...formatter factoryruntime-specific
Bound query matches--match-limit.match_limit(...)match_limit: ...matchLimit: ...runtime-specific

Language detection

If you omit the language, Lumis tries to detect it using:

  • file extensions (.rs, .js, .ex, etc.)
  • filenames (Makefile, Dockerfile, Caddyfile)
  • shebangs (#!/usr/bin/env python)
  • Emacs mode lines (-*- mode: ruby -*-)

If detection fails, it falls back to plaintext.

Match limit

Tree-sitter walks its whole pool of in-progress matches before it emits each capture, so a query pattern that stays open across a large subtree costs more the deeper the document nests. Lumis bounds the number of matches kept in progress at 8192, for the highlight and bracket queries alike. HTML and the languages that embed it do not depend on that bound to stay fast, because their layers replay captures from finished matches; the bound is what keeps other languages linear when a query pattern stays open across a large subtree.

Raise it when a document is large enough that tree-sitter drops matches and scopes go missing, and accept the extra time. Tree-sitter accepts 1 to 65536; every runtime rejects anything else.

const html = await highlight(source, htmlInline({language: html_, theme: frappe}), {
matchLimit: 16384,
});

Incomplete code

Lumis handles incomplete or malformed code without crashing. Tree-sitter produces a partial syntax tree and Lumis highlights what it can. This is useful for streaming scenarios where code arrives in chunks (e.g., LLM output).

Next steps

On this page