7 Runtimes
CLI, Rust, Elixir, JavaScript / TypeScript, Browsers / CDN. Java and Python maintained by the community.
110+ Languages
Compiled Tree-sitter grammars containing highlights and injections.
250+ Themes
Neovim colorschemes btw. Pick one of the built-in themes or bring your own.
5 Formatters
HTML Inline, HTML Linked, Multi Theme, Terminal, BBCode + bring your own.
Install, import, highlight.
cargo install lumis-cli
lumis highlight index.js --lang javascript --theme dracula
cargo add lumis
use lumis::{highlight, HtmlInlineBuilder, languages::Language, themes};
let theme = themes::get("dracula").unwrap();
let formatter = HtmlInlineBuilder::new()
.language(Language::JavaScript)
.theme(Some(theme))
.build()
.unwrap();
let html = highlight("const x = 1", formatter);
npm install @lumis-sh/lumis @lumis-sh/themes @lumis-sh/wasm-javascript
The same package works in JavaScript and TypeScript, with types included. It loads exact parser WASM per language from the packages you install.
import { highlight } from '@lumis-sh/lumis'
import { htmlInline } from '@lumis-sh/lumis/formatters'
import dracula from '@lumis-sh/themes/dracula'
import javascript from '@lumis-sh/wasm-javascript'
const html = await highlight(
'const x = 1',
htmlInline({ language: javascript, theme: dracula })
)
import { highlight } from 'https://cdn.jsdelivr.net/npm/@lumis-sh/lumis/+esm'
import { htmlInline } from 'https://cdn.jsdelivr.net/npm/@lumis-sh/lumis/dist/formatters.js'
import dracula from 'https://cdn.jsdelivr.net/npm/@lumis-sh/themes/dist/themes/dracula.js'
import javascript from 'https://cdn.jsdelivr.net/npm/@lumis-sh/wasm-javascript/+esm'
document.getElementById('output').innerHTML = await highlight(
'const x = 1',
htmlInline({ language: javascript, theme: dracula })
)
{:lumis, "~> 0.10"},
{:lumis_wasm_javascript, "~> 0.26.0"}
Lumis.highlight!(
"const x = 1",
formatter: {:html_inline, language: "javascript", theme: "dracula"}
)
io.roastedroot:lumis4j:0.0.7
Lumis4J is maintained by roastedroot. Java guide
import io.roastedroot.lumis4j.core.Lumis;
import io.roastedroot.lumis4j.core.Lang;
import io.roastedroot.lumis4j.core.Theme;
var lumis = Lumis.builder().build();
var highlighter = lumis.highlighter()
.withLang(Lang.JAVASCRIPT)
.withTheme(Theme.DRACULA)
.build();
var result = highlighter.highlight("const x = 1");
lumis.close();
pip install fastpylight
fastpylight is maintained by Answer.AI. Add the generated CSS to your page to apply the theme. Python guide
from fastpylight import highlight_spans, theme_css
html = highlight_spans("const x = 1", "javascript")
css = theme_css("dracula", "pre code")
Built-in formatters or bring your own.
html_inline
Inline styles on every token. Zero config, works everywhere.
html_linked
Class names instead of inline styles. Full control, cacheable stylesheets.
html_multi_theme
CSS custom properties for multiple themes. Automatic switching with prefers-color-scheme.
terminal
ANSI escape codes. Same themes, same colors, rendered in your shell.
bbcode_scoped
BBCode with scoped color tags. Forum posts, game chat, Discord-style rich text.
custom
Implement the formatter trait/interface to output any format. Markdown, LaTeX, whatever.
Tree-sitter parsing every token.
-
Highlight nested injected languages.
- Multi-level nesting
- Each injected language gets its own parser, loaded during the pass that finds it. No depth limits, no second pass.
- Language-aware scopes
- Tokens know which language they belong to. Themes apply the right colors automatically.
- Real embedded syntax
- Injected blocks are not plain text, so strings, keywords, and punctuation keep the right scopes.
Pre-built WASM parsers.
>npm install @lumis-sh/wasm-html
>npm install @lumis-sh/wasm-bundle-full
- 110+ grammars
- Every language includes highlight queries and injection support, tested for conformance.
- Loaded when a document needs them
- Node reads each parser from the package a project installed, and loads the languages injected inside a document in the same pass. A browser loads the packages it imports. Nothing comes from a CDN unless you configure a resolver.
- Persistent and verified
- Every parser Lumis downloads is checked against the SHA-256 its package declares before it runs. Node.js, Bun, Deno, browsers, and Elixir keep parsers across restarts.
- Verified on npm
- Published with provenance. Browse all packages at npm.
Lumis in the wild.
See how other projects use Lumis.
Community runtimes
roastedroot maintains Lumis4J for Java. Answer.AI maintains fastpylight for Python. Both packages have their own APIs and releases. Check the guides for supported features and examples.
Community runtime guidesUsed by
-
Elixir
Hex.pm
Highlights package source.
-
Elixir
Tuist
Highlights Markdown through MDEx.
-
Elixir
Oban Pro
Highlights website code examples through MDEx.
-
Elixir
Petal Components
Highlights HEEx component examples through MDEx.
-
TypeScript
SocratiCode
Uses Lumis parsers to analyze HEEx and EEx templates.
-
Rust
see
Highlights code and Markdown in the terminal.
Mentions
-
Chris Coyier · Master.dev
Lumis: Syntax Highlighter powered by Tree-sitter
An introduction to Lumis and its runtimes.
-
Andrea Peruffo · Chicory
Syntax highlighting in Java, without the pain
How Lumis4J brings Lumis to the JVM through WebAssembly.
-
Elixir Mentor · Interview
Leandro Pereira on MDEx
A conversation about MDEx, Lumis, open source, and AI.
To add your project or a mention, send a PR.