Library / SDK
highlightjs/highlight.js avatar
highlightjs/highlight.js

Highlight.js: Zero-Dependency Syntax Highlighting for Browser and Node.js

JavaScript syntax highlighter with language auto-detection and zero dependencies.

25,000 stars3,751 forksJavaScriptBSD-3-Clause

At a glance

What is it?
Highlight.js is a JavaScript syntax highlighter that runs in the browser and in Node.js without any framework dependencies. It supports over 180 languages with automatic language detection and ships with multiple themes selectable via a single CSS file swap.
Who is it for?
Highlight.js is the right choice for documentation sites, blogs, and web apps that need reliable syntax highlighting with minimal setup and no build-time dependency. Teams that need line numbers, code folding, or tightly controlled render performance at large scale should evaluate whether a plugin or Shiki's build-time approach better fits their requirements.
Can I use it commercially?
Yes. BSD-3-Clause 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 23 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 26, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What Highlight.js Provides and Who Uses It

Highlight.js solves a common problem in web development: displaying code samples with color-coded syntax on a page without building a custom parser for each language. It works with plain HTML markup, does not require any framework, and takes no external dependencies. The README states it works "with pretty much any markup" and detects the language automatically.

The library runs in two environments. In the browser, it operates as a client-side script that scans the DOM for code elements and applies syntax classes. On the server, it runs as a Node.js module that returns highlighted HTML strings. The same API covers both contexts.

The primary users are documentation platforms, static site generators, technical blogs, and web applications that display user-submitted or generated code. Because the library ships as a single script with a companion CSS file, it fits into projects where adding a full-featured component library is impractical. The version 11 line is current, with 11.12.0 released on 2026-08-12 and 11.11.2 released on 2026-06-23.

Adding Highlight.js to a Web Page

The minimum browser integration loads the CSS theme, the script, and calls one function:

html
<link rel="stylesheet" href="/path/to/styles/default.min.css">
<script src="/path/to/highlight.min.js"></script>
<script>hljs.highlightAll();</script>

This scans `<pre><code>` elements on the page and highlights them with automatic language detection. For explicit language selection, add the language class to the code element:

html
<pre><code class="language-html">...</code></pre>

To apply Highlight.js styling without highlighting (for example, for shell output that should not be parsed as code), use the plaintext class:

html
<pre><code class="language-plaintext">...</code></pre>

To skip a specific block entirely, use the `nohighlight` class:

html
<pre><code class="nohighlight">...</code></pre>

The library is available via CDN from cdnjs, jsDelivr, and unpkg, through the npm package `highlight.js`, or as a direct download from highlightjs.org. The CDN path requires no build step, making it the fastest route for existing static sites.

For manual initialization control, the `highlightElement` and `configure` functions let you decide which elements to highlight and when, rather than scanning the full DOM on `DOMContentLoaded`.

Using Highlight.js in Node.js

The Node.js API follows the same pattern as the browser API. To load the library with all languages:

js
hljs = require('highlight.js');
html = hljs.highlightAuto('<h1>Hello World!</h1>').value

The `highlightAuto` function detects the language and returns an object. The `.value` property contains the highlighted HTML string.

For smaller bundles, the common subset loads only the most popular languages:

js
hljs = require('highlight.js/lib/common');

To highlight with a known language without going through auto-detection:

js
html = hljs.highlight('<h1>Hello World!</h1>', {language: 'xml'}).value

The package also exports ES6 module variants for bundlers that can perform tree-shaking. The package.json shows both `main` (CommonJS at `./lib/index.js`) and types (`./types/index.d.ts`) exports, with named sub-exports for common, WebSocket, and other subsets.

For build workflows, the repository ships build scripts under `tools/`. The `npm run build` command produces a Node.js output, `npm run build-cdn` produces the CDN bundle, and `npm run build-browser` produces a browser bundle with the common language subset.

Language Detection, Coverage, and Third-Party Extensions

The library's auto-detection works by running each loaded language grammar against a sample of the code and scoring the match. The language with the highest score is selected. This approach requires that at least one grammar is a reasonable match for the code, so auto-detection works best when the code sample is long enough to exhibit distinctive syntax.

Over 180 languages are supported in the core library, and the full list is documented in `SUPPORTED_LANGUAGES.md` in the repository. Beyond the core library, third-party language definitions extend coverage to additional languages not included in the main package.

Language definitions live under `src/languages/` in the repository. Each definition is a JavaScript file that exports a grammar object. The build system in `tools/build.js` takes these definitions and produces the various distribution targets.

Theme support is purely CSS: a theme is a stylesheet that defines color classes for the tokens Highlight.js emits. Swapping themes requires changing the linked CSS file without touching the JavaScript. The README links to a demo at highlightjs.org where themes can be previewed.

For Vue.js integration, the README points to the `highlightjs/vue-plugin` project, a separate package that wraps Highlight.js in a Vue component with an `autodetect` prop and a `:code` binding.

Customizing Initialization and Non-Standard HTML

