Themes
Use built-in Neovim themes, load custom theme JSON, or generate new themes for Lumis.
Lumis themes come from the Neovim ecosystem. You can use the built-in collection, load theme JSON yourself, or generate new themes from a colorscheme repository.
To match an application or terminal background automatically, use
closest.
Pick a built-in theme
import frappe from '@lumis-sh/themes/catppuccin_frappe';
console.log(frappe.name);
console.log(frappe.appearance);Transform theme styles
Use mapStyles / map_styles to change colors, backgrounds, or text decorations
before rendering. The callback receives each existing scope name and its complete
style once, and returns the style to use instead. It does not merge a partial
patch. Keep the other fields with a spread or struct update.
For a complete example, see Customize theme styles.
import githubLight from '@lumis-sh/themes/github_light';
import { mapStyles } from '@lumis-sh/lumis/themes';
import { buildCss } from '@lumis-sh/themes';
const theme = mapStyles(githubLight, (scope, style) => {
switch (scope) {
case 'markup.raw.block':
return { ...style, italic: false };
case 'normal':
return { ...style, bg: '#ffffff' };
case 'highlighted':
return { ...style, bg: '#fff3bf' };
default:
return style;
}
});
const css = buildCss(theme);The original theme is unchanged. The returned theme has its own style objects, including for entries whose callback returns the style unchanged.
To disable italics across the whole theme:
const upright = mapStyles(githubLight, (_scope, style) => ({
...style,
italic: false,
}));Pass the result wherever a theme is accepted: inline HTML, each theme in multi-theme HTML, terminal output, or custom formatters. For linked HTML, build CSS from the modified theme and use that stylesheet instead of the prebuilt one.
Transformations preserve scope names, the theme name, appearance, revision, and
license. They visit only existing entries, including language-specific entries,
in an unspecified order. They do not add missing scopes or expand fallback
styles. An exact match for markup.raw.block does not also change an existing
markup.raw.block.markdown entry. Match those explicitly when needed.
Setting a style's italic to false removes that scope's contribution; it does
not cancel italics inherited from an enclosing highlight or the surrounding
page. Independently italic comments inside a code fence can remain italic.
You can compose transformations by passing the result to another call. An empty theme stays empty and never calls the callback. Callback errors propagate to the caller. The API does not convert colors or turn a dark palette into a light one.
Load a custom theme from JSON
Generate the file with the Neovim colorscheme recipe,
or write it by hand. Point $schema at the theme schema to get completion and
validation in editors that support JSON Schema. Theme files
describes every field:
{
"$schema": "https://lumis.sh/schemas/themes/v1.0.0.json",
"name": "my_theme",
"appearance": "dark",
"revision": "v1",
"highlights": {
"keyword": { "fg": "#ff79c6", "bold": true },
"comment": { "fg": "#6272a4", "italic": true }
}
}Then load it in your runtime:
Import your generated JSON as a theme object; no loader helper is needed:
import theme from './my-theme.json' with { type: 'json' };
import { htmlInline } from '@lumis-sh/lumis/formatters';
import javascript from '@lumis-sh/wasm-javascript';
const formatter = htmlInline({ language: javascript, theme });Use Node.js JSON modules or a bundler with JSON import support.
Generate a theme from a Neovim colorscheme
Follow Generate a theme from a Neovim colorscheme
for prerequisites, a runnable example using a theme outside the bundled collection,
and source-license and redistribution considerations. Generation requires Neovim
with vim.pack; it preserves the detected source license rather than relicensing
the theme.
CSS theme files
If you use htmlLinked, pair the HTML output with a stylesheet. See CSS Theme Files for import paths and runtime-specific setup.
Theme switching with CSS variables
If you want one block to support multiple themes, use the multi-theme formatter from Formatters.