
MicroLighter is a tiny, dependency-free JavaScript syntax highlighter that colors code blocks with the CSS Custom Highlight API.
It reads a TextMate grammar, matches tokens with the browser’s native RegExp engine, and registers each token range with CSS.highlights. The markup inside your <pre><code> block never changes.
Features:
- TextMate grammar support for common programming, markup, scripting, and configuration languages.
- Lazy-loaded language grammars.
- Standard HTML code block markup.
- Automatic and programmatic ES module workflows.
- 10 light and dark themes.
- CSS custom properties for syntax colors.
- Optional Web Component with copy controls and line numbers.
- Dynamic re-highlighting for code inserted after the initial page load.
How To Use It:
Installation
Install MicroLighter through npm for an ES module or bundler-based project.
npm install microlighter
Basic Usage
Import highlightAll() and one of the bundled themes. Add a standard language-* class to each code element that needs highlighting.
import { highlightAll } from "microlighter";
import "microlighter/themes/github.css";
await highlightAll();
Set the matching theme name on a parent element and identify the language in the code markup.
<body data-syntax-theme="github">
<pre><code class="language-javascript">
const formatPrice = (value) => `$${value.toFixed(2)}`;
</code></pre>
</body>
MicroLighter also reads data-language from the <code> element or its parent <pre>.
<pre>
<code data-language="python">
def greet(name):
return f"Hello, {name}"
</code>
</pre>
Automatic Page Highlighting
The auto-runner scans matching code blocks as soon as the module loads. Import the theme first, followed by the automatic entry.
import "microlighter/themes/dracula.css"; import "microlighter/microlighter.min.js";
Apply the corresponding theme name to the page or a containing element.
<main data-syntax-theme="dracula">
<pre><code class="language-css">
.card {
display: grid;
gap: 1rem;
}
</code></pre>
</main>
Scope Highlighting To Part Of A Page
highlightAll() accepts a root option when only one page region should be scanned.
import { highlightAll } from "microlighter";
const docsPanel = document.querySelector("#api-reference");
await highlightAll({
root: docsPanel
});
A custom selector can replace the default pre > code selector.
await highlightAll({
selector: ".example-source > code"
});
Re-Highlight Dynamically Added Code
The automatic runner listens for a syntax-highlight event. Dispatch it after a SPA, AJAX response, or client-side renderer inserts new code blocks.
document.querySelector("#examples").insertAdjacentHTML(
"beforeend",
`
<pre>
<code class="language-json">
{ "status": "ready" }
</code>
</pre>
`
);
document.dispatchEvent(new Event("syntax-highlight"));
Custom Language Aliases
Each alias must point to a grammar included with MicroLighter.
await highlightAll({
languageAliases: {
ecmascript: "javascript",
shellsession: "bash"
}
});
Configuration Options
root(Document | Element): Limits the scan to a document or DOM subtree. Defaults todocument.selector(string): Selects code elements inside the root. Defaults topre > code.languageAliases(object): Maps custom language names to bundled grammar names.
Using The Web Component
Import the component bundle when code blocks need a copy button or line-number gutter.
import "microlighter/themes/tokyo-night.css"; import "microlighter/micro-lighter-element.min.js";
The component wraps standard <pre><code> content.
<div data-syntax-theme="tokyo-night">
<micro-lighter
language="typescript"
controls="copy"
line-numbers
>
<pre><code>
type Account = {
id: number;
active: boolean;
};
</code></pre>
</micro-lighter>
</div>
The language attribute on <micro-lighter> takes priority over language metadata on the nested code block.
The controls attribute accepts control names separated by spaces or commas. copy displays the built-in copy button. The boolean line-numbers attribute displays a gutter beside the code and keeps those numbers out of copied text.
Web Component Attributes
language(string): Overrides the language detected from the nested code markup.controls(string): Activates component controls. The available copy control uses the valuecopy.line-numbers(boolean): Displays line numbers beside the code block.
Styling The Web Component
The component exposes CSS parts for its generated controls.
micro-lighter::part(copy-button) {
border-radius: 0.5rem;
font-weight: 600;
}
micro-lighter::part(line-numbers) {
opacity: 0.7;
}
The actual <pre><code> content remains in the light DOM. Normal page selectors can style the code container itself.
micro-lighter pre {
padding: 1.25rem;
overflow: auto;
border-radius: 0.75rem;
}
Themes
Set data-syntax-theme to the loaded theme name.
<section data-syntax-theme="night-owl">
<pre><code class="language-html">
<button type="button">Save</button>
</code></pre>
</section>
Themes included:
githubvscode-plusdraculamonokainight-owlsolarized-lightvespermincobalt2tokyo-night
Customize Theme Colors
Theme styles use CSS custom properties for the main syntax categories. Override them within the element that carries data-syntax-theme.
[data-syntax-theme="github"] {
--syntax-background: #101418;
--syntax-foreground: #e6edf3;
--syntax-comment: #8b949e;
--syntax-keyword: #ff7b72;
--syntax-string: #a5d6ff;
--syntax-function: #d2a8ff;
--syntax-variable: #ffa657;
}
Available theme properties:
--syntax-background: Code block background.--syntax-foreground: Default code text.--syntax-comment: Comments and quoted scopes.--syntax-keyword: Keywords, storage terms, at-rules, and related scopes.--syntax-operator: Operators and punctuation.--syntax-string: Strings, regular expressions, links, and attribute values.--syntax-constant: Numbers, booleans, constants, symbols, and entities.--syntax-function: Functions, decorators, and animation names.--syntax-type: Types and support scopes.--syntax-variable: Variables and interpolations.--syntax-property: Properties, keys, and attribute names.--syntax-tag: Markup tags.--syntax-selector: CSS selectors.--syntax-inserted: Inserted diff content.--syntax-deleted: Deleted diff content.
Custom themes can also target the semantic highlight names directly.
-:highlight(keyword) {
color: #ff6b81;
}
-:highlight(string) {
color: #7bed9f;
}
-:highlight(comment) {
color: #747d8c;
}
Supported Languages
assembly, bash, c, cpp, csharp, css, dart, dockerfile, git-diff, go, graphql, html, java, javascript, json, kotlin, lua, markdown, objective-c, perl, php, powershell, python, r, ruby, rust, scss, sql, svelte, swift, toml, tsx, typescript, vue, and yaml.
Built-in aliases:
jsandjsxtojavascript.tstotypescript.sasstoscss.sh,shell, andzshtobash.ymltoyaml.mdtomarkdown.dockertodockerfile.pytopython.rbtoruby.gqltographql.
Alternatives:
- Modern Syntax Highlighter with CSS Custom Highlight API
- Tiny & Fast JavaScript Syntax Highlighting Library – Speed Highlight
- VS Code Style Syntax Highlighter – shiki.js
- Add Beautiful Code Highlighting with Syntax.js
FAQs:
Q: Does MicroLighter need Prism.js, highlight.js, or another syntax-highlighting dependency?
A: No. MicroLighter includes its own TextMate grammar parser and uses native browser APIs to apply the syntax ranges.
Q: Why does MicroLighter not add token <span> elements to my code?
A: It registers text ranges with the CSS Custom Highlight API. Theme styles target those ranges through ::highlight() while the original code text remains in the DOM.
Q: How do I highlight code added after the page loads?
A: Dispatch a syntax-highlight event when using the automatic runner. A programmatic integration can call highlightAll() again and pass the updated container as root.
Q: Why is syntax highlighting missing in an older browser?
A: Check support for the CSS Custom Highlight API, CSS.highlights, Highlight, and ::highlight().







