Library / SDK
davatron5000/microlighter avatar
davatron5000/microlighter

MicroLighter: a zero-dependency syntax highlighter built on the CSS Custom Highlight API

A zero-dep syntax highlighter that uses the CSS Highlights API

874 stars23 forksJavaScriptMIT

At a glance

What is it?
MicroLighter highlights code with TextMate grammars and the CSS Custom Highlight API instead of wrapping every token in a span. It is small, MIT licensed, and aimed at pages that need clean, editable markup.
Who is it for?
Adopt MicroLighter if you ship documentation, blogs or internal tools where code blocks must stay selectable, editable and free of token markup, and you are willing to accept the browser support that the CSS Custom Highlight API currently has. Do not adopt it if you must support older browsers without a fallback path, or if you need grammar behaviour that the bundled TextMate grammars do not cover.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 16, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem MicroLighter solves: token markup you did not ask for

Most browser highlighters work by walking the text and wrapping every keyword, string and comment in a `<span>` with a class. That is straightforward, and it is also why copying a highlighted code block often drags along markup, why contenteditable regions fight the highlighter, and why the DOM of a documentation page can be several times larger than the code it displays. MicroLighter takes the opposite route. According to the README, it highlights code "without adding a `<span>` around every token, so your markup stays clean and editable." The code stays plain text inside `<pre><code>`; the colour comes from CSS.

The project targets people who publish code on the web: documentation sites, blogs, internal tools and any page where a `<pre><code>` block is part of the content rather than a widget. The package is about 2 KiB compressed with no runtime dependencies, which matters if you are shipping a static site and do not want a highlighter to dominate your JavaScript budget. It is not a code editor and it does not replace one.

How the CSS Custom Highlight API and TextMate grammars fit together

MicroLighter has two halves. The first is tokenisation: grammars in the TextMate style, the same format VS Code uses, decide which ranges of the text are comments, strings, keywords and so on. The README lists 37 grammars, from assembly and astro through to vue and yaml, and says they are ES modules that load on demand. That means a page that only shows JavaScript never downloads the Rust grammar.

The second half is rendering. Instead of inserting elements, MicroLighter registers those ranges with the CSS Custom Highlight API, which lets CSS style arbitrary text ranges without changing the DOM. Themes are therefore plain CSS files that set custom properties such as `--syntax-keyword` and `--syntax-string`, and the active theme is selected with a `data-syntax-theme` attribute on `<body>` or any container. The README maps each property to a token category, so a theme author is really choosing thirteen colours rather than writing selectors per language.

The design has an obvious consequence: because highlighting is applied to ranges over existing text, the underlying code remains a single text node. That is what makes the editable-code example possible, and it is also why the API surface is small. `highlightAll()` is the main export, and importing it has no side effects until you call it.

Installing MicroLighter and highlighting your first code block

The package is published on npm and requires Node 18 or later according to `package.json`. Install it with:

bash
npm install microlighter

Then mark up a code block with a `language-*` class. The README calls this the recommended format:

html
<pre><code class="language-javascript">const answer = 42;</code></pre>

Import a theme and the highlighter, then await the scan. The theme import is what loads the CSS, and setting `data-syntax-theme` on `<body>` is what activates it:

js
import "microlighter/themes/github.css";
import { highlightAll } from "microlighter";

document.body.dataset.syntaxTheme = "github";
await highlightAll();

After that call, MicroLighter finds every `pre > code` block with a supported language and highlights it. If your markup uses different elements, `highlightAll()` accepts a `root`, a `selector` (the default is `"pre > code"`) and a `languageAliases` object for project-specific names. There is also an auto runner, `microlighter.min.js`, that highlights as soon as the module loads, plus a `<micro-lighter>` web component with optional `controls="copy"` and `line-numbers` attributes. If you add or change code later, the README says to dispatch `new Event("syntax-highlight")` on `document`, and notes the event can bubble from a code block or one of its parents.

Where MicroLighter is the wrong tool

