lowlight
Virtual syntax highlighting for virtual DOMs and non-HTML things, powered by highlight.js
Repository Health
Technical Analysis
lowlight wraps highlight.js so that syntax highlighting produces a hast (HTML AST) tree instead of a string of HTML. That makes it the natural choice for virtual DOM frameworks like React and Preact, for CLI tools that render to ANSI, and for any pipeline built on unified/rehype that needs to reason about highlighted code as structured nodes rather than markup.
It exposes a small, explicit API: create an instance with createLowlight, pass it either the common set of 37 popular grammars or the all set of 190+ languages, then call highlight (given a known language) or highlightAuto (to guess the language) to get back a hast root with language and relevance metadata attached. Because the output is a tree rather than a string, it composes cleanly with hast-util-to-html, hast-util-to-jsx-runtime, and the rest of the unified ecosystem, and it stays diff-friendly for virtual DOM reconciliation.
What You Get
- A
createLowlightfactory that produces an isolated highlighter instance, so you can register only the grammars you need common(37 popular languages) andall(190+ languages) grammar bundles ready to pass straight intocreateLowlighthighlight(language, value)for known-language highlighting andhighlightAuto(value)for language detection, both returning a hastRootwithlanguageandrelevancedata- Full TypeScript types, including a registered
hastmodule augmentation for thelanguage/relevancedata fields - An ESM-only, tree-shakeable package with zero HTML-string intermediate step
Common Use Cases
- Rendering highlighted code blocks inside React or Preact apps via
hast-util-to-jsx-runtime, keeping virtual DOM diffing efficient - Highlighting code inside a rehype/remark Markdown or MDX pipeline, where the tree needs to stay in AST form until final serialization
- Rendering syntax-highlighted output to a terminal (ANSI) instead of HTML, by walking the hast tree with a custom serializer
- Building documentation or blog platforms that need consistent, framework-agnostic syntax highlighting across static site generators
Under The Hood
Architecture - The public surface is deliberately tiny: index.js re-exports all and common grammar maps plus a single createLowlight factory from lib/index.js. createLowlight wraps a fresh HighlightJs.newInstance() (highlight.js’s core, imported without any bundled grammars) and closes over it to return {highlight, highlightAuto, listLanguages, register, registerAlias, registered} — each instance is fully isolated, so registering a grammar on one lowlight instance never leaks into another. The core trick is a custom __emitter (HastEmitter, in lib/index.js) that highlight.js drives instead of its default HTML-string emitter; the emitter builds a hast Root node directly, and language/relevance are attached to root.data after highlighting completes. This is what lets lowlight return an AST rather than markup. lib/all.js and lib/common.js are generated files (via script/build-registry.js) mapping language names to highlight.js LanguageFn importers. Tech Stack - Runtime dependencies are minimal and precise: highlight.js (pinned ~11.11.0) does the actual lexing/grammar matching, devlop provides lightweight assert()-style development-only invariants, and @types/hast supplies the tree types. The package is ESM-only ("type": "module"), ships hand-written index.d.ts plus JSDoc-typed source (lib/index.js is annotated with @typedef/@type comments, compiled/checked via tsc --build and type-coverage rather than being authored in .ts). Build tooling is the wooorm-standard stack: xo (ESLint preset) + prettier for style, remark-cli for doc linting, c8 for coverage. Code Quality - test/index.js (485 lines) exercises the public API through node:test with fixture-driven assertions (test/fixture/), covering alias registration (single, list, map-to-string, map-to-list forms), known-language highlighting, auto-detection, and error paths (unknown language throws). The test-coverage script runs c8 --100 --check-coverage, meaning the project enforces 100% statement/branch coverage as a CI gate — a strong quality signal for a library this size. Runtime assertions via devlop’s ok() guard argument types (typeof language === 'string') and are stripped in production builds, keeping the hot path lean. API Design - The API is deliberately small and consistent: two entry functions (highlight, highlightAuto) with parallel signatures, explicit Options/AutoOptions types, and predictable return shape (Root with data.language/data.relevance). Grammar bundling is opt-in via createLowlight(common) or createLowlight(all) rather than importing everything by default, which keeps bundle size in the consumer’s control. Documentation is thorough — the README documents every export with parameters, return types, and runnable examples for both HTML serialization (hast-util-to-html) and JSX conversion (hast-util-to-jsx-runtime), which flattens the learning curve for anyone already familiar with the unified/hast ecosystem, though it does assume that background.
Used by 35 apps in this directory
Baserow
No Code Platforms · Databases
Open-source no-code platform to build databases, apps, automations, and AI agents — self-hosted or cloud, with full data ownership.
Continue
Developer Tools · AI Development · AI Code Assistants
Open-source coding agent for VS Code, JetBrains, and CLI with support for 30+ LLM providers.
CourseLit
Ecommerce · Blogging
Open-source, self-hosted LMS for selling online courses, digital downloads, and building communities on your own branded website.
Docmost
Productivity · Note Taking · Collaboration
Self-hosted collaborative wiki and knowledge base with real-time editing, diagrams, AI assistance, and enterprise access controls — a modern alternative to Confluence and Notion.
Flowise
Developer Tools · Automation · No Code Platforms
Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.
Flowsint
Automation · Developer Tools
A privacy-first, graph-based OSINT investigation platform with 30+ automated enrichers for mapping relationships between domains, IPs, people, and organizations.
fountain-ink
Blogging
A self-hostable, decentralized blogging platform built on Lens Protocol — own your content, audience, and distribution forever.
GitLab
Devops · Developer Tools
The complete DevOps platform that unifies Git hosting, CI/CD, issue tracking, and security scanning into a single self-hostable application.
Huly Platform
Project Management · Team Chat · Collaboration
Open-source all-in-one workspace that replaces Linear, Jira, Slack, and Notion for product and engineering teams.