- 110+ Tree-sitter languages - Fast, accurate, and updated syntax parsing
- 250+ built-in Neovim themes - Updated and curated themes from the Neovim community
- 7 runtimes - CLI, Rust, Elixir, JavaScript / TypeScript, and Browsers / CDN, plus community-maintained Java and Python packages
- Built-in formatters - HTML (inline/linked), Terminal (ANSI), Multi-theme (light/dark), BBCode
- Custom formatters - Build your own output
- Language auto-detection - File extension, shebang, and emacs-mode support
- Line highlighting - Mark and style individual lines, with custom HTML wrappers
- Streaming-friendly - Handles incomplete code
- Load parsers on demand - Verified and cached, including injected languages
![]() |
![]() |
curl -LsSf https://lumis.sh/install.sh | sh
lumis highlight app.jsFor a global install:
npm install -g @lumis-sh/cli
lumis highlight app.jsuse 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);Use the same package in JavaScript and TypeScript apps on Node.js, Bun, and Deno. TypeScript declarations are included.
npm install @lumis-sh/lumis @lumis-sh/themes @lumis-sh/wasm-javascriptimport { 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 }))Each language is its own package, and its default export is the language. Parsers load on demand from the packages you install, including languages injected inside a document. Browsers load only the packages you import, and since loading is asynchronous there, an injected language has to be loaded first. See Languages.
Works in Browsers through bundlers or CDN imports, with the same imports.
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'
const html = await highlight('const x = 1', htmlInline({ language: javascript, theme: dracula }))Lumis.highlight!("const x = 1", formatter: {:html_inline, language: "javascript", theme: "dracula"})A parser is a Hex dependency, such as {:lumis_wasm_javascript, "~> 0.26.0"},
and loads once per VM. Call Lumis.Languages.async_load/1 from your
application's start/2 to move the compile off the first request without
holding up the boot.
See Elixir integration.
The Java and Python packages have their own APIs and releases. Check their guides for supported features.
Maintained by @andreaTP at roastedroot. See the 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");
System.out.println(result.string());
lumis.close();Maintained by Answer.AI. See the Python guide.
pip install fastpylightfrom fastpylight import highlight_spans, theme_css
html = highlight_spans("const x = 1", "javascript")
css = theme_css("dracula", "pre code")Add the generated CSS to your page to apply the theme.
| Runtime | Install | Package | Docs |
|---|---|---|---|
| CLI | curl -LsSf https://lumis.sh/install.sh | sh |
GitHub Releases | Install |
| Rust | cargo add lumis |
crates.io/lumis | README.md • docs.rs |
| Elixir | {:lumis, "~> 0.9"} |
hex.pm/lumis | README.md • hexdocs |
| JavaScript / TypeScript | npm install @lumis-sh/lumis |
npmjs.com/@lumis-sh/lumis | README.md |
| Browsers / CDN | npm install @lumis-sh/lumis |
npmjs.com/@lumis-sh/lumis | README.md |
| Java (community) | io.roastedroot:lumis4j:0.0.7 |
io.roastedroot/lumis4j | Java guide |
| Python (community) | pip install fastpylight |
PyPI | Python guide |
Use Lumis4J for Java or fastpylight for Python. See the examples above or the community runtime guides.
- Hex.pm: Highlights package source.
- Tuist: Highlights Markdown through MDEx.
- Oban Pro: Highlights website code examples through MDEx.
- mdhtml: Optional code highlighting for Markdown through fastpylight.
- mdhtml2docx: Optional code highlighting in Word documents through fastpylight.
- jacko.io: Blog code blocks with light and dark themes.
- termframe: Syntax highlighting for terminal screenshots.
- RPGMTranslate: Highlights code in a Qt app for translating RPG Maker games.
- Aster: Code blocks in a static site generator built with Typst.
Full project list and integration links.
- Lumis: Syntax Highlighter powered by Tree-sitter: Chris Coyier, Master.dev.
- Syntax highlighting in Java, without the pain: Andrea Peruffo, on building Lumis4J.
- Leandro Pereira on MDEx: Elixir Mentor interview covering MDEx, Lumis, and open source.
All mentions. To add your project or a mention, send a PR to the Community page.
Every Lumis package is built around the same three pieces:
- themes extracted from Neovim
- languages backed by Tree-sitter grammars
- formatters that turn highlighted tokens into output
Given some source code, Lumis parses it with the selected Tree-sitter language, resolves styles from the chosen theme, and then formats the highlighted result into HTML, ANSI, or any custom output.
The npm WASM package versions follow the pattern <tree-sitter-version>.<seq> where:
tree-sitter-versionis the major-minor version of the compatible Tree-sitter releaseseqis a patch number for Lumis own updates
For example, @lumis-sh/wasm-rust@0.26.0 is the first published version compatible with Tree-sitter 0.26,
while @lumis-sh/wasm-javascript@0.26.1 is a patch update compatible with Tree-sitter 0.26 (usually containing upstream parser updates).
Contributions are welcome. Feel free to open issues or PRs for bugs, features, new themes, or languages.
See CONTRIBUTING.md
- Makeup for setting up the baseline for the Elixir package
- Inkjet for the Rust implementation in the initial versions
- Shiki and syntect for the hard work defining how syntax highlighters should work
MIT


