# Lumis (/)

Lumis is a syntax highlighter built on [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) and [Neovim themes](https://github.com/topics/neovim-colorscheme).

Lumis supports **7 runtimes**: CLI, Rust, Elixir, JavaScript / TypeScript, Browsers / CDN, and community-maintained [Java](/usage/java) and [Python](/usage/python). The community packages have their own APIs and release schedules.

The examples below cover the first-party runtimes and Lumis4J. See the [fastpylight guide](/usage/python) for Python examples.

To highlight code:

1. [install Lumis](#1-install-lumis)
2. [pick a language](#2-pick-a-language)
3. [pick a theme](#3-pick-a-theme)
4. [pick a formatter](#4-pick-a-formatter)
5. [render to multiple formats](#5-render)

## 1. Install Lumis

### JavaScript / TypeScript

```bash
npm install @lumis-sh/lumis @lumis-sh/themes
```

### Rust

```bash
cargo add lumis
```

### Elixir

```elixir title="mix.exs"
def deps do
  [
    {:lumis, "~> 0.10"}
  ]
end
```

### Java

```xml title="pom.xml"
<dependency>
  <groupId>io.roastedroot</groupId>
  <artifactId>lumis4j</artifactId>
  <version>0.0.7</version>
</dependency>
```

### CLI

```bash
curl -LsSf https://lumis.sh/install.sh | sh
```

On Windows PowerShell:

```powershell
powershell -ExecutionPolicy ByPass `
  -c "irm https://lumis.sh/install.ps1 | iex"
```

Homebrew, npm, `cargo binstall`, and mise: [Install the CLI](/cli/install).

### Browsers / CDN

```js
import {highlight} from 'https://cdn.jsdelivr.net/npm/@lumis-sh/lumis/+esm';
```


[Installation](/installation)

## 2. Pick a language

### JavaScript / TypeScript

A parser is an npm package:

```bash
npm install @lumis-sh/wasm-javascript
```

```js
import javascript from '@lumis-sh/wasm-javascript';
```

### Rust

```rust
use lumis::languages::Language;

let language = Language::JavaScript;
```

### Elixir

A parser is a Hex package:

```elixir title="mix.exs"
{:lumis_wasm_javascript, "~> 0.26.0"}
```

```elixir
language = "javascript"
```

### Java

```java
import io.roastedroot.lumis4j.core.Lang;

var lang = Lang.JAVASCRIPT;
```

### CLI

```bash
lumis highlight index.js --language javascript
```

### Browsers / CDN

```js
// A browser loads only the parser packages you import.
import javascript from 'https://cdn.jsdelivr.net/npm/@lumis-sh/wasm-javascript/+esm';
```


[Languages](/languages) · [Language catalog](/reference/languages)

## 3. Pick a theme

### JavaScript / TypeScript

```js
import frappe from '@lumis-sh/themes/catppuccin_frappe';
```

### Rust

```rust
use lumis::themes;

let theme = themes::get("catppuccin_frappe").unwrap();
```

### Elixir

```elixir
theme = "catppuccin_frappe"
```

### Java

```java
import io.roastedroot.lumis4j.core.Theme;

var theme = Theme.CATPPUCCIN_FRAPPE;
```

### CLI

```bash
lumis themes list
lumis highlight index.js --theme catppuccin_frappe
```

### Browsers / CDN

```js
import frappe from 'https://cdn.jsdelivr.net/npm/@lumis-sh/themes/dist/themes/catppuccin_frappe.js';
```


[Themes](/themes) · [Theme catalog](/reference/themes)

## 4. Pick a formatter

### JavaScript / TypeScript

```js
import {htmlInline} from '@lumis-sh/lumis/formatters';

const formatter = htmlInline({language: javascript, theme: frappe});
```

### Rust

```rust
use lumis::HtmlInlineBuilder;

let formatter = HtmlInlineBuilder::new()
    .language(Language::JavaScript)
    .theme(Some(theme))
    .build()
    .unwrap();
```

### Elixir

```elixir
formatter =
  {:html_inline, language: language, theme: theme}
```

### Java

```java
import io.roastedroot.lumis4j.core.Formatter;

var formatter = Formatter.HTML_INLINE;
```

### CLI

```bash
lumis highlight index.js --formatter html-inline --theme catppuccin_frappe
```

### Browsers / CDN

```js
import {htmlInline} from 'https://cdn.jsdelivr.net/npm/@lumis-sh/lumis/dist/formatters.js';

const formatter = htmlInline({language: javascript, theme: frappe});
```


[Formatters](/formatters)

## 5. Render

### JavaScript / TypeScript

```js
import {highlight} from '@lumis-sh/lumis';
import {htmlInline} from '@lumis-sh/lumis/formatters';
import frappe from '@lumis-sh/themes/catppuccin_frappe';
import javascript from '@lumis-sh/wasm-javascript';

const html = await highlight(
  'const x = 1',
  htmlInline({language: javascript, theme: frappe})
);
```

### Rust

```rust
use lumis::{
    highlight, languages::Language, themes,
    HtmlInlineBuilder,
};

let formatter = HtmlInlineBuilder::new()
    .language(Language::JavaScript)
    .theme(Some(themes::get("catppuccin_frappe").unwrap()))
    .build()
    .unwrap();

let html = highlight("const x = 1", formatter);
```

### Elixir

```elixir
html =
  Lumis.highlight!(
    "const x = 1",
    formatter:
      {:html_inline,
       language: "javascript",
       theme: "catppuccin_frappe"}
  )
```

### Java

```java
import io.roastedroot.lumis4j.core.Formatter;
import io.roastedroot.lumis4j.core.Lang;
import io.roastedroot.lumis4j.core.Lumis;
import io.roastedroot.lumis4j.core.Theme;

var lumis = Lumis.builder().build();

var highlighter = lumis.highlighter()
    .withLang(Lang.JAVASCRIPT)
    .withTheme(Theme.CATPPUCCIN_FRAPPE)
    .withFormatter(Formatter.HTML_INLINE)
    .build();

var html = highlighter.highlight("const x = 1").string();
lumis.close();
```

### CLI

```bash
echo 'const x = 1' | lumis highlight \
  --language javascript \
  --theme catppuccin_frappe \
  --formatter html-inline
```

### Browsers / CDN

```html
<script type="module">
  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 frappe from 'https://cdn.jsdelivr.net/npm/@lumis-sh/themes/dist/themes/catppuccin_frappe.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: frappe})
  );
</script>
```


[Highlight](/usage/highlight)

## Why Lumis

- [Tree-sitter parsing](/architecture) instead of regex-based tokenization
- [110+ languages](/reference/languages) that [load on demand or preload](/languages), with [injected languages](/recipes/injected-languages-html-css-js) highlighted in the same pass
- [250+ themes](/reference/themes) sourced from Neovim colorschemes, or [one you generate](/recipes/generate-theme-from-neovim-colorscheme)
- 5 formatters: [HTML Inline](/formatters/html-inline), [HTML Linked](/formatters/html-linked), [HTML Multi-Themes](/formatters/html-multi-themes), [Terminal](/formatters/terminal), and [BBCode Scoped](/formatters/bbcode), or [one you write](/formatters/custom)
- [handles incomplete code](/usage/highlight#incomplete-code), useful for streaming
- 7 runtimes: [CLI](/usage/cli), [Rust](/usage/rust), [Elixir](/usage/elixir), [JavaScript / TypeScript](/usage/javascript), [Browsers / CDN](/recipes/browser-cdn), community-maintained [Java](/usage/java) and [Python](/usage/python)

## Community

Lumis highlights package source on [Hex.pm](https://hex.pm) and blog code on [jacko.io](https://jacko.io). Python tools [mdhtml](https://github.com/AnswerDotAI/mdhtml) and [mdhtml2docx](https://github.com/AnswerDotAI/mdhtml2docx) use it through fastpylight to highlight code in HTML and Word documents.

See the [community runtimes](/community#community-runtimes), [full project list](/community#used-by), and [articles and talks](/community#mentions).

See the [visual comparison](https://lumis.sh/comparison/) for the same source files highlighted by Lumis and other highlighters.

## Why not Lumis

Parser size is the main tradeoff, especially in the browser. [Load only the languages you need](/languages), or highlight at build time or on the server so visitors don't download parsers. See the [language catalog](/reference/languages) for parser sizes.

## How it works

- [Tree-sitter](https://tree-sitter.github.io/tree-sitter/) parses code into syntax trees
- [Neovim colorschemes](https://github.com/topics/neovim-colorscheme) supply the color data
- highlight queries come from [`nvim-treesitter`](https://github.com/nvim-treesitter/nvim-treesitter)

[Architecture](/architecture) walks the whole pipeline, from source code to styled output.

---

Every code block on this site is highlighted by Lumis itself, using the [multi-themes formatter](/formatters/html-multi-themes) with `catppuccin_latte` and `catppuccin_frappe` themes for automatic light/dark mode switching.