The CSS Custom Highlight API is the whole rendering strategy, and that is the constraint to weigh. MicroLighter does not ship a fallback that wraps tokens in spans for browsers without the API, and the README does not document one. If your audience includes browsers that lack it, you get unhighlighted but perfectly readable code, which is a graceful failure but still a failure. For a public site with a long support tail, that is a decision you have to make deliberately rather than discover later.

There are smaller trade-offs too. Highlighting is not automatic for dynamically inserted content: the README's answer is to dispatch the `syntax-highlight` event yourself, which means every framework that renders code blocks after load needs a hook. Custom aliases passed to `highlightAll()` must point to a bundled language, so you cannot teach it a grammar that is not shipped. And the token vocabulary is fixed at thirteen categories; if a theme needs to distinguish something the categories do not cover, the mapping in the README is the ceiling. Finally, the project ships no plugin system for grammars, so a language outside the list of 37 is not a configuration change.

MicroLighter compared with span-wrapping highlighters

The closest comparison is the family of highlighters that parse code and emit `<span class="...">` for each token, of which highlight.js and Prism are the best known. The difference in approach is not cosmetic. A span-wrapping highlighter produces markup that other tools can style with ordinary selectors, works in any browser, and can be serialised to HTML on the server. MicroLighter produces no markup at all: the DOM is the code, and the colour lives in a highlight registry that CSS reads.

That trade runs in both directions. MicroLighter wins on DOM size, on copy behaviour, and on editability, because there is no token markup to strip or fight. It loses on portability, because the rendering depends on a browser API rather than on HTML, and on server-side rendering, because there is nothing to serialise. If you need highlighted HTML in an RSS feed or an email, a span-based highlighter is the right tool. If you need a page whose code blocks stay clean and editable, and your browser targets allow it, MicroLighter is the one doing something the others structurally cannot.

Maintenance, upgrade cost and the MIT licence

The repository is not archived, and the last push was on 2026-09-11, the same day as the v2.2.0 release. Before that, v2.1.0 landed on 2026-08-19 and v2.0.3 on 2026-08-18, so the 2.x line has seen three releases in under a month. The project is small and its dependency surface is close to zero: `package.json` lists only `@playwright/test` and `typescript` as dev dependencies, and no runtime dependencies at all. Upgrading therefore mostly means tracking the package itself rather than a tree of transitive packages.

There is an unusual detail worth knowing before you file a bug. TypeScript declarations ship with the package and, per the README, are generated from JSDoc types in `src/`, so the published types and the source cannot drift apart. The repository also enforces a size budget: `package.json` sets `sizeLimit` for `dist/microlighter.min.js` at 2150 bytes, and there is a `size` script that reports it. That is a real constraint on what a pull request can add to the core bundle.

MicroLighter is MIT licensed. In practical terms that permits commercial and closed-source use, modification and redistribution provided the copyright notice and permission notice are kept. This is a description of the licence text, not legal advice; if your organisation has rules about attribution, check how you are bundling the package.

Editorial conclusion

Adopt MicroLighter if you ship documentation, blogs or internal tools where code blocks must stay selectable, editable and free of token markup, and you are willing to accept the browser support that the CSS Custom Highlight API currently has. Do not adopt it if you must support older browsers without a fallback path, or if you need grammar behaviour that the bundled TextMate grammars do not cover. Before committing, load a theme, run highlightAll() on a real page, and check how your code blocks render in the browsers you actually support.

Frequently asked questions

What is MicroLighter used for?

It is a syntax highlighter for code shown on web pages. It uses the CSS Custom Highlight API and TextMate grammars so that code blocks are highlighted without adding a span around every token.

How do I install MicroLighter?

Install it from npm with npm install microlighter, then import a theme and call highlightAll(). The package requires Node 18 or later according to package.json.

Does MicroLighter add spans to my HTML?

No. The README states that it highlights code without adding a span around every token, so the markup stays clean and the code remains editable.

Official sources

  1. davatron5000/microlighter on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Community notes

Community notes