The `hljs.highlightAll()` call is a convenience wrapper. For finer control, the `highlightElement` function highlights a single element and `configure` sets global options.

A manual equivalent of `highlightAll` using DOM selection:

js
document.addEventListener('DOMContentLoaded', (event) => {
  document.querySelectorAll('pre code').forEach((el) => {
    hljs.highlightElement(el);
  });
});

When the code blocks use `div` elements instead of `pre code`, the library can still highlight them, but linebreak preservation requires a CSS override because `div` does not preserve whitespace by default:

css
div.code {
  white-space: pre;
}

The README strongly recommends using `<pre><code>` for semantic correctness and to avoid needing the additional CSS step. The documentation acknowledges a line-break plugin exists for other approaches, but recommends CSS as the cleaner solution.

Limitations: What Highlight.js Does Not Include

Highlight.js does not include line numbers as a built-in feature. The RELATED SEARCHES for this project include "highlight js line numbers," indicating this is a common expectation. Adding line numbers requires a third-party plugin or custom JavaScript that counts lines and injects markup around each one. The core library does not provide a configuration option for this.

The library also does not include code folding, diff highlighting with added/removed line markers, or inline error annotations. These are features that editors like CodeMirror and Monaco provide but are outside the scope of a syntax highlighter focused on static display.

Auto-detection produces incorrect results when code samples are very short (fewer than a handful of lines) or when a snippet could belong to multiple languages with similar syntax. The explicit `class="language-X"` attribute is the reliable path for known languages.

Version 11 introduced breaking changes documented in `VERSION_11_UPGRADE.md`. The README notes that users upgrading from earlier versions need to read this file before updating. Major version upgrades in Highlight.js are not backwards-compatible by design.

The demo Dockerfile in the repository uses `FROM node:12-slim`, which refers to Node.js 12, a version that has been out of support since April 2022. The Dockerfile is for running the demo locally, not for production deployment of the library itself, but teams copying it should update the base image.

Highlight.js vs PrismJS and Shiki

PrismJS is the most frequently compared alternative. Both are browser JavaScript syntax highlighters, but their approaches differ on language registration and auto-detection. PrismJS requires explicitly marking the language on every code block; it does not auto-detect. PrismJS uses a plugin architecture for features like line numbers, where the plugin handles the feature with a small JavaScript registration. Highlight.js auto-detects the language when no class is specified, making it more forgiving on pages where authors do not control all code markup.

Shiki is a syntax highlighter based on TextMate grammars, the same grammar format used by VS Code. The key difference from Highlight.js is when rendering happens: Shiki renders syntax highlighting at build time, producing static HTML with inline styles or CSS classes, while Highlight.js renders at runtime in the browser or in a server-side Node.js process. For static site generators where all content is known at build time, Shiki avoids any JavaScript execution cost in the browser. For applications where code content is dynamic or user-submitted, Highlight.js's runtime approach is the natural fit.

The RELATED SEARCHES include both "highlight js vs prismjs" and "highlight js vs shiki," confirming that teams actively compare all three. Highlight.js's BSD-3-Clause license, zero-dependency model, and broad CDN availability make it the lowest-friction starting point for browser-side syntax highlighting.

Editorial conclusion

Highlight.js is the right choice for documentation sites, blogs, and web apps that need reliable syntax highlighting with minimal setup and no build-time dependency. Teams that need line numbers, code folding, or tightly controlled render performance at large scale should evaluate whether a plugin or Shiki's build-time approach better fits their requirements. Version 11 introduced breaking changes; teams upgrading from version 10 or earlier should read the VERSION_11_UPGRADE.md file before updating.

Frequently asked questions

What is Highlight.js?

Highlight.js is a JavaScript syntax highlighter that works in the browser and in Node.js with zero external dependencies. It supports over 180 languages and can automatically detect the language from a code sample without requiring a manual language class.

What are the key differences between Highlight.js and PrismJS?

Highlight.js auto-detects the language when none is specified, while PrismJS requires the language class on every block. PrismJS uses a plugin architecture for extended features like line numbers; Highlight.js does not include line numbers in its core and requires a third-party plugin for that.

How do I install Highlight.js?

Highlight.js is available as the `highlight.js` npm package, via CDN from cdnjs, jsDelivr, and unpkg, or as a direct download from highlightjs.org. For browser use, link the CSS theme file and the highlight.min.js script, then call `hljs.highlightAll()`.

How do I use Highlight.js in React?

Highlight.js does not include a built-in React component. The README documents a `highlightElement` API for highlighting a specific DOM element, which can be called via a React `useEffect` hook on mount. For Vue.js, the README points to a dedicated `highlightjs/vue-plugin`.

How does Highlight.js compare to Shiki?

Shiki renders syntax highlighting at build time using TextMate grammars, producing static HTML. Highlight.js renders at runtime in the browser or Node.js. Shiki is better suited for static site generators where content is known at build time; Highlight.js fits dynamic or user-submitted code content.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/highlightjs-highlight-js.svg)](https://hysenlabs.com/projects/highlightjs-highlight-js)
Community notes

Community notes